--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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_3RDPARTY REQUIRED)
+
+# Set 3rd party sources
+SET(DPL_3RDPARTY_SOURCES
+ # Minizip
+ ${PROJECT_SOURCE_DIR}/3rdparty/minizip/ioapi.c
+# ${PROJECT_SOURCE_DIR}/3rdparty/minizip/iowin32.c
+ ${PROJECT_SOURCE_DIR}/3rdparty/minizip/miniunz.c
+ ${PROJECT_SOURCE_DIR}/3rdparty/minizip/minizip.c
+ ${PROJECT_SOURCE_DIR}/3rdparty/minizip/mztools.c
+ ${PROJECT_SOURCE_DIR}/3rdparty/minizip/unzip.c
+ ${PROJECT_SOURCE_DIR}/3rdparty/minizip/zip.c)
+
+# Set 3rd party headers
+SET(DPL_3RDPARTY_HEADERS
+ # Minizip
+ ${PROJECT_SOURCE_DIR}/3rdparty/minizip/crypt.h
+ ${PROJECT_SOURCE_DIR}/3rdparty/minizip/ioapi.h
+# ${PROJECT_SOURCE_DIR}/3rdparty/minizip/iowin32.h
+ ${PROJECT_SOURCE_DIR}/3rdparty/minizip/mztools.h
+ ${PROJECT_SOURCE_DIR}/3rdparty/minizip/unzip.h
+ ${PROJECT_SOURCE_DIR}/3rdparty/minizip/zip.h)
+
+# Set 3rd party include directory
+SET(DPL_3RDPARTY_INCLUDE_DIR
+ ${PROJECT_SOURCE_DIR}/3rdparty)
+
+# Set name of binaries being created
+SET(TARGET_3RDPARTY "lib3rdparty")
+
+# Add 3rd party include directories
+INCLUDE_DIRECTORIES(${DPL_3RDPARTY_INCLUDE_DIR})
+
+# Add system include files
+INCLUDE_DIRECTORIES(${SYS_3RDPARTY_INCLUDE_DIRS})
+LINK_DIRECTORIES(${SYS_3RDPARTY_LIBRARY_DIRS})
+
+# Build shared library
+ADD_LIBRARY(${TARGET_3RDPARTY} STATIC ${DPL_3RDPARTY_SOURCES})
+TARGET_LINK_LIBRARIES(${TARGET_3RDPARTY} ${SYS_3RDPARTY_LIBRARIES} z)
+
--- /dev/null
+Third-party libraries
--- /dev/null
+<html>\r
+<head>\r
+<title>The Code Project Open License (COPL)</title>\r
+<Style>\r
+BODY, P, TD { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10pt }\r
+H1,H2,H3,H4,H5 { color: #ff9900; font-weight: bold; }\r
+H1 { font-size: 14pt;color:black }\r
+H2 { font-size: 13pt; }\r
+H3 { font-size: 12pt; }\r
+H4 { font-size: 10pt; color: black; }\r
+PRE { BACKGROUND-COLOR: #FBEDBB; FONT-FAMILY: "Courier New", Courier, mono; WHITE-SPACE: pre; }\r
+CODE { COLOR: #990000; FONT-FAMILY: "Courier New", Courier, mono; }\r
+.SpacedList li { padding: 5px 0px 5px 0px;}\r
+</style>\r
+</head>\r
+<body bgcolor="#FFFFFF" color=#000000>\r
+\r
+<h1>The Code Project Open License (CPOL) 1.02</h1>\r
+<br />\r
+\r
+<center>\r
+<div style="text-align: left; border: 2px solid #000000; width: 660; background-color: #FFFFD9; padding: 20px;">\r
+\r
+<h2>Preamble</h2>\r
+<p>\r
+ This License governs Your use of the Work. This License is intended to allow developers\r
+ to use the Source Code and Executable Files provided as part of the Work in any\r
+ application in any form.\r
+</p>\r
+<p>\r
+ The main points subject to the terms of the License are:</p>\r
+<ul>\r
+ <li>Source Code and Executable Files can be used in commercial applications;</li>\r
+ <li>Source Code and Executable Files can be redistributed; and</li>\r
+ <li>Source Code can be modified to create derivative works.</li>\r
+ <li>No claim of suitability, guarantee, or any warranty whatsoever is provided. The software is\r
+ provided "as-is".</li>\r
+ <li>The Article accompanying the Work may not be distributed or republished without the \r
+ Author's consent</li>\r
+</ul>\r
+\r
+<p>\r
+ This License is entered between You, the individual or other entity reading or otherwise\r
+ making use of the Work licensed pursuant to this License and the individual or other\r
+ entity which offers the Work under the terms of this License ("Author").</p>\r
+\r
+ <h2>License</h2>\r
+ <p>\r
+ THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CODE PROJECT OPEN\r
+ LICENSE ("LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE\r
+ LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT\r
+ LAW IS PROHIBITED.</p>\r
+ <p>\r
+ BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HEREIN, YOU ACCEPT AND AGREE TO BE\r
+ BOUND BY THE TERMS OF THIS LICENSE. THE AUTHOR GRANTS YOU THE RIGHTS CONTAINED HEREIN\r
+ IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS. IF YOU DO NOT\r
+ AGREE TO ACCEPT AND BE BOUND BY THE TERMS OF THIS LICENSE, YOU CANNOT MAKE ANY\r
+ USE OF THE WORK.</p>\r
+ \r
+<ol class="SpacedList">\r
+ <li><strong>Definitions.</strong>\r
+ \r
+ <ol class="SpacedList" style="list-style-type: lower-alpha;">\r
+ <li><strong>"Articles"</strong> means, collectively, all articles written by Author\r
+ which describes how the Source Code and Executable Files for the Work may be used\r
+ by a user.</li>\r
+ <li><b>"Author"</b> means the individual or entity that offers the Work under the terms\r
+ of this License.<strong></strong></li>\r
+ <li><strong>"Derivative Work"</strong> means a work based upon the Work or upon the\r
+ Work and other pre-existing works.</li>\r
+ <li><b>"Executable Files"</b> refer to the executables, binary files, configuration\r
+ and any required data files included in the Work.</li>\r
+ <li>"<b>Publisher</b>" means the provider of the website, magazine, CD-ROM, DVD or other\r
+ medium from or by which the Work is obtained by You.</li>\r
+ <li><b>"Source Code"</b> refers to the collection of source code and configuration files\r
+ used to create the Executable Files.</li>\r
+ <li><b>"Standard Version"</b> refers to such a Work if it has not been modified, or\r
+ has been modified in accordance with the consent of the Author, such consent being\r
+ in the full discretion of the Author. </li>\r
+ <li><b>"Work"</b> refers to the collection of files distributed by the Publisher, including\r
+ the Source Code, Executable Files, binaries, data files, documentation, whitepapers\r
+ and the Articles. </li>\r
+ <li><b>"You"</b> is you, an individual or entity wishing to use the Work and exercise\r
+ your rights under this License.\r
+ </li>\r
+ </ol>\r
+ </li>\r
+ \r
+ <li><strong>Fair Use/Fair Use Rights.</strong> Nothing in this License is intended to\r
+ reduce, limit, or restrict any rights arising from fair use, fair dealing, first\r
+ sale or other limitations on the exclusive rights of the copyright owner under copyright\r
+ law or other applicable laws.\r
+ </li>\r
+ \r
+ <li><strong>License Grant.</strong> Subject to the terms and conditions of this License,\r
+ the Author hereby grants You a worldwide, royalty-free, non-exclusive, perpetual\r
+ (for the duration of the applicable copyright) license to exercise the rights in\r
+ the Work as stated below:\r
+ \r
+ <ol class="SpacedList" style="list-style-type: lower-alpha;">\r
+ <li>You may use the standard version of the Source Code or Executable Files in Your\r
+ own applications. </li>\r
+ <li>You may apply bug fixes, portability fixes and other modifications obtained from\r
+ the Public Domain or from the Author. A Work modified in such a way shall still\r
+ be considered the standard version and will be subject to this License.</li>\r
+ <li>You may otherwise modify Your copy of this Work (excluding the Articles) in any\r
+ way to create a Derivative Work, provided that You insert a prominent notice in\r
+ each changed file stating how, when and where You changed that file.</li>\r
+ <li>You may distribute the standard version of the Executable Files and Source Code\r
+ or Derivative Work in aggregate with other (possibly commercial) programs as part\r
+ of a larger (possibly commercial) software distribution. </li>\r
+ <li>The Articles discussing the Work published in any form by the author may not be\r
+ distributed or republished without the Author's consent. The author retains\r
+ copyright to any such Articles. You may use the Executable Files and Source Code\r
+ pursuant to this License but you may not repost or republish or otherwise distribute\r
+ or make available the Articles, without the prior written consent of the Author.</li>\r
+ </ol>\r
+ \r
+ Any subroutines or modules supplied by You and linked into the Source Code or Executable\r
+ Files this Work shall not be considered part of this Work and will not be subject\r
+ to the terms of this License.\r
+ </li>\r
+ \r
+ <li><strong>Patent License.</strong> Subject to the terms and conditions of this License, \r
+ each Author hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, \r
+ irrevocable (except as stated in this section) patent license to make, have made, use, import, \r
+ and otherwise transfer the Work.</li>\r
+ \r
+ <li><strong>Restrictions.</strong> The license granted in Section 3 above is expressly\r
+ made subject to and limited by the following restrictions:\r
+ \r
+ <ol class="SpacedList" style="list-style-type: lower-alpha;">\r
+ <li>You agree not to remove any of the original copyright, patent, trademark, and \r
+ attribution notices and associated disclaimers that may appear in the Source Code \r
+ or Executable Files. </li>\r
+ <li>You agree not to advertise or in any way imply that this Work is a product of Your\r
+ own. </li>\r
+ <li>The name of the Author may not be used to endorse or promote products derived from\r
+ the Work without the prior written consent of the Author.</li>\r
+ <li>You agree not to sell, lease, or rent any part of the Work. This does not restrict\r
+ you from including the Work or any part of the Work inside a larger software \r
+ distribution that itself is being sold. The Work by itself, though, cannot be sold, \r
+ leased or rented.</li>\r
+ <li>You may distribute the Executable Files and Source Code only under the terms of\r
+ this License, and You must include a copy of, or the Uniform Resource Identifier\r
+ for, this License with every copy of the Executable Files or Source Code You distribute\r
+ and ensure that anyone receiving such Executable Files and Source Code agrees that\r
+ the terms of this License apply to such Executable Files and/or Source Code. You\r
+ may not offer or impose any terms on the Work that alter or restrict the terms of\r
+ this License or the recipients' exercise of the rights granted hereunder. You\r
+ may not sublicense the Work. You must keep intact all notices that refer to this\r
+ License and to the disclaimer of warranties. You may not distribute the Executable\r
+ Files or Source Code with any technological measures that control access or use\r
+ of the Work in a manner inconsistent with the terms of this License. </li>\r
+ <li>You agree not to use the Work for illegal, immoral or improper purposes, or on pages\r
+ containing illegal, immoral or improper material. The Work is subject to applicable\r
+ export laws. You agree to comply with all such laws and regulations that may apply\r
+ to the Work after Your receipt of the Work.\r
+ </li>\r
+ </ol>\r
+ </li>\r
+ \r
+ <li><strong>Representations, Warranties and Disclaimer.</strong> THIS WORK IS PROVIDED\r
+ "AS IS", "WHERE IS" AND "AS AVAILABLE", WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES\r
+ OR CONDITIONS OR GUARANTEES. YOU, THE USER, ASSUME ALL RISK IN ITS USE, INCLUDING\r
+ COPYRIGHT INFRINGEMENT, PATENT INFRINGEMENT, SUITABILITY, ETC. AUTHOR EXPRESSLY\r
+ DISCLAIMS ALL EXPRESS, IMPLIED OR STATUTORY WARRANTIES OR CONDITIONS, INCLUDING\r
+ WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY\r
+ OR FITNESS FOR A PARTICULAR PURPOSE, OR ANY WARRANTY OF TITLE OR NON-INFRINGEMENT,\r
+ OR THAT THE WORK (OR ANY PORTION THEREOF) IS CORRECT, USEFUL, BUG-FREE OR FREE OF\r
+ VIRUSES. YOU MUST PASS THIS DISCLAIMER ON WHENEVER YOU DISTRIBUTE THE WORK OR DERIVATIVE\r
+ WORKS.\r
+ </li>\r
+ \r
+ <li><b>Indemnity. </b>You agree to defend, indemnify and hold harmless the Author and\r
+ the Publisher from and against any claims, suits, losses, damages, liabilities,\r
+ costs, and expenses (including reasonable legal or attorneys\92 fees) resulting from\r
+ or relating to any use of the Work by You.\r
+ </li>\r
+ \r
+ <li><strong>Limitation on Liability.</strong> EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE\r
+ LAW, IN NO EVENT WILL THE AUTHOR OR THE PUBLISHER BE LIABLE TO YOU ON ANY LEGAL\r
+ THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES\r
+ ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK OR OTHERWISE, EVEN IF THE AUTHOR\r
+ OR THE PUBLISHER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.\r
+ </li>\r
+ \r
+ <li><strong>Termination.</strong>\r
+ \r
+ <ol style="list-style-type: lower-alpha;">\r
+ <li>This License and the rights granted hereunder will terminate automatically upon\r
+ any breach by You of any term of this License. Individuals or entities who have\r
+ received Derivative Works from You under this License, however, will not have their\r
+ licenses terminated provided such individuals or entities remain in full compliance\r
+ with those licenses. Sections 1, 2, 6, 7, 8, 9, 10 and 11 will survive any termination\r
+ of this License. </li>\r
+ \r
+ <li>If You bring a copyright, trademark, patent or any other infringement claim against \r
+ any contributor over infringements You claim are made by the Work, your License \r
+ from such contributor to the Work ends automatically.</li>\r
+ \r
+ <li>Subject to the above terms and conditions, this License is perpetual (for the duration\r
+ of the applicable copyright in the Work). Notwithstanding the above, the Author\r
+ reserves the right to release the Work under different license terms or to stop\r
+ distributing the Work at any time; provided, however that any such election will\r
+ not serve to withdraw this License (or any other license that has been, or is required\r
+ to be, granted under the terms of this License), and this License will continue\r
+ in full force and effect unless terminated as stated above.\r
+ </li>\r
+ </ol>\r
+ </li>\r
+ \r
+ <li><strong>Publisher</strong>. The parties hereby confirm that the Publisher shall\r
+ not, under any circumstances, be responsible for and shall not have any liability\r
+ in respect of the subject matter of this License. The Publisher makes no warranty\r
+ whatsoever in connection with the Work and shall not be liable to You or any party\r
+ on any legal theory for any damages whatsoever, including without limitation any\r
+ general, special, incidental or consequential damages arising in connection to this\r
+ license. The Publisher reserves the right to cease making the Work available to\r
+ You at any time without notice</li>\r
+ \r
+ <li><strong>Miscellaneous</strong>\r
+ \r
+ <ol class="SpacedList" style="list-style-type: lower-alpha;">\r
+ <li>This License shall be governed by the laws of the location of the head office of\r
+ the Author or if the Author is an individual, the laws of location of the principal\r
+ place of residence of the Author.</li>\r
+ <li>If any provision of this License is invalid or unenforceable under applicable law,\r
+ it shall not affect the validity or enforceability of the remainder of the terms\r
+ of this License, and without further action by the parties to this License, such\r
+ provision shall be reformed to the minimum extent necessary to make such provision\r
+ valid and enforceable. </li>\r
+ <li>No term or provision of this License shall be deemed waived and no breach consented\r
+ to unless such waiver or consent shall be in writing and signed by the party to\r
+ be charged with such waiver or consent. </li>\r
+ <li>This License constitutes the entire agreement between the parties with respect to\r
+ the Work licensed herein. There are no understandings, agreements or representations\r
+ with respect to the Work not specified herein. The Author shall not be bound by\r
+ any additional provisions that may appear in any communication from You. This License\r
+ may not be modified without the mutual written agreement of the Author and You.\r
+ </li>\r
+ </ol>\r
+ \r
+ </li>\r
+</ol>\r
+\r
+</div>\r
+</center>\r
+\r
+</body>\r
+</html>\r
--- /dev/null
+Support for delegate constructs
--- /dev/null
+#include <stdio.h>\r
+#include "FastDelegate.h"\r
+// Demonstrate the syntax for FastDelegates.\r
+// -Don Clugston, May 2004.\r
+// It's a really boring example, but it shows the most important cases.\r
+\r
+// Declare some functions of varying complexity...\r
+void SimpleStaticFunction(int num, char *str) {\r
+ printf("In SimpleStaticFunction. Num=%d, str = %s\n", num, str);\r
+}\r
+\r
+void SimpleVoidFunction() {\r
+ printf("In SimpleVoidFunction with no parameters.\n");\r
+}\r
+\r
+class CBaseClass {\r
+protected:\r
+ char *m_name;\r
+public:\r
+ CBaseClass(char *name) : m_name(name) {};\r
+ void SimpleMemberFunction(int num, char *str) {\r
+ printf("In SimpleMemberFunction in %s. Num=%d, str = %s\n", m_name, num, str); }\r
+ int SimpleMemberFunctionReturnsInt(int num, char *str) {\r
+ printf("In SimpleMemberFunction in %s. Num=%d, str = %s\n", m_name, num, str); return -1; }\r
+ void ConstMemberFunction(int num, char *str) const {\r
+ printf("In ConstMemberFunction in %s. Num=%d, str = %s\n", m_name, num, str); }\r
+ virtual void SimpleVirtualFunction(int num, char *str) {\r
+ printf("In SimpleVirtualFunction in %s. Num=%d, str = %s\n", m_name, num, str); }\r
+ static void StaticMemberFunction(int num, char *str) {\r
+ printf("In StaticMemberFunction. Num=%d, str =%s\n", num, str); }\r
+};\r
+\r
+class COtherClass {\r
+ double rubbish; // to ensure this class has non-zero size.\r
+public:\r
+ virtual void UnusedVirtualFunction(void) { }\r
+ virtual void TrickyVirtualFunction(int num, char *str)=0;\r
+};\r
+\r
+class VeryBigClass {\r
+ int letsMakeThingsComplicated[400];\r
+};\r
+\r
+// This declaration ensures that we get a convoluted class heirarchy.\r
+class CDerivedClass : public VeryBigClass, virtual public COtherClass, virtual public CBaseClass\r
+{\r
+ double m_somemember[8];\r
+public:\r
+ CDerivedClass() : CBaseClass("Base of Derived") { m_somemember[0]=1.2345; }\r
+ void SimpleDerivedFunction(int num, char *str) { printf("In SimpleDerived. num=%d\n", num); }\r
+ virtual void AnotherUnusedVirtualFunction(int num, char *str) {}\r
+ virtual void TrickyVirtualFunction(int num, char *str) {\r
+ printf("In Derived TrickyMemberFunction. Num=%d, str = %s\n", num, str);\r
+ }\r
+};\r
+\r
+using namespace fastdelegate;\r
+\r
+int main(void)\r
+{\r
+ // Delegates with up to 8 parameters are supported.\r
+ // Here's the case for a void function.\r
+ // We declare a delegate and attach it to SimpleVoidFunction()\r
+ printf("-- FastDelegate demo --\nA no-parameter delegate is declared using FastDelegate0\n\n");\r
+\r
+ FastDelegate0<> noparameterdelegate(&SimpleVoidFunction);\r
+\r
+ noparameterdelegate(); // invoke the delegate - this calls SimpleVoidFunction()\r
+\r
+ printf("\n-- Examples using two-parameter delegates (int, char *) --\n\n");\r
+\r
+ // By default, the return value is void.\r
+ typedef FastDelegate2<int, char *> MyDelegate;\r
+\r
+ // If you want to have a non-void return value, put it at the end.\r
+ typedef FastDelegate2<int, char *, int> IntMyDelegate;\r
+\r
+\r
+ MyDelegate funclist[12]; // delegates are initialized to empty\r
+ CBaseClass a("Base A");\r
+ CBaseClass b("Base B");\r
+ CDerivedClass d;\r
+ CDerivedClass c;\r
+\r
+ IntMyDelegate newdeleg;\r
+ newdeleg = MakeDelegate(&a, &CBaseClass::SimpleMemberFunctionReturnsInt);\r
+ \r
+ // Binding a simple member function\r
+ funclist[0].bind(&a, &CBaseClass::SimpleMemberFunction);\r
+ \r
+ // You can also bind static (free) functions\r
+ funclist[1].bind(&SimpleStaticFunction);\r
+ // and static member functions\r
+ funclist[2].bind(&CBaseClass::StaticMemberFunction);\r
+ // and const member functions (these only need a const class pointer). \r
+ funclist[11].bind( (const CBaseClass *)&a, &CBaseClass::ConstMemberFunction);\r
+ funclist[3].bind( &a, &CBaseClass::ConstMemberFunction);\r
+ // and virtual member functions\r
+ funclist[4].bind(&b, &CBaseClass::SimpleVirtualFunction);\r
+\r
+ // You can also use the = operator. For static functions, a fastdelegate\r
+ // looks identical to a simple function pointer.\r
+ funclist[5] = &CBaseClass::StaticMemberFunction;\r
+\r
+ // The weird rule about the class of derived member function pointers is avoided.\r
+ // For MSVC, you can use &CDerivedClass::SimpleVirtualFunction here, but DMC will complain.\r
+ // Note that as well as .bind(), you can also use the MakeDelegate()\r
+ // global function.\r
+ funclist[6] = MakeDelegate(&d, &CBaseClass::SimpleVirtualFunction);\r
+\r
+ // The worst case is an abstract virtual function of a virtually-derived class\r
+ // with at least one non-virtual base class. This is a VERY obscure situation,\r
+ // which you're unlikely to encounter in the real world.\r
+ // FastDelegate versions prior to 1.3 had problems with this case on VC6.\r
+ // Now, it works without problems on all compilers.\r
+ funclist[7].bind(&c, &CDerivedClass::TrickyVirtualFunction);\r
+ // BUT... in such cases you should be using the base class as an \r
+ // interface, anyway.\r
+ funclist[8].bind(&c, &COtherClass::TrickyVirtualFunction);\r
+ // Calling a function that was first declared in the derived class is straightforward\r
+ funclist[9] = MakeDelegate(&c, &CDerivedClass::SimpleDerivedFunction);\r
+\r
+ // You can also bind directly using the constructor\r
+ MyDelegate dg(&b, &CBaseClass::SimpleVirtualFunction);\r
+\r
+ char *msg = "Looking for equal delegate";\r
+ for (int i=0; i<12; i++) {\r
+ printf("%d :", i);\r
+ // The == and != operators are provided\r
+ // Note that they work even for inline functions.\r
+ if (funclist[i]==dg) { msg = "Found equal delegate"; };\r
+ // operator ! can be used to test for an empty delegate\r
+ // You can also use the .empty() member function.\r
+ if (!funclist[i]) {\r
+ printf("Delegate is empty\n");\r
+ } else {\r
+ // Invocation generates optimal assembly code.\r
+ funclist[i](i, msg);\r
+ };\r
+ }\r
+ return 0;\r
+}\r
+\r
--- /dev/null
+License
+
+The source code attached to this article is released into the public domain.
+You may use it for any purpose. Frankly, writing the article was about ten
+times as much work as writing the code. Of course, if you create great software
+using the code, I would be interested to hear about it. And submissions are always welcome.
+
--- /dev/null
+Minizip - ZIP file format support
--- /dev/null
+CC=cc
+CFLAGS=-O -I../..
+
+UNZ_OBJS = miniunz.o unzip.o ioapi.o ../../libz.a
+ZIP_OBJS = minizip.o zip.o ioapi.o ../../libz.a
+
+.c.o:
+ $(CC) -c $(CFLAGS) $*.c
+
+all: miniunz minizip
+
+miniunz: $(UNZ_OBJS)
+ $(CC) $(CFLAGS) -o $@ $(UNZ_OBJS)
+
+minizip: $(ZIP_OBJS)
+ $(CC) $(CFLAGS) -o $@ $(ZIP_OBJS)
+
+test: miniunz minizip
+ ./minizip test readme.txt
+ ./miniunz -l test.zip
+ mv readme.txt readme.old
+ ./miniunz test.zip
+
+clean:
+ /bin/rm -f *.o *~ minizip miniunz
--- /dev/null
+
+MiniZip 1.1 was derrived from MiniZip at version 1.01f
+
+Change in 1.0 (Okt 2009)
+ - **TODO - Add history**
+
--- /dev/null
+MiniZip - Copyright (c) 1998-2010 - by Gilles Vollant - version 1.1 64 bits from Mathias Svensson
+
+Introduction
+---------------------
+MiniZip 1.1 is built from MiniZip 1.0 by Gilles Vollant ( http://www.winimage.com/zLibDll/minizip.html )
+
+When adding ZIP64 support into minizip it would result into risk of breaking compatibility with minizip 1.0.
+All possible work was done for compatibility.
+
+
+Background
+---------------------
+When adding ZIP64 support Mathias Svensson found that Even Rouault have added ZIP64
+support for unzip.c into minizip for a open source project called gdal ( http://www.gdal.org/ )
+
+That was used as a starting point. And after that ZIP64 support was added to zip.c
+some refactoring and code cleanup was also done.
+
+
+Changed from MiniZip 1.0 to MiniZip 1.1
+---------------------------------------
+* Added ZIP64 support for unzip ( by Even Rouault )
+* Added ZIP64 support for zip ( by Mathias Svensson )
+* Reverted some changed that Even Rouault did.
+* Bunch of patches received from Gulles Vollant that he received for MiniZip from various users.
+* Added unzip patch for BZIP Compression method (patch create by Daniel Borca)
+* Added BZIP Compress method for zip
+* Did some refactoring and code cleanup
+
+
+Credits
+
+ Gilles Vollant - Original MiniZip author
+ Even Rouault - ZIP64 unzip Support
+ Daniel Borca - BZip Compression method support in unzip
+ Mathias Svensson - ZIP64 zip support
+ Mathias Svensson - BZip Compression method support in zip
+
+ Resources
+
+ ZipLayout http://result42.com/projects/ZipFileLayout
+ Command line tool for Windows that shows the layout and information of the headers in a zip archive.
+ Used when debugging and validating the creation of zip files using MiniZip64
+
+
+ ZIP App Note http://www.pkware.com/documents/casestudies/APPNOTE.TXT
+ Zip File specification
+
+
+Notes.
+ * To be able to use BZip compression method in zip64.c or unzip64.c the BZIP2 lib is needed and HAVE_BZIP2 need to be defined.
+
+License
+----------------------------------------------------------
+ Condition of use and distribution are the same than zlib :
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+----------------------------------------------------------
+
--- /dev/null
+/* crypt.h -- base code for crypt/uncrypt ZIPfile
+
+
+ Version 1.01e, February 12th, 2005
+
+ Copyright (C) 1998-2005 Gilles Vollant
+
+ This code is a modified version of crypting code in Infozip distribution
+
+ The encryption/decryption parts of this source code (as opposed to the
+ non-echoing password parts) were originally written in Europe. The
+ whole source package can be freely distributed, including from the USA.
+ (Prior to January 2000, re-export from the US was a violation of US law.)
+
+ This encryption code is a direct transcription of the algorithm from
+ Roger Schlafly, described by Phil Katz in the file appnote.txt. This
+ file (appnote.txt) is distributed with the PKZIP program (even in the
+ version without encryption capabilities).
+
+ If you don't need crypting in your application, just define symbols
+ NOCRYPT and NOUNCRYPT.
+
+ This code support the "Traditional PKWARE Encryption".
+
+ The new AES encryption added on Zip format by Winzip (see the page
+ http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong
+ Encryption is not supported.
+*/
+
+#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))
+
+/***********************************************************************
+ * Return the next byte in the pseudo-random sequence
+ */
+static int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab)
+{
+ unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an
+ * unpredictable manner on 16-bit systems; not a problem
+ * with any known compiler so far, though */
+
+ temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2;
+ return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
+}
+
+/***********************************************************************
+ * Update the encryption keys with the next byte of plain text
+ */
+static int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c)
+{
+ (*(pkeys+0)) = CRC32((*(pkeys+0)), c);
+ (*(pkeys+1)) += (*(pkeys+0)) & 0xff;
+ (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
+ {
+ register int keyshift = (int)((*(pkeys+1)) >> 24);
+ (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);
+ }
+ return c;
+}
+
+
+/***********************************************************************
+ * Initialize the encryption keys and the random header according to
+ * the given password.
+ */
+static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab)
+{
+ *(pkeys+0) = 305419896L;
+ *(pkeys+1) = 591751049L;
+ *(pkeys+2) = 878082192L;
+ while (*passwd != '\0') {
+ update_keys(pkeys,pcrc_32_tab,(int)*passwd);
+ passwd++;
+ }
+}
+
+#define zdecode(pkeys,pcrc_32_tab,c) \
+ (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))
+
+#define zencode(pkeys,pcrc_32_tab,c,t) \
+ (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c))
+
+#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED
+
+#define RAND_HEAD_LEN 12
+ /* "last resort" source for second part of crypt seed pattern */
+# ifndef ZCR_SEED2
+# define ZCR_SEED2 3141592654UL /* use PI as default pattern */
+# endif
+
+static int crypthead(const char* passwd, /* password string */
+ unsigned char* buf, /* where to write header */
+ int bufSize,
+ unsigned long* pkeys,
+ const unsigned long* pcrc_32_tab,
+ unsigned long crcForCrypting)
+{
+ int n; /* index in random header */
+ int t; /* temporary */
+ int c; /* random byte */
+ unsigned char header[RAND_HEAD_LEN-2]; /* random header */
+ static unsigned calls = 0; /* ensure different random header each time */
+
+ if (bufSize<RAND_HEAD_LEN)
+ return 0;
+
+ /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
+ * output of rand() to get less predictability, since rand() is
+ * often poorly implemented.
+ */
+ if (++calls == 1)
+ {
+ srand((unsigned)(time(NULL) ^ ZCR_SEED2));
+ }
+ init_keys(passwd, pkeys, pcrc_32_tab);
+ for (n = 0; n < RAND_HEAD_LEN-2; n++)
+ {
+ c = (rand() >> 7) & 0xff;
+ header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t);
+ }
+ /* Encrypt random header (last two bytes is high word of crc) */
+ init_keys(passwd, pkeys, pcrc_32_tab);
+ for (n = 0; n < RAND_HEAD_LEN-2; n++)
+ {
+ buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t);
+ }
+ buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);
+ buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);
+ return n;
+}
+
+#endif
--- /dev/null
+/*
+ * @file framework_minizip.h
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the forward header file for minizip library
+ */
+#pragma GCC system_header
+#include <minizip/unzip.h>
--- /dev/null
+/* ioapi.h -- IO base function header for compress/uncompress .zip
+ part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Modifications for Zip64 support
+ Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+ For more info read MiniZip_info.txt
+
+*/
+
+#if (defined(_WIN32))
+ #define _CRT_SECURE_NO_WARNINGS
+#endif
+
+#include "ioapi.h"
+
+voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)
+{
+ if (pfilefunc->zfile_func64.zopen64_file != NULL)
+ return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,filename,mode);
+ else
+ {
+ return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,(const char*)filename,mode);
+ }
+}
+
+long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)
+{
+ if (pfilefunc->zfile_func64.zseek64_file != NULL)
+ return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin);
+ else
+ {
+ uLong offsetTruncated = (uLong)offset;
+ if (offsetTruncated != offset)
+ return -1;
+ else
+ return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin);
+ }
+}
+
+ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)
+{
+ if (pfilefunc->zfile_func64.zseek64_file != NULL)
+ return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream);
+ else
+ {
+ uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream);
+ if ((tell_uLong) == ((uLong)-1))
+ return (ZPOS64_T)-1;
+ else
+ return tell_uLong;
+ }
+}
+
+void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32)
+{
+ p_filefunc64_32->zfile_func64.zopen64_file = NULL;
+ p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file;
+ p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
+ p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file;
+ p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file;
+ p_filefunc64_32->zfile_func64.ztell64_file = NULL;
+ p_filefunc64_32->zfile_func64.zseek64_file = NULL;
+ p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file;
+ p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
+ p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque;
+ p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file;
+ p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file;
+}
+
+
+
+static voidpf ZCALLBACK fopen_file_func OF((voidpf opaque, const char* filename, int mode));
+static uLong ZCALLBACK fread_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size));
+static uLong ZCALLBACK fwrite_file_func OF((voidpf opaque, voidpf stream, const void* buf,uLong size));
+static ZPOS64_T ZCALLBACK ftell64_file_func OF((voidpf opaque, voidpf stream));
+static long ZCALLBACK fseek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
+static int ZCALLBACK fclose_file_func OF((voidpf opaque, voidpf stream));
+static int ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream));
+
+static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode)
+{
+ FILE* file = NULL;
+ const char* mode_fopen = NULL;
+ if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
+ mode_fopen = "rb";
+ else
+ if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
+ mode_fopen = "r+b";
+ else
+ if (mode & ZLIB_FILEFUNC_MODE_CREATE)
+ mode_fopen = "wb";
+
+ if ((filename!=NULL) && (mode_fopen != NULL))
+ file = fopen(filename, mode_fopen);
+ return file;
+}
+
+static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, int mode)
+{
+ FILE* file = NULL;
+ const char* mode_fopen = NULL;
+ if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
+ mode_fopen = "rb";
+ else
+ if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
+ mode_fopen = "r+b";
+ else
+ if (mode & ZLIB_FILEFUNC_MODE_CREATE)
+ mode_fopen = "wb";
+
+ if ((filename!=NULL) && (mode_fopen != NULL))
+ file = fopen64((const char*)filename, mode_fopen);
+ return file;
+}
+
+
+static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size)
+{
+ uLong ret;
+ ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream);
+ return ret;
+}
+
+static uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size)
+{
+ uLong ret;
+ ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream);
+ return ret;
+}
+
+static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream)
+{
+ long ret;
+ ret = ftell((FILE *)stream);
+ return ret;
+}
+
+
+static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream)
+{
+ ZPOS64_T ret;
+ ret = ftello64((FILE *)stream);
+ return ret;
+}
+
+static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offset, int origin)
+{
+ int fseek_origin=0;
+ long ret;
+ switch (origin)
+ {
+ case ZLIB_FILEFUNC_SEEK_CUR :
+ fseek_origin = SEEK_CUR;
+ break;
+ case ZLIB_FILEFUNC_SEEK_END :
+ fseek_origin = SEEK_END;
+ break;
+ case ZLIB_FILEFUNC_SEEK_SET :
+ fseek_origin = SEEK_SET;
+ break;
+ default: return -1;
+ }
+ ret = 0;
+ if (fseek((FILE *)stream, offset, fseek_origin) != 0)
+ ret = -1;
+ return ret;
+}
+
+static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)
+{
+ int fseek_origin=0;
+ long ret;
+ switch (origin)
+ {
+ case ZLIB_FILEFUNC_SEEK_CUR :
+ fseek_origin = SEEK_CUR;
+ break;
+ case ZLIB_FILEFUNC_SEEK_END :
+ fseek_origin = SEEK_END;
+ break;
+ case ZLIB_FILEFUNC_SEEK_SET :
+ fseek_origin = SEEK_SET;
+ break;
+ default: return -1;
+ }
+ ret = 0;
+
+ if(fseeko64((FILE *)stream, offset, fseek_origin) != 0)
+ ret = -1;
+
+ return ret;
+}
+
+
+static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream)
+{
+ int ret;
+ ret = fclose((FILE *)stream);
+ return ret;
+}
+
+static int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream)
+{
+ int ret;
+ ret = ferror((FILE *)stream);
+ return ret;
+}
+
+void fill_fopen_filefunc (pzlib_filefunc_def)
+ zlib_filefunc_def* pzlib_filefunc_def;
+{
+ pzlib_filefunc_def->zopen_file = fopen_file_func;
+ pzlib_filefunc_def->zread_file = fread_file_func;
+ pzlib_filefunc_def->zwrite_file = fwrite_file_func;
+ pzlib_filefunc_def->ztell_file = ftell_file_func;
+ pzlib_filefunc_def->zseek_file = fseek_file_func;
+ pzlib_filefunc_def->zclose_file = fclose_file_func;
+ pzlib_filefunc_def->zerror_file = ferror_file_func;
+ pzlib_filefunc_def->opaque = NULL;
+}
+
+void fill_fopen64_filefunc (zlib_filefunc64_def* pzlib_filefunc_def)
+{
+ pzlib_filefunc_def->zopen64_file = fopen64_file_func;
+ pzlib_filefunc_def->zread_file = fread_file_func;
+ pzlib_filefunc_def->zwrite_file = fwrite_file_func;
+ pzlib_filefunc_def->ztell64_file = ftell64_file_func;
+ pzlib_filefunc_def->zseek64_file = fseek64_file_func;
+ pzlib_filefunc_def->zclose_file = fclose_file_func;
+ pzlib_filefunc_def->zerror_file = ferror_file_func;
+ pzlib_filefunc_def->opaque = NULL;
+}
--- /dev/null
+/* ioapi.h -- IO base function header for compress/uncompress .zip
+ part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Modifications for Zip64 support
+ Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+ For more info read MiniZip_info.txt
+
+ Changes
+
+ Oct-2009 - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. (might need to find a better why for this)
+ Oct-2009 - Change to fseeko64, ftello64 and fopen64 so large files would work on linux.
+ More if/def section may be needed to support other platforms
+ Oct-2009 - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows.
+ (but you should use iowin32.c for windows instead)
+
+*/
+
+#ifndef _ZLIBIOAPI64_H
+#define _ZLIBIOAPI64_H
+
+#if (!defined(_WIN32)) && (!defined(WIN32))
+
+ // Linux needs this to support file operation on files larger then 4+GB
+ // But might need better if/def to select just the platforms that needs them.
+
+ #ifndef __USE_FILE_OFFSET64
+ #define __USE_FILE_OFFSET64
+ #endif
+ #ifndef __USE_LARGEFILE64
+ #define __USE_LARGEFILE64
+ #endif
+ #ifndef _LARGEFILE64_SOURCE
+ #define _LARGEFILE64_SOURCE
+ #endif
+ #ifndef _FILE_OFFSET_BIT
+ #define _FILE_OFFSET_BIT 64
+ #endif
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "zlib.h"
+
+#if defined(USE_FILE32API)
+#define fopen64 fopen
+#define ftello64 ftell
+#define fseeko64 fseek
+#else
+#ifdef _MSC_VER
+ #define fopen64 fopen
+ #if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC)))
+ #define ftello64 _ftelli64
+ #define fseeko64 _fseeki64
+ #else // old MSC
+ #define ftello64 ftell
+ #define fseeko64 fseek
+ #endif
+#endif
+#endif
+
+/*
+#ifndef ZPOS64_T
+ #ifdef _WIN32
+ #define ZPOS64_T fpos_t
+ #else
+ #include <stdint.h>
+ #define ZPOS64_T uint64_t
+ #endif
+#endif
+*/
+
+#ifdef HAVE_MINIZIP64_CONF_H
+#include "mz64conf.h"
+#endif
+
+/* a type choosen by DEFINE */
+#ifdef HAVE_64BIT_INT_CUSTOM
+typedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T;
+#else
+#ifdef HAS_STDINT_H
+#include "stdint.h"
+typedef uint64_t ZPOS64_T;
+#else
+
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+typedef unsigned __int64 ZPOS64_T;
+#else
+typedef unsigned long long int ZPOS64_T;
+#endif
+#endif
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define ZLIB_FILEFUNC_SEEK_CUR (1)
+#define ZLIB_FILEFUNC_SEEK_END (2)
+#define ZLIB_FILEFUNC_SEEK_SET (0)
+
+#define ZLIB_FILEFUNC_MODE_READ (1)
+#define ZLIB_FILEFUNC_MODE_WRITE (2)
+#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)
+
+#define ZLIB_FILEFUNC_MODE_EXISTING (4)
+#define ZLIB_FILEFUNC_MODE_CREATE (8)
+
+
+#ifndef ZCALLBACK
+ #if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK)
+ #define ZCALLBACK CALLBACK
+ #else
+ #define ZCALLBACK
+ #endif
+#endif
+
+
+
+
+typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode));
+typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size));
+typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
+typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream));
+typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));
+
+typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream));
+typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin));
+
+
+/* here is the "old" 32 bits structure structure */
+typedef struct zlib_filefunc_def_s
+{
+ open_file_func zopen_file;
+ read_file_func zread_file;
+ write_file_func zwrite_file;
+ tell_file_func ztell_file;
+ seek_file_func zseek_file;
+ close_file_func zclose_file;
+ testerror_file_func zerror_file;
+ voidpf opaque;
+} zlib_filefunc_def;
+
+typedef ZPOS64_T (ZCALLBACK *tell64_file_func) OF((voidpf opaque, voidpf stream));
+typedef long (ZCALLBACK *seek64_file_func) OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
+typedef voidpf (ZCALLBACK *open64_file_func) OF((voidpf opaque, const void* filename, int mode));
+
+typedef struct zlib_filefunc64_def_s
+{
+ open64_file_func zopen64_file;
+ read_file_func zread_file;
+ write_file_func zwrite_file;
+ tell64_file_func ztell64_file;
+ seek64_file_func zseek64_file;
+ close_file_func zclose_file;
+ testerror_file_func zerror_file;
+ voidpf opaque;
+} zlib_filefunc64_def;
+
+void fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def));
+void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
+
+/* now internal definition, only for zip.c and unzip.h */
+typedef struct zlib_filefunc64_32_def_s
+{
+ zlib_filefunc64_def zfile_func64;
+ open_file_func zopen32_file;
+ tell_file_func ztell32_file;
+ seek_file_func zseek32_file;
+} zlib_filefunc64_32_def;
+
+
+#define ZREAD64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zread_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size))
+#define ZWRITE64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zwrite_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size))
+//#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream))
+//#define ZSEEK64(filefunc,filestream,pos,mode) ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode))
+#define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream))
+#define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream))
+
+voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode));
+long call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin));
+ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream));
+
+void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32);
+
+#define ZOPEN64(filefunc,filename,mode) (call_zopen64((&(filefunc)),(filename),(mode)))
+#define ZTELL64(filefunc,filestream) (call_ztell64((&(filefunc)),(filestream)))
+#define ZSEEK64(filefunc,filestream,pos,mode) (call_zseek64((&(filefunc)),(filestream),(pos),(mode)))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null
+/* iowin32.c -- IO base function header for compress/uncompress .zip
+ Version 1.1, February 14h, 2010
+ part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Modifications for Zip64 support
+ Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+ For more info read MiniZip_info.txt
+
+*/
+
+#include <stdlib.h>
+
+#include "zlib.h"
+#include "ioapi.h"
+#include "iowin32.h"
+
+#ifndef INVALID_HANDLE_VALUE
+#define INVALID_HANDLE_VALUE (0xFFFFFFFF)
+#endif
+
+#ifndef INVALID_SET_FILE_POINTER
+#define INVALID_SET_FILE_POINTER ((DWORD)-1)
+#endif
+
+voidpf ZCALLBACK win32_open_file_func OF((voidpf opaque, const char* filename, int mode));
+uLong ZCALLBACK win32_read_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size));
+uLong ZCALLBACK win32_write_file_func OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
+ZPOS64_T ZCALLBACK win32_tell64_file_func OF((voidpf opaque, voidpf stream));
+long ZCALLBACK win32_seek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
+int ZCALLBACK win32_close_file_func OF((voidpf opaque, voidpf stream));
+int ZCALLBACK win32_error_file_func OF((voidpf opaque, voidpf stream));
+
+typedef struct
+{
+ HANDLE hf;
+ int error;
+} WIN32FILE_IOWIN;
+
+
+static void win32_translate_open_mode(int mode,
+ DWORD* lpdwDesiredAccess,
+ DWORD* lpdwCreationDisposition,
+ DWORD* lpdwShareMode,
+ DWORD* lpdwFlagsAndAttributes)
+{
+ *lpdwDesiredAccess = *lpdwShareMode = *lpdwFlagsAndAttributes = *lpdwCreationDisposition = 0;
+
+ if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
+ {
+ *lpdwDesiredAccess = GENERIC_READ;
+ *lpdwCreationDisposition = OPEN_EXISTING;
+ *lpdwShareMode = FILE_SHARE_READ;
+ }
+ else if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
+ {
+ *lpdwDesiredAccess = GENERIC_WRITE | GENERIC_READ;
+ *lpdwCreationDisposition = OPEN_EXISTING;
+ }
+ else if (mode & ZLIB_FILEFUNC_MODE_CREATE)
+ {
+ *lpdwDesiredAccess = GENERIC_WRITE | GENERIC_READ;
+ *lpdwCreationDisposition = CREATE_ALWAYS;
+ }
+}
+
+static voidpf win32_build_iowin(HANDLE hFile)
+{
+ voidpf ret=NULL;
+
+ if ((hFile != NULL) && (hFile != INVALID_HANDLE_VALUE))
+ {
+ WIN32FILE_IOWIN w32fiow;
+ w32fiow.hf = hFile;
+ w32fiow.error = 0;
+ ret = malloc(sizeof(WIN32FILE_IOWIN));
+
+ if (ret==NULL)
+ CloseHandle(hFile);
+ else
+ *((WIN32FILE_IOWIN*)ret) = w32fiow;
+ }
+ return ret;
+}
+
+voidpf ZCALLBACK win32_open64_file_func (voidpf opaque,const void* filename,int mode)
+{
+ const char* mode_fopen = NULL;
+ DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;
+ HANDLE hFile = NULL;
+
+ win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
+
+ if ((filename!=NULL) && (dwDesiredAccess != 0))
+ hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
+
+ return win32_build_iowin(hFile);
+}
+
+
+voidpf ZCALLBACK win32_open64_file_funcA (voidpf opaque,const void* filename,int mode)
+{
+ const char* mode_fopen = NULL;
+ DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;
+ HANDLE hFile = NULL;
+
+ win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
+
+ if ((filename!=NULL) && (dwDesiredAccess != 0))
+ hFile = CreateFileA((LPCSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
+
+ return win32_build_iowin(hFile);
+}
+
+
+voidpf ZCALLBACK win32_open64_file_funcW (voidpf opaque,const void* filename,int mode)
+{
+ const char* mode_fopen = NULL;
+ DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;
+ HANDLE hFile = NULL;
+
+ win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
+
+ if ((filename!=NULL) && (dwDesiredAccess != 0))
+ hFile = CreateFileW((LPCWSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
+
+ return win32_build_iowin(hFile);
+}
+
+
+voidpf ZCALLBACK win32_open_file_func (voidpf opaque,const char* filename,int mode)
+{
+ const char* mode_fopen = NULL;
+ DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;
+ HANDLE hFile = NULL;
+
+ win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
+
+ if ((filename!=NULL) && (dwDesiredAccess != 0))
+ hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
+
+ return win32_build_iowin(hFile);
+}
+
+
+uLong ZCALLBACK win32_read_file_func (voidpf opaque, voidpf stream, void* buf,uLong size)
+{
+ uLong ret=0;
+ HANDLE hFile = NULL;
+ if (stream!=NULL)
+ hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
+
+ if (hFile != NULL)
+ {
+ if (!ReadFile(hFile, buf, size, &ret, NULL))
+ {
+ DWORD dwErr = GetLastError();
+ if (dwErr == ERROR_HANDLE_EOF)
+ dwErr = 0;
+ ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
+ }
+ }
+
+ return ret;
+}
+
+
+uLong ZCALLBACK win32_write_file_func (voidpf opaque,voidpf stream,const void* buf,uLong size)
+{
+ uLong ret=0;
+ HANDLE hFile = NULL;
+ if (stream!=NULL)
+ hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
+
+ if (hFile != NULL)
+ {
+ if (!WriteFile(hFile, buf, size, &ret, NULL))
+ {
+ DWORD dwErr = GetLastError();
+ if (dwErr == ERROR_HANDLE_EOF)
+ dwErr = 0;
+ ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
+ }
+ }
+
+ return ret;
+}
+
+long ZCALLBACK win32_tell_file_func (voidpf opaque,voidpf stream)
+{
+ long ret=-1;
+ HANDLE hFile = NULL;
+ if (stream!=NULL)
+ hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
+ if (hFile != NULL)
+ {
+ DWORD dwSet = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);
+ if (dwSet == INVALID_SET_FILE_POINTER)
+ {
+ DWORD dwErr = GetLastError();
+ ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
+ ret = -1;
+ }
+ else
+ ret=(long)dwSet;
+ }
+ return ret;
+}
+
+ZPOS64_T ZCALLBACK win32_tell64_file_func (voidpf opaque, voidpf stream)
+{
+ ZPOS64_T ret= (ZPOS64_T)-1;
+ HANDLE hFile = NULL;
+ if (stream!=NULL)
+ hFile = ((WIN32FILE_IOWIN*)stream)->hf;
+
+ if (hFile)
+ {
+ LARGE_INTEGER li;
+ li.QuadPart = 0;
+ li.u.LowPart = SetFilePointer(hFile, li.u.LowPart, &li.u.HighPart, FILE_CURRENT);
+ if ( (li.LowPart == 0xFFFFFFFF) && (GetLastError() != NO_ERROR))
+ {
+ DWORD dwErr = GetLastError();
+ ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
+ ret = (ZPOS64_T)-1;
+ }
+ else
+ ret=li.QuadPart;
+ }
+ return ret;
+}
+
+
+long ZCALLBACK win32_seek_file_func (voidpf opaque,voidpf stream,uLong offset,int origin)
+{
+ DWORD dwMoveMethod=0xFFFFFFFF;
+ HANDLE hFile = NULL;
+
+ long ret=-1;
+ if (stream!=NULL)
+ hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
+ switch (origin)
+ {
+ case ZLIB_FILEFUNC_SEEK_CUR :
+ dwMoveMethod = FILE_CURRENT;
+ break;
+ case ZLIB_FILEFUNC_SEEK_END :
+ dwMoveMethod = FILE_END;
+ break;
+ case ZLIB_FILEFUNC_SEEK_SET :
+ dwMoveMethod = FILE_BEGIN;
+ break;
+ default: return -1;
+ }
+
+ if (hFile != NULL)
+ {
+ DWORD dwSet = SetFilePointer(hFile, offset, NULL, dwMoveMethod);
+ if (dwSet == INVALID_SET_FILE_POINTER)
+ {
+ DWORD dwErr = GetLastError();
+ ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
+ ret = -1;
+ }
+ else
+ ret=0;
+ }
+ return ret;
+}
+
+long ZCALLBACK win32_seek64_file_func (voidpf opaque, voidpf stream,ZPOS64_T offset,int origin)
+{
+ DWORD dwMoveMethod=0xFFFFFFFF;
+ HANDLE hFile = NULL;
+ long ret=-1;
+
+ if (stream!=NULL)
+ hFile = ((WIN32FILE_IOWIN*)stream)->hf;
+
+ switch (origin)
+ {
+ case ZLIB_FILEFUNC_SEEK_CUR :
+ dwMoveMethod = FILE_CURRENT;
+ break;
+ case ZLIB_FILEFUNC_SEEK_END :
+ dwMoveMethod = FILE_END;
+ break;
+ case ZLIB_FILEFUNC_SEEK_SET :
+ dwMoveMethod = FILE_BEGIN;
+ break;
+ default: return -1;
+ }
+
+ if (hFile)
+ {
+ LARGE_INTEGER* li = (LARGE_INTEGER*)&offset;
+ DWORD dwSet = SetFilePointer(hFile, li->u.LowPart, &li->u.HighPart, dwMoveMethod);
+ if (dwSet == INVALID_SET_FILE_POINTER)
+ {
+ DWORD dwErr = GetLastError();
+ ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
+ ret = -1;
+ }
+ else
+ ret=0;
+ }
+ return ret;
+}
+
+int ZCALLBACK win32_close_file_func (voidpf opaque, voidpf stream)
+{
+ int ret=-1;
+
+ if (stream!=NULL)
+ {
+ HANDLE hFile;
+ hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
+ if (hFile != NULL)
+ {
+ CloseHandle(hFile);
+ ret=0;
+ }
+ free(stream);
+ }
+ return ret;
+}
+
+int ZCALLBACK win32_error_file_func (voidpf opaque,voidpf stream)
+{
+ int ret=-1;
+ if (stream!=NULL)
+ {
+ ret = ((WIN32FILE_IOWIN*)stream) -> error;
+ }
+ return ret;
+}
+
+void fill_win32_filefunc (zlib_filefunc_def* pzlib_filefunc_def)
+{
+ pzlib_filefunc_def->zopen_file = win32_open_file_func;
+ pzlib_filefunc_def->zread_file = win32_read_file_func;
+ pzlib_filefunc_def->zwrite_file = win32_write_file_func;
+ pzlib_filefunc_def->ztell_file = win32_tell_file_func;
+ pzlib_filefunc_def->zseek_file = win32_seek_file_func;
+ pzlib_filefunc_def->zclose_file = win32_close_file_func;
+ pzlib_filefunc_def->zerror_file = win32_error_file_func;
+ pzlib_filefunc_def->opaque = NULL;
+}
+
+void fill_win32_filefunc64(zlib_filefunc64_def* pzlib_filefunc_def)
+{
+ pzlib_filefunc_def->zopen64_file = win32_open64_file_func;
+ pzlib_filefunc_def->zread_file = win32_read_file_func;
+ pzlib_filefunc_def->zwrite_file = win32_write_file_func;
+ pzlib_filefunc_def->ztell64_file = win32_tell64_file_func;
+ pzlib_filefunc_def->zseek64_file = win32_seek64_file_func;
+ pzlib_filefunc_def->zclose_file = win32_close_file_func;
+ pzlib_filefunc_def->zerror_file = win32_error_file_func;
+ pzlib_filefunc_def->opaque = NULL;
+}
+
+
+void fill_win32_filefunc64A(zlib_filefunc64_def* pzlib_filefunc_def)
+{
+ pzlib_filefunc_def->zopen64_file = win32_open64_file_funcA;
+ pzlib_filefunc_def->zread_file = win32_read_file_func;
+ pzlib_filefunc_def->zwrite_file = win32_write_file_func;
+ pzlib_filefunc_def->ztell64_file = win32_tell64_file_func;
+ pzlib_filefunc_def->zseek64_file = win32_seek64_file_func;
+ pzlib_filefunc_def->zclose_file = win32_close_file_func;
+ pzlib_filefunc_def->zerror_file = win32_error_file_func;
+ pzlib_filefunc_def->opaque = NULL;
+}
+
+
+void fill_win32_filefunc64W(zlib_filefunc64_def* pzlib_filefunc_def)
+{
+ pzlib_filefunc_def->zopen64_file = win32_open64_file_funcW;
+ pzlib_filefunc_def->zread_file = win32_read_file_func;
+ pzlib_filefunc_def->zwrite_file = win32_write_file_func;
+ pzlib_filefunc_def->ztell64_file = win32_tell64_file_func;
+ pzlib_filefunc_def->zseek64_file = win32_seek64_file_func;
+ pzlib_filefunc_def->zclose_file = win32_close_file_func;
+ pzlib_filefunc_def->zerror_file = win32_error_file_func;
+ pzlib_filefunc_def->opaque = NULL;
+}
--- /dev/null
+/* iowin32.h -- IO base function header for compress/uncompress .zip
+ Version 1.1, February 14h, 2010
+ part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Modifications for Zip64 support
+ Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+ For more info read MiniZip_info.txt
+
+*/
+
+#include <windows.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void fill_win32_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
+void fill_win32_filefunc64 OF((zlib_filefunc64_def* pzlib_filefunc_def));
+void fill_win32_filefunc64A OF((zlib_filefunc64_def* pzlib_filefunc_def));
+void fill_win32_filefunc64W OF((zlib_filefunc64_def* pzlib_filefunc_def));
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null
+$ if f$search("ioapi.h_orig") .eqs. "" then copy ioapi.h ioapi.h_orig
+$ open/write zdef vmsdefs.h
+$ copy sys$input: zdef
+$ deck
+#define unix
+#define fill_zlib_filefunc64_32_def_from_filefunc32 fillzffunc64from
+#define Write_Zip64EndOfCentralDirectoryLocator Write_Zip64EoDLocator
+#define Write_Zip64EndOfCentralDirectoryRecord Write_Zip64EoDRecord
+#define Write_EndOfCentralDirectoryRecord Write_EoDRecord
+$ eod
+$ close zdef
+$ copy vmsdefs.h,ioapi.h_orig ioapi.h
+$ cc/include=[--]/prefix=all ioapi.c
+$ cc/include=[--]/prefix=all miniunz.c
+$ cc/include=[--]/prefix=all unzip.c
+$ cc/include=[--]/prefix=all minizip.c
+$ cc/include=[--]/prefix=all zip.c
+$ link miniunz,unzip,ioapi,[--]libz.olb/lib
+$ link minizip,zip,ioapi,[--]libz.olb/lib
+$ mcr []minizip test minizip_info.txt
+$ mcr []miniunz -l test.zip
+$ rename minizip_info.txt; minizip_info.txt_old
+$ mcr []miniunz test.zip
+$ delete test.zip;*
+$exit
--- /dev/null
+/*
+ miniunz.c
+ Version 1.1, February 14h, 2010
+ sample part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Modifications of Unzip for Zip64
+ Copyright (C) 2007-2008 Even Rouault
+
+ Modifications for Zip64 support on both zip and unzip
+ Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+*/
+
+#ifndef _WIN32
+ #ifndef __USE_FILE_OFFSET64
+ #define __USE_FILE_OFFSET64
+ #endif
+ #ifndef __USE_LARGEFILE64
+ #define __USE_LARGEFILE64
+ #endif
+ #ifndef _LARGEFILE64_SOURCE
+ #define _LARGEFILE64_SOURCE
+ #endif
+ #ifndef _FILE_OFFSET_BIT
+ #define _FILE_OFFSET_BIT 64
+ #endif
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#ifdef unix
+# include <unistd.h>
+# include <utime.h>
+#else
+# include <direct.h>
+# include <io.h>
+#endif
+
+#include "unzip.h"
+
+#define CASESENSITIVITY (0)
+#define WRITEBUFFERSIZE (8192)
+#define MAXFILENAME (256)
+
+#ifdef _WIN32
+#define USEWIN32IOAPI
+#include "iowin32.h"
+#endif
+/*
+ mini unzip, demo of unzip package
+
+ usage :
+ Usage : miniunz [-exvlo] file.zip [file_to_extract] [-d extractdir]
+
+ list the file in the zipfile, and print the content of FILE_ID.ZIP or README.TXT
+ if it exists
+*/
+
+
+/* change_file_date : change the date/time of a file
+ filename : the filename of the file where date/time must be modified
+ dosdate : the new date at the MSDos format (4 bytes)
+ tmu_date : the SAME new date at the tm_unz format */
+void change_file_date(filename,dosdate,tmu_date)
+ const char *filename;
+ uLong dosdate;
+ tm_unz tmu_date;
+{
+#ifdef _WIN32
+ HANDLE hFile;
+ FILETIME ftm,ftLocal,ftCreate,ftLastAcc,ftLastWrite;
+
+ hFile = CreateFileA(filename,GENERIC_READ | GENERIC_WRITE,
+ 0,NULL,OPEN_EXISTING,0,NULL);
+ GetFileTime(hFile,&ftCreate,&ftLastAcc,&ftLastWrite);
+ DosDateTimeToFileTime((WORD)(dosdate>>16),(WORD)dosdate,&ftLocal);
+ LocalFileTimeToFileTime(&ftLocal,&ftm);
+ SetFileTime(hFile,&ftm,&ftLastAcc,&ftm);
+ CloseHandle(hFile);
+#else
+#ifdef unix
+ struct utimbuf ut;
+ struct tm newdate;
+ newdate.tm_sec = tmu_date.tm_sec;
+ newdate.tm_min=tmu_date.tm_min;
+ newdate.tm_hour=tmu_date.tm_hour;
+ newdate.tm_mday=tmu_date.tm_mday;
+ newdate.tm_mon=tmu_date.tm_mon;
+ if (tmu_date.tm_year > 1900)
+ newdate.tm_year=tmu_date.tm_year - 1900;
+ else
+ newdate.tm_year=tmu_date.tm_year ;
+ newdate.tm_isdst=-1;
+
+ ut.actime=ut.modtime=mktime(&newdate);
+ utime(filename,&ut);
+#endif
+#endif
+}
+
+
+/* mymkdir and change_file_date are not 100 % portable
+ As I don't know well Unix, I wait feedback for the unix portion */
+
+int mymkdir(dirname)
+ const char* dirname;
+{
+ int ret=0;
+#ifdef _WIN32
+ ret = _mkdir(dirname);
+#else
+#ifdef unix
+ ret = mkdir (dirname,0775);
+#endif
+#endif
+ return ret;
+}
+
+int makedir (newdir)
+ char *newdir;
+{
+ char *buffer ;
+ char *p;
+ int len = (int)strlen(newdir);
+
+ if (len <= 0)
+ return 0;
+
+ buffer = (char*)malloc(len+1);
+ if (buffer==NULL)
+ {
+ printf("Error allocating memory\n");
+ return UNZ_INTERNALERROR;
+ }
+ strcpy(buffer,newdir);
+
+ if (buffer[len-1] == '/') {
+ buffer[len-1] = '\0';
+ }
+ if (mymkdir(buffer) == 0)
+ {
+ free(buffer);
+ return 1;
+ }
+
+ p = buffer+1;
+ while (1)
+ {
+ char hold;
+
+ while(*p && *p != '\\' && *p != '/')
+ p++;
+ hold = *p;
+ *p = 0;
+ if ((mymkdir(buffer) == -1) && (errno == ENOENT))
+ {
+ printf("couldn't create directory %s\n",buffer);
+ free(buffer);
+ return 0;
+ }
+ if (hold == 0)
+ break;
+ *p++ = hold;
+ }
+ free(buffer);
+ return 1;
+}
+
+void do_banner()
+{
+ printf("MiniUnz 1.01b, demo of zLib + Unz package written by Gilles Vollant\n");
+ printf("more info at http://www.winimage.com/zLibDll/unzip.html\n\n");
+}
+
+void do_help()
+{
+ printf("Usage : miniunz [-e] [-x] [-v] [-l] [-o] [-p password] file.zip [file_to_extr.] [-d extractdir]\n\n" \
+ " -e Extract without pathname (junk paths)\n" \
+ " -x Extract with pathname\n" \
+ " -v list files\n" \
+ " -l list files\n" \
+ " -d directory to extract into\n" \
+ " -o overwrite files without prompting\n" \
+ " -p extract crypted file using password\n\n");
+}
+
+void Display64BitsSize(ZPOS64_T n, int size_char)
+{
+ /* to avoid compatibility problem , we do here the conversion */
+ char number[21];
+ int offset=19;
+ int pos_string = 19;
+ number[20]=0;
+ for (;;) {
+ number[offset]=(char)((n%10)+'0');
+ if (number[offset] != '0')
+ pos_string=offset;
+ n/=10;
+ if (offset==0)
+ break;
+ offset--;
+ }
+ {
+ int size_display_string = 19-pos_string;
+ while (size_char > size_display_string)
+ {
+ size_char--;
+ printf(" ");
+ }
+ }
+
+ printf("%s",&number[pos_string]);
+}
+
+int do_list(uf)
+ unzFile uf;
+{
+ uLong i;
+ unz_global_info64 gi;
+ int err;
+
+ err = unzGetGlobalInfo64(uf,&gi);
+ if (err!=UNZ_OK)
+ printf("error %d with zipfile in unzGetGlobalInfo \n",err);
+ printf(" Length Method Size Ratio Date Time CRC-32 Name\n");
+ printf(" ------ ------ ---- ----- ---- ---- ------ ----\n");
+ for (i=0;i<gi.number_entry;i++)
+ {
+ char filename_inzip[256];
+ unz_file_info64 file_info;
+ uLong ratio=0;
+ const char *string_method;
+ char charCrypt=' ';
+ err = unzGetCurrentFileInfo64(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
+ if (err!=UNZ_OK)
+ {
+ printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
+ break;
+ }
+ if (file_info.uncompressed_size>0)
+ ratio = (uLong)((file_info.compressed_size*100)/file_info.uncompressed_size);
+
+ /* display a '*' if the file is crypted */
+ if ((file_info.flag & 1) != 0)
+ charCrypt='*';
+
+ if (file_info.compression_method==0)
+ string_method="Stored";
+ else
+ if (file_info.compression_method==Z_DEFLATED)
+ {
+ uInt iLevel=(uInt)((file_info.flag & 0x6)/2);
+ if (iLevel==0)
+ string_method="Defl:N";
+ else if (iLevel==1)
+ string_method="Defl:X";
+ else if ((iLevel==2) || (iLevel==3))
+ string_method="Defl:F"; /* 2:fast , 3 : extra fast*/
+ }
+ else
+ if (file_info.compression_method==Z_BZIP2ED)
+ {
+ string_method="BZip2 ";
+ }
+ else
+ string_method="Unkn. ";
+
+ Display64BitsSize(file_info.uncompressed_size,7);
+ printf(" %6s%c",string_method,charCrypt);
+ Display64BitsSize(file_info.compressed_size,7);
+ printf(" %3lu%% %2.2lu-%2.2lu-%2.2lu %2.2lu:%2.2lu %8.8lx %s\n",
+ ratio,
+ (uLong)file_info.tmu_date.tm_mon + 1,
+ (uLong)file_info.tmu_date.tm_mday,
+ (uLong)file_info.tmu_date.tm_year % 100,
+ (uLong)file_info.tmu_date.tm_hour,(uLong)file_info.tmu_date.tm_min,
+ (uLong)file_info.crc,filename_inzip);
+ if ((i+1)<gi.number_entry)
+ {
+ err = unzGoToNextFile(uf);
+ if (err!=UNZ_OK)
+ {
+ printf("error %d with zipfile in unzGoToNextFile\n",err);
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
+
+
+int do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite,password)
+ unzFile uf;
+ const int* popt_extract_without_path;
+ int* popt_overwrite;
+ const char* password;
+{
+ char filename_inzip[256];
+ char* filename_withoutpath;
+ char* p;
+ int err=UNZ_OK;
+ FILE *fout=NULL;
+ void* buf;
+ uInt size_buf;
+
+ unz_file_info64 file_info;
+ uLong ratio=0;
+ err = unzGetCurrentFileInfo64(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
+
+ if (err!=UNZ_OK)
+ {
+ printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
+ return err;
+ }
+
+ size_buf = WRITEBUFFERSIZE;
+ buf = (void*)malloc(size_buf);
+ if (buf==NULL)
+ {
+ printf("Error allocating memory\n");
+ return UNZ_INTERNALERROR;
+ }
+
+ p = filename_withoutpath = filename_inzip;
+ while ((*p) != '\0')
+ {
+ if (((*p)=='/') || ((*p)=='\\'))
+ filename_withoutpath = p+1;
+ p++;
+ }
+
+ if ((*filename_withoutpath)=='\0')
+ {
+ if ((*popt_extract_without_path)==0)
+ {
+ printf("creating directory: %s\n",filename_inzip);
+ mymkdir(filename_inzip);
+ }
+ }
+ else
+ {
+ const char* write_filename;
+ int skip=0;
+
+ if ((*popt_extract_without_path)==0)
+ write_filename = filename_inzip;
+ else
+ write_filename = filename_withoutpath;
+
+ err = unzOpenCurrentFilePassword(uf,password);
+ if (err!=UNZ_OK)
+ {
+ printf("error %d with zipfile in unzOpenCurrentFilePassword\n",err);
+ }
+
+ if (((*popt_overwrite)==0) && (err==UNZ_OK))
+ {
+ char rep=0;
+ FILE* ftestexist;
+ ftestexist = fopen64(write_filename,"rb");
+ if (ftestexist!=NULL)
+ {
+ fclose(ftestexist);
+ do
+ {
+ char answer[128];
+ int ret;
+
+ printf("The file %s exists. Overwrite ? [y]es, [n]o, [A]ll: ",write_filename);
+ ret = scanf("%1s",answer);
+ if (ret != 1)
+ {
+ exit(EXIT_FAILURE);
+ }
+ rep = answer[0] ;
+ if ((rep>='a') && (rep<='z'))
+ rep -= 0x20;
+ }
+ while ((rep!='Y') && (rep!='N') && (rep!='A'));
+ }
+
+ if (rep == 'N')
+ skip = 1;
+
+ if (rep == 'A')
+ *popt_overwrite=1;
+ }
+
+ if ((skip==0) && (err==UNZ_OK))
+ {
+ fout=fopen64(write_filename,"wb");
+
+ /* some zipfile don't contain directory alone before file */
+ if ((fout==NULL) && ((*popt_extract_without_path)==0) &&
+ (filename_withoutpath!=(char*)filename_inzip))
+ {
+ char c=*(filename_withoutpath-1);
+ *(filename_withoutpath-1)='\0';
+ makedir(write_filename);
+ *(filename_withoutpath-1)=c;
+ fout=fopen64(write_filename,"wb");
+ }
+
+ if (fout==NULL)
+ {
+ printf("error opening %s\n",write_filename);
+ }
+ }
+
+ if (fout!=NULL)
+ {
+ printf(" extracting: %s\n",write_filename);
+
+ do
+ {
+ err = unzReadCurrentFile(uf,buf,size_buf);
+ if (err<0)
+ {
+ printf("error %d with zipfile in unzReadCurrentFile\n",err);
+ break;
+ }
+ if (err>0)
+ if (fwrite(buf,err,1,fout)!=1)
+ {
+ printf("error in writing extracted file\n");
+ err=UNZ_ERRNO;
+ break;
+ }
+ }
+ while (err>0);
+ if (fout)
+ fclose(fout);
+
+ if (err==0)
+ change_file_date(write_filename,file_info.dosDate,
+ file_info.tmu_date);
+ }
+
+ if (err==UNZ_OK)
+ {
+ err = unzCloseCurrentFile (uf);
+ if (err!=UNZ_OK)
+ {
+ printf("error %d with zipfile in unzCloseCurrentFile\n",err);
+ }
+ }
+ else
+ unzCloseCurrentFile(uf); /* don't lose the error */
+ }
+
+ free(buf);
+ return err;
+}
+
+
+int do_extract(uf,opt_extract_without_path,opt_overwrite,password)
+ unzFile uf;
+ int opt_extract_without_path;
+ int opt_overwrite;
+ const char* password;
+{
+ uLong i;
+ unz_global_info64 gi;
+ int err;
+ FILE* fout=NULL;
+
+ err = unzGetGlobalInfo64(uf,&gi);
+ if (err!=UNZ_OK)
+ printf("error %d with zipfile in unzGetGlobalInfo \n",err);
+
+ for (i=0;i<gi.number_entry;i++)
+ {
+ if (do_extract_currentfile(uf,&opt_extract_without_path,
+ &opt_overwrite,
+ password) != UNZ_OK)
+ break;
+
+ if ((i+1)<gi.number_entry)
+ {
+ err = unzGoToNextFile(uf);
+ if (err!=UNZ_OK)
+ {
+ printf("error %d with zipfile in unzGoToNextFile\n",err);
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
+
+int do_extract_onefile(uf,filename,opt_extract_without_path,opt_overwrite,password)
+ unzFile uf;
+ const char* filename;
+ int opt_extract_without_path;
+ int opt_overwrite;
+ const char* password;
+{
+ int err = UNZ_OK;
+ if (unzLocateFile(uf,filename,CASESENSITIVITY)!=UNZ_OK)
+ {
+ printf("file %s not found in the zipfile\n",filename);
+ return 2;
+ }
+
+ if (do_extract_currentfile(uf,&opt_extract_without_path,
+ &opt_overwrite,
+ password) == UNZ_OK)
+ return 0;
+ else
+ return 1;
+}
+
+
+int main(argc,argv)
+ int argc;
+ char *argv[];
+{
+ const char *zipfilename=NULL;
+ const char *filename_to_extract=NULL;
+ const char *password=NULL;
+ char filename_try[MAXFILENAME+16] = "";
+ int i;
+ int ret_value=0;
+ int opt_do_list=0;
+ int opt_do_extract=1;
+ int opt_do_extract_withoutpath=0;
+ int opt_overwrite=0;
+ int opt_extractdir=0;
+ const char *dirname=NULL;
+ unzFile uf=NULL;
+
+ do_banner();
+ if (argc==1)
+ {
+ do_help();
+ return 0;
+ }
+ else
+ {
+ for (i=1;i<argc;i++)
+ {
+ if ((*argv[i])=='-')
+ {
+ const char *p=argv[i]+1;
+
+ while ((*p)!='\0')
+ {
+ char c=*(p++);;
+ if ((c=='l') || (c=='L'))
+ opt_do_list = 1;
+ if ((c=='v') || (c=='V'))
+ opt_do_list = 1;
+ if ((c=='x') || (c=='X'))
+ opt_do_extract = 1;
+ if ((c=='e') || (c=='E'))
+ opt_do_extract = opt_do_extract_withoutpath = 1;
+ if ((c=='o') || (c=='O'))
+ opt_overwrite=1;
+ if ((c=='d') || (c=='D'))
+ {
+ opt_extractdir=1;
+ dirname=argv[i+1];
+ }
+
+ if (((c=='p') || (c=='P')) && (i+1<argc))
+ {
+ password=argv[i+1];
+ i++;
+ }
+ }
+ }
+ else
+ {
+ if (zipfilename == NULL)
+ zipfilename = argv[i];
+ else if ((filename_to_extract==NULL) && (!opt_extractdir))
+ filename_to_extract = argv[i] ;
+ }
+ }
+ }
+
+ if (zipfilename!=NULL)
+ {
+
+# ifdef USEWIN32IOAPI
+ zlib_filefunc64_def ffunc;
+# endif
+
+ strncpy(filename_try, zipfilename,MAXFILENAME-1);
+ /* strncpy doesnt append the trailing NULL, of the string is too long. */
+ filename_try[ MAXFILENAME ] = '\0';
+
+# ifdef USEWIN32IOAPI
+ fill_win32_filefunc64A(&ffunc);
+ uf = unzOpen2_64(zipfilename,&ffunc);
+# else
+ uf = unzOpen64(zipfilename);
+# endif
+ if (uf==NULL)
+ {
+ strcat(filename_try,".zip");
+# ifdef USEWIN32IOAPI
+ uf = unzOpen2_64(filename_try,&ffunc);
+# else
+ uf = unzOpen64(filename_try);
+# endif
+ }
+ }
+
+ if (uf==NULL)
+ {
+ printf("Cannot open %s or %s.zip\n",zipfilename,zipfilename);
+ return 1;
+ }
+ printf("%s opened\n",filename_try);
+
+ if (opt_do_list==1)
+ ret_value = do_list(uf);
+ else if (opt_do_extract==1)
+ {
+#ifdef _WIN32
+ if (opt_extractdir && _chdir(dirname))
+#else
+ if (opt_extractdir && chdir(dirname))
+#endif
+ {
+ printf("Error changing into %s, aborting\n", dirname);
+ exit(-1);
+ }
+
+ if (filename_to_extract == NULL)
+ ret_value = do_extract(uf, opt_do_extract_withoutpath, opt_overwrite, password);
+ else
+ ret_value = do_extract_onefile(uf, filename_to_extract, opt_do_extract_withoutpath, opt_overwrite, password);
+ }
+
+ unzClose(uf);
+
+ return ret_value;
+}
--- /dev/null
+/*
+ minizip.c
+ Version 1.1, February 14h, 2010
+ sample part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Modifications of Unzip for Zip64
+ Copyright (C) 2007-2008 Even Rouault
+
+ Modifications for Zip64 support on both zip and unzip
+ Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+*/
+
+
+#ifndef _WIN32
+ #ifndef __USE_FILE_OFFSET64
+ #define __USE_FILE_OFFSET64
+ #endif
+ #ifndef __USE_LARGEFILE64
+ #define __USE_LARGEFILE64
+ #endif
+ #ifndef _LARGEFILE64_SOURCE
+ #define _LARGEFILE64_SOURCE
+ #endif
+ #ifndef _FILE_OFFSET_BIT
+ #define _FILE_OFFSET_BIT 64
+ #endif
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#ifdef unix
+# include <unistd.h>
+# include <utime.h>
+# include <sys/types.h>
+# include <sys/stat.h>
+#else
+# include <direct.h>
+# include <io.h>
+#endif
+
+#include "zip.h"
+
+#ifdef _WIN32
+ #define USEWIN32IOAPI
+ #include "iowin32.h"
+#endif
+
+
+
+#define WRITEBUFFERSIZE (16384)
+#define MAXFILENAME (256)
+
+#ifdef _WIN32
+uLong filetime(f, tmzip, dt)
+ char *f; /* name of file to get info on */
+ tm_zip *tmzip; /* return value: access, modific. and creation times */
+ uLong *dt; /* dostime */
+{
+ int ret = 0;
+ {
+ FILETIME ftLocal;
+ HANDLE hFind;
+ WIN32_FIND_DATAA ff32;
+
+ hFind = FindFirstFileA(f,&ff32);
+ if (hFind != INVALID_HANDLE_VALUE)
+ {
+ FileTimeToLocalFileTime(&(ff32.ftLastWriteTime),&ftLocal);
+ FileTimeToDosDateTime(&ftLocal,((LPWORD)dt)+1,((LPWORD)dt)+0);
+ FindClose(hFind);
+ ret = 1;
+ }
+ }
+ return ret;
+}
+#else
+#ifdef unix
+uLong filetime(f, tmzip, dt)
+ char *f; /* name of file to get info on */
+ tm_zip *tmzip; /* return value: access, modific. and creation times */
+ uLong *dt; /* dostime */
+{
+ int ret=0;
+ struct stat s; /* results of stat() */
+ struct tm* filedate;
+ time_t tm_t=0;
+
+ if (strcmp(f,"-")!=0)
+ {
+ char name[MAXFILENAME+1];
+ int len = strlen(f);
+ if (len > MAXFILENAME)
+ len = MAXFILENAME;
+
+ strncpy(name, f,MAXFILENAME-1);
+ /* strncpy doesnt append the trailing NULL, of the string is too long. */
+ name[ MAXFILENAME ] = '\0';
+
+ if (name[len - 1] == '/')
+ name[len - 1] = '\0';
+ /* not all systems allow stat'ing a file with / appended */
+ if (stat(name,&s)==0)
+ {
+ tm_t = s.st_mtime;
+ ret = 1;
+ }
+ }
+ filedate = localtime(&tm_t);
+
+ tmzip->tm_sec = filedate->tm_sec;
+ tmzip->tm_min = filedate->tm_min;
+ tmzip->tm_hour = filedate->tm_hour;
+ tmzip->tm_mday = filedate->tm_mday;
+ tmzip->tm_mon = filedate->tm_mon ;
+ tmzip->tm_year = filedate->tm_year;
+
+ return ret;
+}
+#else
+uLong filetime(f, tmzip, dt)
+ char *f; /* name of file to get info on */
+ tm_zip *tmzip; /* return value: access, modific. and creation times */
+ uLong *dt; /* dostime */
+{
+ return 0;
+}
+#endif
+#endif
+
+
+
+
+int check_exist_file(filename)
+ const char* filename;
+{
+ FILE* ftestexist;
+ int ret = 1;
+ ftestexist = fopen64(filename,"rb");
+ if (ftestexist==NULL)
+ ret = 0;
+ else
+ fclose(ftestexist);
+ return ret;
+}
+
+void do_banner()
+{
+ printf("MiniZip 1.1, demo of zLib + MiniZip64 package, written by Gilles Vollant\n");
+ printf("more info on MiniZip at http://www.winimage.com/zLibDll/minizip.html\n\n");
+}
+
+void do_help()
+{
+ printf("Usage : minizip [-o] [-a] [-0 to -9] [-p password] [-j] file.zip [files_to_add]\n\n" \
+ " -o Overwrite existing file.zip\n" \
+ " -a Append to existing file.zip\n" \
+ " -0 Store only\n" \
+ " -1 Compress faster\n" \
+ " -9 Compress better\n\n" \
+ " -j exclude path. store only the file name.\n\n");
+}
+
+/* calculate the CRC32 of a file,
+ because to encrypt a file, we need known the CRC32 of the file before */
+int getFileCrc(const char* filenameinzip,void*buf,unsigned long size_buf,unsigned long* result_crc)
+{
+ unsigned long calculate_crc=0;
+ int err=ZIP_OK;
+ FILE * fin = fopen64(filenameinzip,"rb");
+ unsigned long size_read = 0;
+ unsigned long total_read = 0;
+ if (fin==NULL)
+ {
+ err = ZIP_ERRNO;
+ }
+
+ if (err == ZIP_OK)
+ do
+ {
+ err = ZIP_OK;
+ size_read = (int)fread(buf,1,size_buf,fin);
+ if (size_read < size_buf)
+ if (feof(fin)==0)
+ {
+ printf("error in reading %s\n",filenameinzip);
+ err = ZIP_ERRNO;
+ }
+
+ if (size_read>0)
+ calculate_crc = crc32(calculate_crc,buf,size_read);
+ total_read += size_read;
+
+ } while ((err == ZIP_OK) && (size_read>0));
+
+ if (fin)
+ fclose(fin);
+
+ *result_crc=calculate_crc;
+ printf("file %s crc %lx\n", filenameinzip, calculate_crc);
+ return err;
+}
+
+int isLargeFile(const char* filename)
+{
+ int largeFile = 0;
+ ZPOS64_T pos = 0;
+ FILE* pFile = fopen64(filename, "rb");
+
+ if(pFile != NULL)
+ {
+ int n = fseeko64(pFile, 0, SEEK_END);
+
+ pos = ftello64(pFile);
+
+ printf("File : %s is %lld bytes\n", filename, pos);
+
+ if(pos >= 0xffffffff)
+ largeFile = 1;
+
+ fclose(pFile);
+ }
+
+ return largeFile;
+}
+
+int main(argc,argv)
+ int argc;
+ char *argv[];
+{
+ int i;
+ int opt_overwrite=0;
+ int opt_compress_level=Z_DEFAULT_COMPRESSION;
+ int opt_exclude_path=0;
+ int zipfilenamearg = 0;
+ char filename_try[MAXFILENAME+16];
+ int zipok;
+ int err=0;
+ int size_buf=0;
+ void* buf=NULL;
+ const char* password=NULL;
+
+
+ do_banner();
+ if (argc==1)
+ {
+ do_help();
+ return 0;
+ }
+ else
+ {
+ for (i=1;i<argc;i++)
+ {
+ if ((*argv[i])=='-')
+ {
+ const char *p=argv[i]+1;
+
+ while ((*p)!='\0')
+ {
+ char c=*(p++);;
+ if ((c=='o') || (c=='O'))
+ opt_overwrite = 1;
+ if ((c=='a') || (c=='A'))
+ opt_overwrite = 2;
+ if ((c>='0') && (c<='9'))
+ opt_compress_level = c-'0';
+ if ((c=='j') || (c=='J'))
+ opt_exclude_path = 1;
+
+ if (((c=='p') || (c=='P')) && (i+1<argc))
+ {
+ password=argv[i+1];
+ i++;
+ }
+ }
+ }
+ else
+ {
+ if (zipfilenamearg == 0)
+ {
+ zipfilenamearg = i ;
+ }
+ }
+ }
+ }
+
+ size_buf = WRITEBUFFERSIZE;
+ buf = (void*)malloc(size_buf);
+ if (buf==NULL)
+ {
+ printf("Error allocating memory\n");
+ return ZIP_INTERNALERROR;
+ }
+
+ if (zipfilenamearg==0)
+ {
+ zipok=0;
+ }
+ else
+ {
+ int i,len;
+ int dot_found=0;
+
+ zipok = 1 ;
+ strncpy(filename_try, argv[zipfilenamearg],MAXFILENAME-1);
+ /* strncpy doesnt append the trailing NULL, of the string is too long. */
+ filename_try[ MAXFILENAME ] = '\0';
+
+ len=(int)strlen(filename_try);
+ for (i=0;i<len;i++)
+ if (filename_try[i]=='.')
+ dot_found=1;
+
+ if (dot_found==0)
+ strcat(filename_try,".zip");
+
+ if (opt_overwrite==2)
+ {
+ /* if the file don't exist, we not append file */
+ if (check_exist_file(filename_try)==0)
+ opt_overwrite=1;
+ }
+ else
+ if (opt_overwrite==0)
+ if (check_exist_file(filename_try)!=0)
+ {
+ char rep=0;
+ do
+ {
+ char answer[128];
+ int ret;
+ printf("The file %s exists. Overwrite ? [y]es, [n]o, [a]ppend : ",filename_try);
+ ret = scanf("%1s",answer);
+ if (ret != 1)
+ {
+ exit(EXIT_FAILURE);
+ }
+ rep = answer[0] ;
+ if ((rep>='a') && (rep<='z'))
+ rep -= 0x20;
+ }
+ while ((rep!='Y') && (rep!='N') && (rep!='A'));
+ if (rep=='N')
+ zipok = 0;
+ if (rep=='A')
+ opt_overwrite = 2;
+ }
+ }
+
+ if (zipok==1)
+ {
+ zipFile zf;
+ int errclose;
+# ifdef USEWIN32IOAPI
+ zlib_filefunc64_def ffunc;
+ fill_win32_filefunc64A(&ffunc);
+ zf = zipOpen2_64(filename_try,(opt_overwrite==2) ? 2 : 0,NULL,&ffunc);
+# else
+ zf = zipOpen64(filename_try,(opt_overwrite==2) ? 2 : 0);
+# endif
+
+ if (zf == NULL)
+ {
+ printf("error opening %s\n",filename_try);
+ err= ZIP_ERRNO;
+ }
+ else
+ printf("creating %s\n",filename_try);
+
+ for (i=zipfilenamearg+1;(i<argc) && (err==ZIP_OK);i++)
+ {
+ if (!((((*(argv[i]))=='-') || ((*(argv[i]))=='/')) &&
+ ((argv[i][1]=='o') || (argv[i][1]=='O') ||
+ (argv[i][1]=='a') || (argv[i][1]=='A') ||
+ (argv[i][1]=='p') || (argv[i][1]=='P') ||
+ ((argv[i][1]>='0') || (argv[i][1]<='9'))) &&
+ (strlen(argv[i]) == 2)))
+ {
+ FILE * fin;
+ int size_read;
+ const char* filenameinzip = argv[i];
+ const char *savefilenameinzip;
+ zip_fileinfo zi;
+ unsigned long crcFile=0;
+ int zip64 = 0;
+
+ zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour =
+ zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0;
+ zi.dosDate = 0;
+ zi.internal_fa = 0;
+ zi.external_fa = 0;
+ filetime(filenameinzip,&zi.tmz_date,&zi.dosDate);
+
+/*
+ err = zipOpenNewFileInZip(zf,filenameinzip,&zi,
+ NULL,0,NULL,0,NULL / * comment * /,
+ (opt_compress_level != 0) ? Z_DEFLATED : 0,
+ opt_compress_level);
+*/
+ if ((password != NULL) && (err==ZIP_OK))
+ err = getFileCrc(filenameinzip,buf,size_buf,&crcFile);
+
+ zip64 = isLargeFile(filenameinzip);
+
+ /* The path name saved, should not include a leading slash. */
+ /*if it did, windows/xp and dynazip couldn't read the zip file. */
+ savefilenameinzip = filenameinzip;
+ while( savefilenameinzip[0] == '\\' || savefilenameinzip[0] == '/' )
+ {
+ savefilenameinzip++;
+ }
+
+ /*should the zip file contain any path at all?*/
+ if( opt_exclude_path )
+ {
+ const char *tmpptr;
+ const char *lastslash = 0;
+ for( tmpptr = savefilenameinzip; *tmpptr; tmpptr++)
+ {
+ if( *tmpptr == '\\' || *tmpptr == '/')
+ {
+ lastslash = tmpptr;
+ }
+ }
+ if( lastslash != NULL )
+ {
+ savefilenameinzip = lastslash+1; // base filename follows last slash.
+ }
+ }
+
+ /**/
+ err = zipOpenNewFileInZip3_64(zf,savefilenameinzip,&zi,
+ NULL,0,NULL,0,NULL /* comment*/,
+ (opt_compress_level != 0) ? Z_DEFLATED : 0,
+ opt_compress_level,0,
+ /* -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, */
+ -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
+ password,crcFile, zip64);
+
+ if (err != ZIP_OK)
+ printf("error in opening %s in zipfile\n",filenameinzip);
+ else
+ {
+ fin = fopen64(filenameinzip,"rb");
+ if (fin==NULL)
+ {
+ err=ZIP_ERRNO;
+ printf("error in opening %s for reading\n",filenameinzip);
+ }
+ }
+
+ if (err == ZIP_OK)
+ do
+ {
+ err = ZIP_OK;
+ size_read = (int)fread(buf,1,size_buf,fin);
+ if (size_read < size_buf)
+ if (feof(fin)==0)
+ {
+ printf("error in reading %s\n",filenameinzip);
+ err = ZIP_ERRNO;
+ }
+
+ if (size_read>0)
+ {
+ err = zipWriteInFileInZip (zf,buf,size_read);
+ if (err<0)
+ {
+ printf("error in writing %s in the zipfile\n",
+ filenameinzip);
+ }
+
+ }
+ } while ((err == ZIP_OK) && (size_read>0));
+
+ if (fin)
+ fclose(fin);
+
+ if (err<0)
+ err=ZIP_ERRNO;
+ else
+ {
+ err = zipCloseFileInZip(zf);
+ if (err!=ZIP_OK)
+ printf("error in closing %s in the zipfile\n",
+ filenameinzip);
+ }
+ }
+ }
+ errclose = zipClose(zf,NULL);
+ if (errclose != ZIP_OK)
+ printf("error in closing %s\n",filename_try);
+ }
+ else
+ {
+ do_help();
+ }
+
+ free(buf);
+ return 0;
+}
--- /dev/null
+/*
+ Additional tools for Minizip
+ Code: Xavier Roche '2004
+ License: Same as ZLIB (www.gzip.org)
+*/
+
+/* Code */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "zlib.h"
+#include "unzip.h"
+
+#define READ_8(adr) ((unsigned char)*(adr))
+#define READ_16(adr) ( READ_8(adr) | (READ_8(adr+1) << 8) )
+#define READ_32(adr) ( READ_16(adr) | (READ_16((adr)+2) << 16) )
+
+#define WRITE_8(buff, n) do { \
+ *((unsigned char*)(buff)) = (unsigned char) ((n) & 0xff); \
+} while(0)
+#define WRITE_16(buff, n) do { \
+ WRITE_8((unsigned char*)(buff), n); \
+ WRITE_8(((unsigned char*)(buff)) + 1, (n) >> 8); \
+} while(0)
+#define WRITE_32(buff, n) do { \
+ WRITE_16((unsigned char*)(buff), (n) & 0xffff); \
+ WRITE_16((unsigned char*)(buff) + 2, (n) >> 16); \
+} while(0)
+
+extern int ZEXPORT unzRepair(file, fileOut, fileOutTmp, nRecovered, bytesRecovered)
+const char* file;
+const char* fileOut;
+const char* fileOutTmp;
+uLong* nRecovered;
+uLong* bytesRecovered;
+{
+ int err = Z_OK;
+ FILE* fpZip = fopen(file, "rb");
+ FILE* fpOut = fopen(fileOut, "wb");
+ FILE* fpOutCD = fopen(fileOutTmp, "wb");
+ if (fpZip != NULL && fpOut != NULL) {
+ int entries = 0;
+ uLong totalBytes = 0;
+ char header[30];
+ char filename[256];
+ char extra[1024];
+ int offset = 0;
+ int offsetCD = 0;
+ while ( fread(header, 1, 30, fpZip) == 30 ) {
+ int currentOffset = offset;
+
+ /* File entry */
+ if (READ_32(header) == 0x04034b50) {
+ unsigned int version = READ_16(header + 4);
+ unsigned int gpflag = READ_16(header + 6);
+ unsigned int method = READ_16(header + 8);
+ unsigned int filetime = READ_16(header + 10);
+ unsigned int filedate = READ_16(header + 12);
+ unsigned int crc = READ_32(header + 14); /* crc */
+ unsigned int cpsize = READ_32(header + 18); /* compressed size */
+ unsigned int uncpsize = READ_32(header + 22); /* uncompressed sz */
+ unsigned int fnsize = READ_16(header + 26); /* file name length */
+ unsigned int extsize = READ_16(header + 28); /* extra field length */
+ filename[0] = extra[0] = '\0';
+
+ /* Header */
+ if (fwrite(header, 1, 30, fpOut) == 30) {
+ offset += 30;
+ } else {
+ err = Z_ERRNO;
+ break;
+ }
+
+ /* Filename */
+ if (fnsize > 0) {
+ if (fread(filename, 1, fnsize, fpZip) == fnsize) {
+ if (fwrite(filename, 1, fnsize, fpOut) == fnsize) {
+ offset += fnsize;
+ } else {
+ err = Z_ERRNO;
+ break;
+ }
+ } else {
+ err = Z_ERRNO;
+ break;
+ }
+ } else {
+ err = Z_STREAM_ERROR;
+ break;
+ }
+
+ /* Extra field */
+ if (extsize > 0) {
+ if (fread(extra, 1, extsize, fpZip) == extsize) {
+ if (fwrite(extra, 1, extsize, fpOut) == extsize) {
+ offset += extsize;
+ } else {
+ err = Z_ERRNO;
+ break;
+ }
+ } else {
+ err = Z_ERRNO;
+ break;
+ }
+ }
+
+ /* Data */
+ {
+ int dataSize = cpsize;
+ if (dataSize == 0) {
+ dataSize = uncpsize;
+ }
+ if (dataSize > 0) {
+ char* data = malloc(dataSize);
+ if (data != NULL) {
+ if ((int)fread(data, 1, dataSize, fpZip) == dataSize) {
+ if ((int)fwrite(data, 1, dataSize, fpOut) == dataSize) {
+ offset += dataSize;
+ totalBytes += dataSize;
+ } else {
+ err = Z_ERRNO;
+ }
+ } else {
+ err = Z_ERRNO;
+ }
+ free(data);
+ if (err != Z_OK) {
+ break;
+ }
+ } else {
+ err = Z_MEM_ERROR;
+ break;
+ }
+ }
+ }
+
+ /* Central directory entry */
+ {
+ char header[46];
+ char* comment = "";
+ int comsize = (int) strlen(comment);
+ WRITE_32(header, 0x02014b50);
+ WRITE_16(header + 4, version);
+ WRITE_16(header + 6, version);
+ WRITE_16(header + 8, gpflag);
+ WRITE_16(header + 10, method);
+ WRITE_16(header + 12, filetime);
+ WRITE_16(header + 14, filedate);
+ WRITE_32(header + 16, crc);
+ WRITE_32(header + 20, cpsize);
+ WRITE_32(header + 24, uncpsize);
+ WRITE_16(header + 28, fnsize);
+ WRITE_16(header + 30, extsize);
+ WRITE_16(header + 32, comsize);
+ WRITE_16(header + 34, 0); /* disk # */
+ WRITE_16(header + 36, 0); /* int attrb */
+ WRITE_32(header + 38, 0); /* ext attrb */
+ WRITE_32(header + 42, currentOffset);
+ /* Header */
+ if (fwrite(header, 1, 46, fpOutCD) == 46) {
+ offsetCD += 46;
+
+ /* Filename */
+ if (fnsize > 0) {
+ if (fwrite(filename, 1, fnsize, fpOutCD) == fnsize) {
+ offsetCD += fnsize;
+ } else {
+ err = Z_ERRNO;
+ break;
+ }
+ } else {
+ err = Z_STREAM_ERROR;
+ break;
+ }
+
+ /* Extra field */
+ if (extsize > 0) {
+ if (fwrite(extra, 1, extsize, fpOutCD) == extsize) {
+ offsetCD += extsize;
+ } else {
+ err = Z_ERRNO;
+ break;
+ }
+ }
+
+ /* Comment field */
+ if (comsize > 0) {
+ if ((int)fwrite(comment, 1, comsize, fpOutCD) == comsize) {
+ offsetCD += comsize;
+ } else {
+ err = Z_ERRNO;
+ break;
+ }
+ }
+
+
+ } else {
+ err = Z_ERRNO;
+ break;
+ }
+ }
+
+ /* Success */
+ entries++;
+
+ } else {
+ break;
+ }
+ }
+
+ /* Final central directory */
+ {
+ int entriesZip = entries;
+ char header[22];
+ char* comment = ""; // "ZIP File recovered by zlib/minizip/mztools";
+ int comsize = (int) strlen(comment);
+ if (entriesZip > 0xffff) {
+ entriesZip = 0xffff;
+ }
+ WRITE_32(header, 0x06054b50);
+ WRITE_16(header + 4, 0); /* disk # */
+ WRITE_16(header + 6, 0); /* disk # */
+ WRITE_16(header + 8, entriesZip); /* hack */
+ WRITE_16(header + 10, entriesZip); /* hack */
+ WRITE_32(header + 12, offsetCD); /* size of CD */
+ WRITE_32(header + 16, offset); /* offset to CD */
+ WRITE_16(header + 20, comsize); /* comment */
+
+ /* Header */
+ if (fwrite(header, 1, 22, fpOutCD) == 22) {
+
+ /* Comment field */
+ if (comsize > 0) {
+ if ((int)fwrite(comment, 1, comsize, fpOutCD) != comsize) {
+ err = Z_ERRNO;
+ }
+ }
+
+ } else {
+ err = Z_ERRNO;
+ }
+ }
+
+ /* Final merge (file + central directory) */
+ fclose(fpOutCD);
+ if (err == Z_OK) {
+ fpOutCD = fopen(fileOutTmp, "rb");
+ if (fpOutCD != NULL) {
+ int nRead;
+ char buffer[8192];
+ while ( (nRead = (int)fread(buffer, 1, sizeof(buffer), fpOutCD)) > 0) {
+ if ((int)fwrite(buffer, 1, nRead, fpOut) != nRead) {
+ err = Z_ERRNO;
+ break;
+ }
+ }
+ fclose(fpOutCD);
+ }
+ }
+
+ /* Close */
+ fclose(fpZip);
+ fclose(fpOut);
+
+ /* Wipe temporary file */
+ (void)remove(fileOutTmp);
+
+ /* Number of recovered entries */
+ if (err == Z_OK) {
+ if (nRecovered != NULL) {
+ *nRecovered = entries;
+ }
+ if (bytesRecovered != NULL) {
+ *bytesRecovered = totalBytes;
+ }
+ }
+ } else {
+ err = Z_STREAM_ERROR;
+ }
+ return err;
+}
--- /dev/null
+/*
+ Additional tools for Minizip
+ Code: Xavier Roche '2004
+ License: Same as ZLIB (www.gzip.org)
+*/
+
+#ifndef _zip_tools_H
+#define _zip_tools_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _ZLIB_H
+#include "zlib.h"
+#endif
+
+#include "unzip.h"
+
+/* Repair a ZIP file (missing central directory)
+ file: file to recover
+ fileOut: output file after recovery
+ fileOutTmp: temporary file name used for recovery
+*/
+extern int ZEXPORT unzRepair(const char* file,
+ const char* fileOut,
+ const char* fileOutTmp,
+ uLong* nRecovered,
+ uLong* bytesRecovered);
+
+#endif
--- /dev/null
+/* unzip.c -- IO for uncompress .zip files using zlib
+ Version 1.1, February 14h, 2010
+ part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Modifications of Unzip for Zip64
+ Copyright (C) 2007-2008 Even Rouault
+
+ Modifications for Zip64 support on both zip and unzip
+ Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+ For more info read MiniZip_info.txt
+
+
+ ------------------------------------------------------------------------------------
+ Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of
+ compatibility with older software. The following is from the original crypt.c.
+ Code woven in by Terry Thorsen 1/2003.
+
+ Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2000-Apr-09 or later
+ (the contents of which are also included in zip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+
+ crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h]
+
+ The encryption/decryption parts of this source code (as opposed to the
+ non-echoing password parts) were originally written in Europe. The
+ whole source package can be freely distributed, including from the USA.
+ (Prior to January 2000, re-export from the US was a violation of US law.)
+
+ This encryption code is a direct transcription of the algorithm from
+ Roger Schlafly, described by Phil Katz in the file appnote.txt. This
+ file (appnote.txt) is distributed with the PKZIP program (even in the
+ version without encryption capabilities).
+
+ ------------------------------------------------------------------------------------
+
+ Changes in unzip.c
+
+ 2007-2008 - Even Rouault - Addition of cpl_unzGetCurrentFileZStreamPos
+ 2007-2008 - Even Rouault - Decoration of symbol names unz* -> cpl_unz*
+ 2007-2008 - Even Rouault - Remove old C style function prototypes
+ 2007-2008 - Even Rouault - Add unzip support for ZIP64
+
+ Copyright (C) 2007-2008 Even Rouault
+
+
+ Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again).
+ Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G
+ should only read the compressed/uncompressed size from the Zip64 format if
+ the size from normal header was 0xFFFFFFFF
+ Oct-2009 - Mathias Svensson - Applied some bug fixes from paches recived from Gilles Vollant
+ Oct-2009 - Mathias Svensson - Applied support to unzip files with compression mathod BZIP2 (bzip2 lib is required)
+ Patch created by Daniel Borca
+
+ Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
+
+ Copyright (C) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson
+
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef NOUNCRYPT
+ #define NOUNCRYPT
+#endif
+
+#include "zlib.h"
+#include "unzip.h"
+
+#ifdef STDC
+# include <stddef.h>
+# include <string.h>
+# include <stdlib.h>
+#endif
+#ifdef NO_ERRNO_H
+ extern int errno;
+#else
+# include <errno.h>
+#endif
+
+
+#ifndef local
+# define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+
+#ifndef CASESENSITIVITYDEFAULT_NO
+# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
+# define CASESENSITIVITYDEFAULT_NO
+# endif
+#endif
+
+
+#ifndef UNZ_BUFSIZE
+#define UNZ_BUFSIZE (16384)
+#endif
+
+#ifndef UNZ_MAXFILENAMEINZIP
+#define UNZ_MAXFILENAMEINZIP (256)
+#endif
+
+#ifndef ALLOC
+# define ALLOC(size) (malloc(size))
+#endif
+#ifndef TRYFREE
+# define TRYFREE(p) {if (p) free(p);}
+#endif
+
+#define SIZECENTRALDIRITEM (0x2e)
+#define SIZEZIPLOCALHEADER (0x1e)
+
+
+const char unz_copyright[] =
+ " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
+
+/* unz_file_info_interntal contain internal info about a file in zipfile*/
+typedef struct unz_file_info64_internal_s
+{
+ ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */
+} unz_file_info64_internal;
+
+
+/* file_in_zip_read_info_s contain internal information about a file in zipfile,
+ when reading and decompress it */
+typedef struct
+{
+ char *read_buffer; /* internal buffer for compressed data */
+ z_stream stream; /* zLib stream structure for inflate */
+
+#ifdef HAVE_BZIP2
+ bz_stream bstream; /* bzLib stream structure for bziped */
+#endif
+
+ ZPOS64_T pos_in_zipfile; /* position in byte on the zipfile, for fseek*/
+ uLong stream_initialised; /* flag set if stream structure is initialised*/
+
+ ZPOS64_T offset_local_extrafield;/* offset of the local extra field */
+ uInt size_local_extrafield;/* size of the local extra field */
+ ZPOS64_T pos_local_extrafield; /* position in the local extra field in read*/
+ ZPOS64_T total_out_64;
+
+ uLong crc32; /* crc32 of all data uncompressed */
+ uLong crc32_wait; /* crc32 we must obtain after decompress all */
+ ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */
+ ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/
+ zlib_filefunc64_32_def z_filefunc;
+ voidpf filestream; /* io structore of the zipfile */
+ uLong compression_method; /* compression method (0==store) */
+ ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
+ int raw;
+} file_in_zip64_read_info_s;
+
+
+/* unz64_s contain internal information about the zipfile
+*/
+typedef struct
+{
+ zlib_filefunc64_32_def z_filefunc;
+ int is64bitOpenFunction;
+ voidpf filestream; /* io structore of the zipfile */
+ unz_global_info64 gi; /* public global information */
+ ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
+ ZPOS64_T num_file; /* number of the current file in the zipfile*/
+ ZPOS64_T pos_in_central_dir; /* pos of the current file in the central dir*/
+ ZPOS64_T current_file_ok; /* flag about the usability of the current file*/
+ ZPOS64_T central_pos; /* position of the beginning of the central dir*/
+
+ ZPOS64_T size_central_dir; /* size of the central directory */
+ ZPOS64_T offset_central_dir; /* offset of start of central directory with
+ respect to the starting disk number */
+
+ unz_file_info64 cur_file_info; /* public info about the current file in zip*/
+ unz_file_info64_internal cur_file_info_internal; /* private info about it*/
+ file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current
+ file if we are decompressing it */
+ int encrypted;
+
+ int isZip64;
+
+# ifndef NOUNCRYPT
+ unsigned long keys[3]; /* keys defining the pseudo-random sequence */
+ const unsigned long* pcrc_32_tab;
+# endif
+} unz64_s;
+
+
+#ifndef NOUNCRYPT
+#include "crypt.h"
+#endif
+
+/* ===========================================================================
+ Read a byte from a gz_stream; update next_in and avail_in. Return EOF
+ for end of file.
+ IN assertion: the stream s has been sucessfully opened for reading.
+*/
+
+
+local int unz64local_getByte OF((
+ const zlib_filefunc64_32_def* pzlib_filefunc_def,
+ voidpf filestream,
+ int *pi));
+
+local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)
+{
+ unsigned char c;
+ int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
+ if (err==1)
+ {
+ *pi = (int)c;
+ return UNZ_OK;
+ }
+ else
+ {
+ if (ZERROR64(*pzlib_filefunc_def,filestream))
+ return UNZ_ERRNO;
+ else
+ return UNZ_EOF;
+ }
+}
+
+
+/* ===========================================================================
+ Reads a long in LSB order from the given gz_stream. Sets
+*/
+local int unz64local_getShort OF((
+ const zlib_filefunc64_32_def* pzlib_filefunc_def,
+ voidpf filestream,
+ uLong *pX));
+
+local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def,
+ voidpf filestream,
+ uLong *pX)
+{
+ uLong x ;
+ int i = 0;
+ int err;
+
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x = (uLong)i;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x |= ((uLong)i)<<8;
+
+ if (err==UNZ_OK)
+ *pX = x;
+ else
+ *pX = 0;
+ return err;
+}
+
+local int unz64local_getLong OF((
+ const zlib_filefunc64_32_def* pzlib_filefunc_def,
+ voidpf filestream,
+ uLong *pX));
+
+local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def,
+ voidpf filestream,
+ uLong *pX)
+{
+ uLong x ;
+ int i = 0;
+ int err;
+
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x = (uLong)i;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x |= ((uLong)i)<<8;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x |= ((uLong)i)<<16;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x += ((uLong)i)<<24;
+
+ if (err==UNZ_OK)
+ *pX = x;
+ else
+ *pX = 0;
+ return err;
+}
+
+local int unz64local_getLong64 OF((
+ const zlib_filefunc64_32_def* pzlib_filefunc_def,
+ voidpf filestream,
+ ZPOS64_T *pX));
+
+
+local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def,
+ voidpf filestream,
+ ZPOS64_T *pX)
+{
+ ZPOS64_T x ;
+ int i = 0;
+ int err;
+
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x = (ZPOS64_T)i;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x |= ((ZPOS64_T)i)<<8;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x |= ((ZPOS64_T)i)<<16;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x |= ((ZPOS64_T)i)<<24;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x |= ((ZPOS64_T)i)<<32;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x |= ((ZPOS64_T)i)<<40;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x |= ((ZPOS64_T)i)<<48;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x |= ((ZPOS64_T)i)<<56;
+
+ if (err==UNZ_OK)
+ *pX = x;
+ else
+ *pX = 0;
+ return err;
+}
+
+/* My own strcmpi / strcasecmp */
+local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2)
+{
+ for (;;)
+ {
+ char c1=*(fileName1++);
+ char c2=*(fileName2++);
+ if ((c1>='a') && (c1<='z'))
+ c1 -= 0x20;
+ if ((c2>='a') && (c2<='z'))
+ c2 -= 0x20;
+ if (c1=='\0')
+ return ((c2=='\0') ? 0 : -1);
+ if (c2=='\0')
+ return 1;
+ if (c1<c2)
+ return -1;
+ if (c1>c2)
+ return 1;
+ }
+}
+
+
+#ifdef CASESENSITIVITYDEFAULT_NO
+#define CASESENSITIVITYDEFAULTVALUE 2
+#else
+#define CASESENSITIVITYDEFAULTVALUE 1
+#endif
+
+#ifndef STRCMPCASENOSENTIVEFUNCTION
+#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
+#endif
+
+/*
+ Compare two filename (fileName1,fileName2).
+ If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
+ If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
+ or strcasecmp)
+ If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
+ (like 1 on Unix, 2 on Windows)
+
+*/
+extern int ZEXPORT unzStringFileNameCompare (const char* fileName1,
+ const char* fileName2,
+ int iCaseSensitivity)
+
+{
+ if (iCaseSensitivity==0)
+ iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
+
+ if (iCaseSensitivity==1)
+ return strcmp(fileName1,fileName2);
+
+ return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
+}
+
+#ifndef BUFREADCOMMENT
+#define BUFREADCOMMENT (0x400)
+#endif
+
+/*
+ Locate the Central directory of a zipfile (at the end, just before
+ the global comment)
+*/
+local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
+local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
+{
+ unsigned char* buf;
+ ZPOS64_T uSizeFile;
+ ZPOS64_T uBackRead;
+ ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
+ ZPOS64_T uPosFound=0;
+
+ if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
+ return 0;
+
+
+ uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
+
+ if (uMaxBack>uSizeFile)
+ uMaxBack = uSizeFile;
+
+ buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
+ if (buf==NULL)
+ return 0;
+
+ uBackRead = 4;
+ while (uBackRead<uMaxBack)
+ {
+ uLong uReadSize;
+ ZPOS64_T uReadPos ;
+ int i;
+ if (uBackRead+BUFREADCOMMENT>uMaxBack)
+ uBackRead = uMaxBack;
+ else
+ uBackRead+=BUFREADCOMMENT;
+ uReadPos = uSizeFile-uBackRead ;
+
+ uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
+ (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
+ if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ break;
+
+ if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
+ break;
+
+ for (i=(int)uReadSize-3; (i--)>0;)
+ if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
+ ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
+ {
+ uPosFound = uReadPos+i;
+ break;
+ }
+
+ if (uPosFound!=0)
+ break;
+ }
+ TRYFREE(buf);
+ return uPosFound;
+}
+
+
+/*
+ Locate the Central directory 64 of a zipfile (at the end, just before
+ the global comment)
+*/
+local ZPOS64_T unz64local_SearchCentralDir64 OF((
+ const zlib_filefunc64_32_def* pzlib_filefunc_def,
+ voidpf filestream));
+
+local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def,
+ voidpf filestream)
+{
+ unsigned char* buf;
+ ZPOS64_T uSizeFile;
+ ZPOS64_T uBackRead;
+ ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
+ ZPOS64_T uPosFound=0;
+ uLong uL;
+ ZPOS64_T relativeOffset;
+
+ if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
+ return 0;
+
+
+ uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
+
+ if (uMaxBack>uSizeFile)
+ uMaxBack = uSizeFile;
+
+ buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
+ if (buf==NULL)
+ return 0;
+
+ uBackRead = 4;
+ while (uBackRead<uMaxBack)
+ {
+ uLong uReadSize;
+ ZPOS64_T uReadPos;
+ int i;
+ if (uBackRead+BUFREADCOMMENT>uMaxBack)
+ uBackRead = uMaxBack;
+ else
+ uBackRead+=BUFREADCOMMENT;
+ uReadPos = uSizeFile-uBackRead ;
+
+ uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
+ (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
+ if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ break;
+
+ if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
+ break;
+
+ for (i=(int)uReadSize-3; (i--)>0;)
+ if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
+ ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
+ {
+ uPosFound = uReadPos+i;
+ break;
+ }
+
+ if (uPosFound!=0)
+ break;
+ }
+ TRYFREE(buf);
+ if (uPosFound == 0)
+ return 0;
+
+ /* Zip64 end of central directory locator */
+ if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ return 0;
+
+ /* the signature, already checked */
+ if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
+ return 0;
+
+ /* number of the disk with the start of the zip64 end of central directory */
+ if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
+ return 0;
+ if (uL != 0)
+ return 0;
+
+ /* relative offset of the zip64 end of central directory record */
+ if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK)
+ return 0;
+
+ /* total number of disks */
+ if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
+ return 0;
+ if (uL != 1)
+ return 0;
+
+ /* Goto end of central directory record */
+ if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ return 0;
+
+ /* the signature */
+ if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
+ return 0;
+
+ if (uL != 0x06064b50)
+ return 0;
+
+ return relativeOffset;
+}
+
+/*
+ Open a Zip file. path contain the full pathname (by example,
+ on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
+ "zlib/zlib114.zip".
+ If the zipfile cannot be opened (file doesn't exist or in not valid), the
+ return value is NULL.
+ Else, the return value is a unzFile Handle, usable with other function
+ of this unzip package.
+*/
+local unzFile unzOpenInternal (const void *path,
+ zlib_filefunc64_32_def* pzlib_filefunc64_32_def,
+ int is64bitOpenFunction)
+{
+ unz64_s us;
+ unz64_s *s;
+ ZPOS64_T central_pos;
+ uLong uL;
+
+ uLong number_disk; /* number of the current dist, used for
+ spaning ZIP, unsupported, always 0*/
+ uLong number_disk_with_CD; /* number the the disk with central dir, used
+ for spaning ZIP, unsupported, always 0*/
+ ZPOS64_T number_entry_CD; /* total number of entries in
+ the central dir
+ (same than number_entry on nospan) */
+
+ int err=UNZ_OK;
+
+ if (unz_copyright[0]!=' ')
+ return NULL;
+
+ us.z_filefunc.zseek32_file = NULL;
+ us.z_filefunc.ztell32_file = NULL;
+ if (pzlib_filefunc64_32_def==NULL)
+ fill_fopen64_filefunc(&us.z_filefunc.zfile_func64);
+ else
+ us.z_filefunc = *pzlib_filefunc64_32_def;
+ us.is64bitOpenFunction = is64bitOpenFunction;
+
+
+
+ us.filestream = ZOPEN64(us.z_filefunc,
+ path,
+ ZLIB_FILEFUNC_MODE_READ |
+ ZLIB_FILEFUNC_MODE_EXISTING);
+ if (us.filestream==NULL)
+ return NULL;
+
+ central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream);
+ if (central_pos)
+ {
+ uLong uS;
+ ZPOS64_T uL64;
+
+ us.isZip64 = 1;
+
+ if (ZSEEK64(us.z_filefunc, us.filestream,
+ central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ err=UNZ_ERRNO;
+
+ /* the signature, already checked */
+ if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* size of zip64 end of central directory record */
+ if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* version made by */
+ if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* version needed to extract */
+ if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* number of this disk */
+ if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* number of the disk with the start of the central directory */
+ if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* total number of entries in the central directory on this disk */
+ if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* total number of entries in the central directory */
+ if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if ((number_entry_CD!=us.gi.number_entry) ||
+ (number_disk_with_CD!=0) ||
+ (number_disk!=0))
+ err=UNZ_BADZIPFILE;
+
+ /* size of the central directory */
+ if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* offset of start of central directory with respect to the
+ starting disk number */
+ if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ us.gi.size_comment = 0;
+ }
+ else
+ {
+ central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream);
+ if (central_pos==0)
+ err=UNZ_ERRNO;
+
+ us.isZip64 = 0;
+
+ if (ZSEEK64(us.z_filefunc, us.filestream,
+ central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ err=UNZ_ERRNO;
+
+ /* the signature, already checked */
+ if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* number of this disk */
+ if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* number of the disk with the start of the central directory */
+ if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* total number of entries in the central dir on this disk */
+ if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
+ err=UNZ_ERRNO;
+ us.gi.number_entry = uL;
+
+ /* total number of entries in the central dir */
+ if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
+ err=UNZ_ERRNO;
+ number_entry_CD = uL;
+
+ if ((number_entry_CD!=us.gi.number_entry) ||
+ (number_disk_with_CD!=0) ||
+ (number_disk!=0))
+ err=UNZ_BADZIPFILE;
+
+ /* size of the central directory */
+ if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
+ err=UNZ_ERRNO;
+ us.size_central_dir = uL;
+
+ /* offset of start of central directory with respect to the
+ starting disk number */
+ if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
+ err=UNZ_ERRNO;
+ us.offset_central_dir = uL;
+
+ /* zipfile comment length */
+ if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
+ err=UNZ_ERRNO;
+ }
+
+ if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
+ (err==UNZ_OK))
+ err=UNZ_BADZIPFILE;
+
+ if (err!=UNZ_OK)
+ {
+ ZCLOSE64(us.z_filefunc, us.filestream);
+ return NULL;
+ }
+
+ us.byte_before_the_zipfile = central_pos -
+ (us.offset_central_dir+us.size_central_dir);
+ us.central_pos = central_pos;
+ us.pfile_in_zip_read = NULL;
+ us.encrypted = 0;
+
+
+ s=(unz64_s*)ALLOC(sizeof(unz64_s));
+ if( s != NULL)
+ {
+ *s=us;
+ unzGoToFirstFile((unzFile)s);
+ }
+ return (unzFile)s;
+}
+
+
+extern unzFile ZEXPORT unzOpen2 (const char *path,
+ zlib_filefunc_def* pzlib_filefunc32_def)
+{
+ if (pzlib_filefunc32_def != NULL)
+ {
+ zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
+ fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
+ return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 0);
+ }
+ else
+ return unzOpenInternal(path, NULL, 0);
+}
+
+extern unzFile ZEXPORT unzOpen2_64 (const void *path,
+ zlib_filefunc64_def* pzlib_filefunc_def)
+{
+ if (pzlib_filefunc_def != NULL)
+ {
+ zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
+ zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
+ zlib_filefunc64_32_def_fill.ztell32_file = NULL;
+ zlib_filefunc64_32_def_fill.zseek32_file = NULL;
+ return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 1);
+ }
+ else
+ return unzOpenInternal(path, NULL, 1);
+}
+
+extern unzFile ZEXPORT unzOpen (const char *path)
+{
+ return unzOpenInternal(path, NULL, 0);
+}
+
+extern unzFile ZEXPORT unzOpen64 (const void *path)
+{
+ return unzOpenInternal(path, NULL, 1);
+}
+
+/*
+ Close a ZipFile opened with unzipOpen.
+ If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
+ these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
+ return UNZ_OK if there is no problem. */
+extern int ZEXPORT unzClose (unzFile file)
+{
+ unz64_s* s;
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+
+ if (s->pfile_in_zip_read!=NULL)
+ unzCloseCurrentFile(file);
+
+ ZCLOSE64(s->z_filefunc, s->filestream);
+ TRYFREE(s);
+ return UNZ_OK;
+}
+
+
+/*
+ Write info about the ZipFile in the *pglobal_info structure.
+ No preparation of the structure is needed
+ return UNZ_OK if there is no problem. */
+extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info)
+{
+ unz64_s* s;
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ *pglobal_info=s->gi;
+ return UNZ_OK;
+}
+
+extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32)
+{
+ unz64_s* s;
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ /* to do : check if number_entry is not truncated */
+ pglobal_info32->number_entry = (uLong)s->gi.number_entry;
+ pglobal_info32->size_comment = s->gi.size_comment;
+ return UNZ_OK;
+}
+/*
+ Translate date/time from Dos format to tm_unz (readable more easilty)
+*/
+local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm)
+{
+ ZPOS64_T uDate;
+ uDate = (ZPOS64_T)(ulDosDate>>16);
+ ptm->tm_mday = (uInt)(uDate&0x1f) ;
+ ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
+ ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
+
+ ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
+ ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
+ ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
+}
+
+/*
+ Get Info about the current file in the zipfile, with internal only info
+*/
+local int unz64local_GetCurrentFileInfoInternal OF((unzFile file,
+ unz_file_info64 *pfile_info,
+ unz_file_info64_internal
+ *pfile_info_internal,
+ char *szFileName,
+ uLong fileNameBufferSize,
+ void *extraField,
+ uLong extraFieldBufferSize,
+ char *szComment,
+ uLong commentBufferSize));
+
+local int unz64local_GetCurrentFileInfoInternal (unzFile file,
+ unz_file_info64 *pfile_info,
+ unz_file_info64_internal
+ *pfile_info_internal,
+ char *szFileName,
+ uLong fileNameBufferSize,
+ void *extraField,
+ uLong extraFieldBufferSize,
+ char *szComment,
+ uLong commentBufferSize)
+{
+ unz64_s* s;
+ unz_file_info64 file_info;
+ unz_file_info64_internal file_info_internal;
+ int err=UNZ_OK;
+ uLong uMagic;
+ long lSeek=0;
+ uLong uL;
+
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ if (ZSEEK64(s->z_filefunc, s->filestream,
+ s->pos_in_central_dir+s->byte_before_the_zipfile,
+ ZLIB_FILEFUNC_SEEK_SET)!=0)
+ err=UNZ_ERRNO;
+
+
+ /* we check the magic */
+ if (err==UNZ_OK)
+ {
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
+ err=UNZ_ERRNO;
+ else if (uMagic!=0x02014b50)
+ err=UNZ_BADZIPFILE;
+ }
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
+
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
+ err=UNZ_ERRNO;
+ file_info.compressed_size = uL;
+
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
+ err=UNZ_ERRNO;
+ file_info.uncompressed_size = uL;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ // relative offset of local header
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
+ err=UNZ_ERRNO;
+ file_info_internal.offset_curfile = uL;
+
+ lSeek+=file_info.size_filename;
+ if ((err==UNZ_OK) && (szFileName!=NULL))
+ {
+ uLong uSizeRead ;
+ if (file_info.size_filename<fileNameBufferSize)
+ {
+ *(szFileName+file_info.size_filename)='\0';
+ uSizeRead = file_info.size_filename;
+ }
+ else
+ uSizeRead = fileNameBufferSize;
+
+ if ((file_info.size_filename>0) && (fileNameBufferSize>0))
+ if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
+ err=UNZ_ERRNO;
+ lSeek -= uSizeRead;
+ }
+
+ // Read extrafield
+ if ((err==UNZ_OK) && (extraField!=NULL))
+ {
+ ZPOS64_T uSizeRead ;
+ if (file_info.size_file_extra<extraFieldBufferSize)
+ uSizeRead = file_info.size_file_extra;
+ else
+ uSizeRead = extraFieldBufferSize;
+
+ if (lSeek!=0)
+ {
+ if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
+ lSeek=0;
+ else
+ err=UNZ_ERRNO;
+ }
+
+ if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
+ if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead)
+ err=UNZ_ERRNO;
+
+ lSeek += file_info.size_file_extra - (uLong)uSizeRead;
+ }
+ else
+ lSeek += file_info.size_file_extra;
+
+
+ if ((err==UNZ_OK) && (file_info.size_file_extra != 0))
+ {
+ uLong acc = 0;
+
+ // since lSeek now points to after the extra field we need to move back
+ lSeek -= file_info.size_file_extra;
+
+ if (lSeek!=0)
+ {
+ if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
+ lSeek=0;
+ else
+ err=UNZ_ERRNO;
+ }
+
+ while(acc < file_info.size_file_extra)
+ {
+ uLong headerId;
+ uLong dataSize;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* ZIP64 extra fields */
+ if (headerId == 0x0001)
+ {
+ uLong uL;
+
+ if(file_info.uncompressed_size == (ZPOS64_T)(unsigned long)-1)
+ {
+ if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
+ err=UNZ_ERRNO;
+ }
+
+ if(file_info.compressed_size == (ZPOS64_T)(unsigned long)-1)
+ {
+ if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
+ err=UNZ_ERRNO;
+ }
+
+ if(file_info_internal.offset_curfile == (ZPOS64_T)(unsigned long)-1)
+ {
+ /* Relative Header offset */
+ if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
+ err=UNZ_ERRNO;
+ }
+
+ if(file_info.disk_num_start == (unsigned long)-1)
+ {
+ /* Disk Start Number */
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
+ err=UNZ_ERRNO;
+ }
+
+ }
+ else
+ {
+ if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0)
+ err=UNZ_ERRNO;
+ }
+
+ acc += 2 + 2 + dataSize;
+ }
+ }
+
+ if ((err==UNZ_OK) && (szComment!=NULL))
+ {
+ uLong uSizeRead ;
+ if (file_info.size_file_comment<commentBufferSize)
+ {
+ *(szComment+file_info.size_file_comment)='\0';
+ uSizeRead = file_info.size_file_comment;
+ }
+ else
+ uSizeRead = commentBufferSize;
+
+ if (lSeek!=0)
+ {
+ if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
+ lSeek=0;
+ else
+ err=UNZ_ERRNO;
+ }
+
+ if ((file_info.size_file_comment>0) && (commentBufferSize>0))
+ if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
+ err=UNZ_ERRNO;
+ lSeek+=file_info.size_file_comment - uSizeRead;
+ }
+ else
+ lSeek+=file_info.size_file_comment;
+
+
+ if ((err==UNZ_OK) && (pfile_info!=NULL))
+ *pfile_info=file_info;
+
+ if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
+ *pfile_info_internal=file_info_internal;
+
+ return err;
+}
+
+
+
+/*
+ Write info about the ZipFile in the *pglobal_info structure.
+ No preparation of the structure is needed
+ return UNZ_OK if there is no problem.
+*/
+extern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file,
+ unz_file_info64 * pfile_info,
+ char * szFileName, uLong fileNameBufferSize,
+ void *extraField, uLong extraFieldBufferSize,
+ char* szComment, uLong commentBufferSize)
+{
+ return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL,
+ szFileName,fileNameBufferSize,
+ extraField,extraFieldBufferSize,
+ szComment,commentBufferSize);
+}
+
+extern int ZEXPORT unzGetCurrentFileInfo (unzFile file,
+ unz_file_info * pfile_info,
+ char * szFileName, uLong fileNameBufferSize,
+ void *extraField, uLong extraFieldBufferSize,
+ char* szComment, uLong commentBufferSize)
+{
+ int err;
+ unz_file_info64 file_info64;
+ err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL,
+ szFileName,fileNameBufferSize,
+ extraField,extraFieldBufferSize,
+ szComment,commentBufferSize);
+ if (err==UNZ_OK)
+ {
+ pfile_info->version = file_info64.version;
+ pfile_info->version_needed = file_info64.version_needed;
+ pfile_info->flag = file_info64.flag;
+ pfile_info->compression_method = file_info64.compression_method;
+ pfile_info->dosDate = file_info64.dosDate;
+ pfile_info->crc = file_info64.crc;
+
+ pfile_info->size_filename = file_info64.size_filename;
+ pfile_info->size_file_extra = file_info64.size_file_extra;
+ pfile_info->size_file_comment = file_info64.size_file_comment;
+
+ pfile_info->disk_num_start = file_info64.disk_num_start;
+ pfile_info->internal_fa = file_info64.internal_fa;
+ pfile_info->external_fa = file_info64.external_fa;
+
+ pfile_info->tmu_date = file_info64.tmu_date,
+
+
+ pfile_info->compressed_size = (uLong)file_info64.compressed_size;
+ pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size;
+
+ }
+ return err;
+}
+/*
+ Set the current file of the zipfile to the first file.
+ return UNZ_OK if there is no problem
+*/
+extern int ZEXPORT unzGoToFirstFile (unzFile file)
+{
+ int err=UNZ_OK;
+ unz64_s* s;
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ s->pos_in_central_dir=s->offset_central_dir;
+ s->num_file=0;
+ err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
+ &s->cur_file_info_internal,
+ NULL,0,NULL,0,NULL,0);
+ s->current_file_ok = (err == UNZ_OK);
+ return err;
+}
+
+/*
+ Set the current file of the zipfile to the next file.
+ return UNZ_OK if there is no problem
+ return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
+*/
+extern int ZEXPORT unzGoToNextFile (unzFile file)
+{
+ unz64_s* s;
+ int err;
+
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ if (!s->current_file_ok)
+ return UNZ_END_OF_LIST_OF_FILE;
+ if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */
+ if (s->num_file+1==s->gi.number_entry)
+ return UNZ_END_OF_LIST_OF_FILE;
+
+ s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
+ s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
+ s->num_file++;
+ err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
+ &s->cur_file_info_internal,
+ NULL,0,NULL,0,NULL,0);
+ s->current_file_ok = (err == UNZ_OK);
+ return err;
+}
+
+
+/*
+ Try locate the file szFileName in the zipfile.
+ For the iCaseSensitivity signification, see unzipStringFileNameCompare
+
+ return value :
+ UNZ_OK if the file is found. It becomes the current file.
+ UNZ_END_OF_LIST_OF_FILE if the file is not found
+*/
+extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity)
+{
+ unz64_s* s;
+ int err;
+
+ /* We remember the 'current' position in the file so that we can jump
+ * back there if we fail.
+ */
+ unz_file_info64 cur_file_infoSaved;
+ unz_file_info64_internal cur_file_info_internalSaved;
+ ZPOS64_T num_fileSaved;
+ ZPOS64_T pos_in_central_dirSaved;
+
+
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+
+ if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
+ return UNZ_PARAMERROR;
+
+ s=(unz64_s*)file;
+ if (!s->current_file_ok)
+ return UNZ_END_OF_LIST_OF_FILE;
+
+ /* Save the current state */
+ num_fileSaved = s->num_file;
+ pos_in_central_dirSaved = s->pos_in_central_dir;
+ cur_file_infoSaved = s->cur_file_info;
+ cur_file_info_internalSaved = s->cur_file_info_internal;
+
+ err = unzGoToFirstFile(file);
+
+ while (err == UNZ_OK)
+ {
+ char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
+ err = unzGetCurrentFileInfo64(file,NULL,
+ szCurrentFileName,sizeof(szCurrentFileName)-1,
+ NULL,0,NULL,0);
+ if (err == UNZ_OK)
+ {
+ if (unzStringFileNameCompare(szCurrentFileName,
+ szFileName,iCaseSensitivity)==0)
+ return UNZ_OK;
+ err = unzGoToNextFile(file);
+ }
+ }
+
+ /* We failed, so restore the state of the 'current file' to where we
+ * were.
+ */
+ s->num_file = num_fileSaved ;
+ s->pos_in_central_dir = pos_in_central_dirSaved ;
+ s->cur_file_info = cur_file_infoSaved;
+ s->cur_file_info_internal = cur_file_info_internalSaved;
+ return err;
+}
+
+
+/*
+///////////////////////////////////////////
+// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
+// I need random access
+//
+// Further optimization could be realized by adding an ability
+// to cache the directory in memory. The goal being a single
+// comprehensive file read to put the file I need in a memory.
+*/
+
+/*
+typedef struct unz_file_pos_s
+{
+ ZPOS64_T pos_in_zip_directory; // offset in file
+ ZPOS64_T num_of_file; // # of file
+} unz_file_pos;
+*/
+
+extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos)
+{
+ unz64_s* s;
+
+ if (file==NULL || file_pos==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ if (!s->current_file_ok)
+ return UNZ_END_OF_LIST_OF_FILE;
+
+ file_pos->pos_in_zip_directory = s->pos_in_central_dir;
+ file_pos->num_of_file = s->num_file;
+
+ return UNZ_OK;
+}
+
+extern int ZEXPORT unzGetFilePos(
+ unzFile file,
+ unz_file_pos* file_pos)
+{
+ unz64_file_pos file_pos64;
+ int err = unzGetFilePos64(file,&file_pos64);
+ if (err==UNZ_OK)
+ {
+ file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory;
+ file_pos->num_of_file = (uLong)file_pos64.num_of_file;
+ }
+ return err;
+}
+
+extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos)
+{
+ unz64_s* s;
+ int err;
+
+ if (file==NULL || file_pos==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+
+ /* jump to the right spot */
+ s->pos_in_central_dir = file_pos->pos_in_zip_directory;
+ s->num_file = file_pos->num_of_file;
+
+ /* set the current file */
+ err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
+ &s->cur_file_info_internal,
+ NULL,0,NULL,0,NULL,0);
+ /* return results */
+ s->current_file_ok = (err == UNZ_OK);
+ return err;
+}
+
+extern int ZEXPORT unzGoToFilePos(
+ unzFile file,
+ unz_file_pos* file_pos)
+{
+ unz64_file_pos file_pos64;
+ if (file_pos == NULL)
+ return UNZ_PARAMERROR;
+
+ file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory;
+ file_pos64.num_of_file = file_pos->num_of_file;
+ return unzGoToFilePos64(file,&file_pos64);
+}
+
+/*
+// Unzip Helper Functions - should be here?
+///////////////////////////////////////////
+*/
+
+/*
+ Read the local header of the current zipfile
+ Check the coherency of the local header and info in the end of central
+ directory about this file
+ store in *piSizeVar the size of extra info in local header
+ (filename and size of extra field data)
+*/
+local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar,
+ ZPOS64_T * poffset_local_extrafield,
+ uInt * psize_local_extrafield)
+{
+ uLong uMagic,uData,uFlags;
+ uLong size_filename;
+ uLong size_extra_field;
+ int err=UNZ_OK;
+
+ *piSizeVar = 0;
+ *poffset_local_extrafield = 0;
+ *psize_local_extrafield = 0;
+
+ if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
+ s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ return UNZ_ERRNO;
+
+
+ if (err==UNZ_OK)
+ {
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
+ err=UNZ_ERRNO;
+ else if (uMagic!=0x04034b50)
+ err=UNZ_BADZIPFILE;
+ }
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
+ err=UNZ_ERRNO;
+/*
+ else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
+ err=UNZ_BADZIPFILE;
+*/
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
+ err=UNZ_ERRNO;
+ else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
+ err=UNZ_BADZIPFILE;
+
+ if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
+/* #ifdef HAVE_BZIP2 */
+ (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
+/* #endif */
+ (s->cur_file_info.compression_method!=Z_DEFLATED))
+ err=UNZ_BADZIPFILE;
+
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
+ err=UNZ_ERRNO;
+
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
+ err=UNZ_ERRNO;
+ else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0))
+ err=UNZ_BADZIPFILE;
+
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
+ err=UNZ_ERRNO;
+ else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0))
+ err=UNZ_BADZIPFILE;
+
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
+ err=UNZ_ERRNO;
+ else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0))
+ err=UNZ_BADZIPFILE;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
+ err=UNZ_ERRNO;
+ else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
+ err=UNZ_BADZIPFILE;
+
+ *piSizeVar += (uInt)size_filename;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
+ err=UNZ_ERRNO;
+ *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
+ SIZEZIPLOCALHEADER + size_filename;
+ *psize_local_extrafield = (uInt)size_extra_field;
+
+ *piSizeVar += (uInt)size_extra_field;
+
+ return err;
+}
+
+/*
+ Open for reading data the current file in the zipfile.
+ If there is no error and the file is opened, the return value is UNZ_OK.
+*/
+extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method,
+ int* level, int raw, const char* password)
+{
+ int err=UNZ_OK;
+ uInt iSizeVar;
+ unz64_s* s;
+ file_in_zip64_read_info_s* pfile_in_zip_read_info;
+ ZPOS64_T offset_local_extrafield; /* offset of the local extra field */
+ uInt size_local_extrafield; /* size of the local extra field */
+# ifndef NOUNCRYPT
+ char source[12];
+# else
+ if (password != NULL)
+ return UNZ_PARAMERROR;
+# endif
+
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ if (!s->current_file_ok)
+ return UNZ_PARAMERROR;
+
+ if (s->pfile_in_zip_read != NULL)
+ unzCloseCurrentFile(file);
+
+ if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
+ return UNZ_BADZIPFILE;
+
+ pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s));
+ if (pfile_in_zip_read_info==NULL)
+ return UNZ_INTERNALERROR;
+
+ pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
+ pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
+ pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
+ pfile_in_zip_read_info->pos_local_extrafield=0;
+ pfile_in_zip_read_info->raw=raw;
+
+ if (pfile_in_zip_read_info->read_buffer==NULL)
+ {
+ TRYFREE(pfile_in_zip_read_info);
+ return UNZ_INTERNALERROR;
+ }
+
+ pfile_in_zip_read_info->stream_initialised=0;
+
+ if (method!=NULL)
+ *method = (int)s->cur_file_info.compression_method;
+
+ if (level!=NULL)
+ {
+ *level = 6;
+ switch (s->cur_file_info.flag & 0x06)
+ {
+ case 6 : *level = 1; break;
+ case 4 : *level = 2; break;
+ case 2 : *level = 9; break;
+ }
+ }
+
+ if ((s->cur_file_info.compression_method!=0) &&
+/* #ifdef HAVE_BZIP2 */
+ (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
+/* #endif */
+ (s->cur_file_info.compression_method!=Z_DEFLATED))
+
+ err=UNZ_BADZIPFILE;
+
+ pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
+ pfile_in_zip_read_info->crc32=0;
+ pfile_in_zip_read_info->total_out_64=0;
+ pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method;
+ pfile_in_zip_read_info->filestream=s->filestream;
+ pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
+ pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
+
+ pfile_in_zip_read_info->stream.total_out = 0;
+
+ if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw))
+ {
+#ifdef HAVE_BZIP2
+ pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0;
+ pfile_in_zip_read_info->bstream.bzfree = (free_func)0;
+ pfile_in_zip_read_info->bstream.opaque = (voidpf)0;
+ pfile_in_zip_read_info->bstream.state = (voidpf)0;
+
+ pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
+ pfile_in_zip_read_info->stream.zfree = (free_func)0;
+ pfile_in_zip_read_info->stream.opaque = (voidpf)0;
+ pfile_in_zip_read_info->stream.next_in = (voidpf)0;
+ pfile_in_zip_read_info->stream.avail_in = 0;
+
+ err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0);
+ if (err == Z_OK)
+ pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED;
+ else
+ {
+ TRYFREE(pfile_in_zip_read_info);
+ return err;
+ }
+#else
+ pfile_in_zip_read_info->raw=1;
+#endif
+ }
+ else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw))
+ {
+ pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
+ pfile_in_zip_read_info->stream.zfree = (free_func)0;
+ pfile_in_zip_read_info->stream.opaque = (voidpf)0;
+ pfile_in_zip_read_info->stream.next_in = 0;
+ pfile_in_zip_read_info->stream.avail_in = 0;
+
+ err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
+ if (err == Z_OK)
+ pfile_in_zip_read_info->stream_initialised=Z_DEFLATED;
+ else
+ {
+ TRYFREE(pfile_in_zip_read_info);
+ return err;
+ }
+ /* windowBits is passed < 0 to tell that there is no zlib header.
+ * Note that in this case inflate *requires* an extra "dummy" byte
+ * after the compressed stream in order to complete decompression and
+ * return Z_STREAM_END.
+ * In unzip, i don't wait absolutely Z_STREAM_END because I known the
+ * size of both compressed and uncompressed data
+ */
+ }
+ pfile_in_zip_read_info->rest_read_compressed =
+ s->cur_file_info.compressed_size ;
+ pfile_in_zip_read_info->rest_read_uncompressed =
+ s->cur_file_info.uncompressed_size ;
+
+
+ pfile_in_zip_read_info->pos_in_zipfile =
+ s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
+ iSizeVar;
+
+ pfile_in_zip_read_info->stream.avail_in = (uInt)0;
+
+ s->pfile_in_zip_read = pfile_in_zip_read_info;
+ s->encrypted = 0;
+
+# ifndef NOUNCRYPT
+ if (password != NULL)
+ {
+ int i;
+ s->pcrc_32_tab = get_crc_table();
+ init_keys(password,s->keys,s->pcrc_32_tab);
+ if (ZSEEK64(s->z_filefunc, s->filestream,
+ s->pfile_in_zip_read->pos_in_zipfile +
+ s->pfile_in_zip_read->byte_before_the_zipfile,
+ SEEK_SET)!=0)
+ return UNZ_INTERNALERROR;
+ if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12)
+ return UNZ_INTERNALERROR;
+
+ for (i = 0; i<12; i++)
+ zdecode(s->keys,s->pcrc_32_tab,source[i]);
+
+ s->pfile_in_zip_read->pos_in_zipfile+=12;
+ s->encrypted=1;
+ }
+# endif
+
+
+ return UNZ_OK;
+}
+
+extern int ZEXPORT unzOpenCurrentFile (unzFile file)
+{
+ return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
+}
+
+extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char* password)
+{
+ return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
+}
+
+extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw)
+{
+ return unzOpenCurrentFile3(file, method, level, raw, NULL);
+}
+
+/** Addition for GDAL : START */
+
+extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file)
+{
+ unz64_s* s;
+ file_in_zip64_read_info_s* pfile_in_zip_read_info;
+ s=(unz64_s*)file;
+ if (file==NULL)
+ return 0; //UNZ_PARAMERROR;
+ pfile_in_zip_read_info=s->pfile_in_zip_read;
+ if (pfile_in_zip_read_info==NULL)
+ return 0; //UNZ_PARAMERROR;
+ return pfile_in_zip_read_info->pos_in_zipfile +
+ pfile_in_zip_read_info->byte_before_the_zipfile;
+}
+
+/** Addition for GDAL : END */
+
+/*
+ Read bytes from the current file.
+ buf contain buffer where data must be copied
+ len the size of buf.
+
+ return the number of byte copied if somes bytes are copied
+ return 0 if the end of file was reached
+ return <0 with error code if there is an error
+ (UNZ_ERRNO for IO error, or zLib error for uncompress error)
+*/
+extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len)
+{
+ int err=UNZ_OK;
+ uInt iRead = 0;
+ unz64_s* s;
+ file_in_zip64_read_info_s* pfile_in_zip_read_info;
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+ if (pfile_in_zip_read_info==NULL)
+ return UNZ_PARAMERROR;
+
+
+ if ((pfile_in_zip_read_info->read_buffer == NULL))
+ return UNZ_END_OF_LIST_OF_FILE;
+ if (len==0)
+ return 0;
+
+ pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
+
+ pfile_in_zip_read_info->stream.avail_out = (uInt)len;
+
+ if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
+ (!(pfile_in_zip_read_info->raw)))
+ pfile_in_zip_read_info->stream.avail_out =
+ (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
+
+ if ((len>pfile_in_zip_read_info->rest_read_compressed+
+ pfile_in_zip_read_info->stream.avail_in) &&
+ (pfile_in_zip_read_info->raw))
+ pfile_in_zip_read_info->stream.avail_out =
+ (uInt)pfile_in_zip_read_info->rest_read_compressed+
+ pfile_in_zip_read_info->stream.avail_in;
+
+ while (pfile_in_zip_read_info->stream.avail_out>0)
+ {
+ if ((pfile_in_zip_read_info->stream.avail_in==0) &&
+ (pfile_in_zip_read_info->rest_read_compressed>0))
+ {
+ uInt uReadThis = UNZ_BUFSIZE;
+ if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
+ uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
+ if (uReadThis == 0)
+ return UNZ_EOF;
+ if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
+ pfile_in_zip_read_info->filestream,
+ pfile_in_zip_read_info->pos_in_zipfile +
+ pfile_in_zip_read_info->byte_before_the_zipfile,
+ ZLIB_FILEFUNC_SEEK_SET)!=0)
+ return UNZ_ERRNO;
+ if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
+ pfile_in_zip_read_info->filestream,
+ pfile_in_zip_read_info->read_buffer,
+ uReadThis)!=uReadThis)
+ return UNZ_ERRNO;
+
+
+# ifndef NOUNCRYPT
+ if(s->encrypted)
+ {
+ uInt i;
+ for(i=0;i<uReadThis;i++)
+ pfile_in_zip_read_info->read_buffer[i] =
+ zdecode(s->keys,s->pcrc_32_tab,
+ pfile_in_zip_read_info->read_buffer[i]);
+ }
+# endif
+
+
+ pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
+
+ pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
+
+ pfile_in_zip_read_info->stream.next_in =
+ (Bytef*)pfile_in_zip_read_info->read_buffer;
+ pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
+ }
+
+ if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
+ {
+ uInt uDoCopy,i ;
+
+ if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
+ (pfile_in_zip_read_info->rest_read_compressed == 0))
+ return (iRead==0) ? UNZ_EOF : iRead;
+
+ if (pfile_in_zip_read_info->stream.avail_out <
+ pfile_in_zip_read_info->stream.avail_in)
+ uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
+ else
+ uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
+
+ for (i=0;i<uDoCopy;i++)
+ *(pfile_in_zip_read_info->stream.next_out+i) =
+ *(pfile_in_zip_read_info->stream.next_in+i);
+
+ pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy;
+
+ pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
+ pfile_in_zip_read_info->stream.next_out,
+ uDoCopy);
+ pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
+ pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
+ pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
+ pfile_in_zip_read_info->stream.next_out += uDoCopy;
+ pfile_in_zip_read_info->stream.next_in += uDoCopy;
+ pfile_in_zip_read_info->stream.total_out += uDoCopy;
+ iRead += uDoCopy;
+ }
+ else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED)
+ {
+#ifdef HAVE_BZIP2
+ uLong uTotalOutBefore,uTotalOutAfter;
+ const Bytef *bufBefore;
+ uLong uOutThis;
+
+ pfile_in_zip_read_info->bstream.next_in = (char*)pfile_in_zip_read_info->stream.next_in;
+ pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in;
+ pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_info->stream.total_in;
+ pfile_in_zip_read_info->bstream.total_in_hi32 = 0;
+ pfile_in_zip_read_info->bstream.next_out = (char*)pfile_in_zip_read_info->stream.next_out;
+ pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_info->stream.avail_out;
+ pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out;
+ pfile_in_zip_read_info->bstream.total_out_hi32 = 0;
+
+ uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32;
+ bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out;
+
+ err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream);
+
+ uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32;
+ uOutThis = uTotalOutAfter-uTotalOutBefore;
+
+ pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
+
+ pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis));
+ pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis;
+ iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
+
+ pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->bstream.next_in;
+ pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in;
+ pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->bstream.total_in_lo32;
+ pfile_in_zip_read_info->stream.next_out = (Bytef*)pfile_in_zip_read_info->bstream.next_out;
+ pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out;
+ pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32;
+
+ if (err==BZ_STREAM_END)
+ return (iRead==0) ? UNZ_EOF : iRead;
+ if (err!=BZ_OK)
+ break;
+#endif
+ } // end Z_BZIP2ED
+ else
+ {
+ ZPOS64_T uTotalOutBefore,uTotalOutAfter;
+ const Bytef *bufBefore;
+ ZPOS64_T uOutThis;
+ int flush=Z_SYNC_FLUSH;
+
+ uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
+ bufBefore = pfile_in_zip_read_info->stream.next_out;
+
+ /*
+ if ((pfile_in_zip_read_info->rest_read_uncompressed ==
+ pfile_in_zip_read_info->stream.avail_out) &&
+ (pfile_in_zip_read_info->rest_read_compressed == 0))
+ flush = Z_FINISH;
+ */
+ err=inflate(&pfile_in_zip_read_info->stream,flush);
+
+ if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
+ err = Z_DATA_ERROR;
+
+ uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
+ uOutThis = uTotalOutAfter-uTotalOutBefore;
+
+ pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
+
+ pfile_in_zip_read_info->crc32 =
+ crc32(pfile_in_zip_read_info->crc32,bufBefore,
+ (uInt)(uOutThis));
+
+ pfile_in_zip_read_info->rest_read_uncompressed -=
+ uOutThis;
+
+ iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
+
+ if (err==Z_STREAM_END)
+ return (iRead==0) ? UNZ_EOF : iRead;
+ if (err!=Z_OK)
+ break;
+ }
+ }
+
+ if (err==Z_OK)
+ return iRead;
+ return err;
+}
+
+
+/*
+ Give the current position in uncompressed data
+*/
+extern z_off_t ZEXPORT unztell (unzFile file)
+{
+ unz64_s* s;
+ file_in_zip64_read_info_s* pfile_in_zip_read_info;
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+ if (pfile_in_zip_read_info==NULL)
+ return UNZ_PARAMERROR;
+
+ return (z_off_t)pfile_in_zip_read_info->stream.total_out;
+}
+
+extern ZPOS64_T ZEXPORT unztell64 (unzFile file)
+{
+
+ unz64_s* s;
+ file_in_zip64_read_info_s* pfile_in_zip_read_info;
+ if (file==NULL)
+ return (ZPOS64_T)-1;
+ s=(unz64_s*)file;
+ pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+ if (pfile_in_zip_read_info==NULL)
+ return (ZPOS64_T)-1;
+
+ return pfile_in_zip_read_info->total_out_64;
+}
+
+
+/*
+ return 1 if the end of file was reached, 0 elsewhere
+*/
+extern int ZEXPORT unzeof (unzFile file)
+{
+ unz64_s* s;
+ file_in_zip64_read_info_s* pfile_in_zip_read_info;
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+ if (pfile_in_zip_read_info==NULL)
+ return UNZ_PARAMERROR;
+
+ if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
+ return 1;
+ else
+ return 0;
+}
+
+
+
+/*
+Read extra field from the current file (opened by unzOpenCurrentFile)
+This is the local-header version of the extra field (sometimes, there is
+more info in the local-header version than in the central-header)
+
+ if buf==NULL, it return the size of the local extra field that can be read
+
+ if buf!=NULL, len is the size of the buffer, the extra header is copied in
+ buf.
+ the return value is the number of bytes copied in buf, or (if <0)
+ the error code
+*/
+extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len)
+{
+ unz64_s* s;
+ file_in_zip64_read_info_s* pfile_in_zip_read_info;
+ uInt read_now;
+ ZPOS64_T size_to_read;
+
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+ if (pfile_in_zip_read_info==NULL)
+ return UNZ_PARAMERROR;
+
+ size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
+ pfile_in_zip_read_info->pos_local_extrafield);
+
+ if (buf==NULL)
+ return (int)size_to_read;
+
+ if (len>size_to_read)
+ read_now = (uInt)size_to_read;
+ else
+ read_now = (uInt)len ;
+
+ if (read_now==0)
+ return 0;
+
+ if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
+ pfile_in_zip_read_info->filestream,
+ pfile_in_zip_read_info->offset_local_extrafield +
+ pfile_in_zip_read_info->pos_local_extrafield,
+ ZLIB_FILEFUNC_SEEK_SET)!=0)
+ return UNZ_ERRNO;
+
+ if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
+ pfile_in_zip_read_info->filestream,
+ buf,read_now)!=read_now)
+ return UNZ_ERRNO;
+
+ return (int)read_now;
+}
+
+/*
+ Close the file in zip opened with unzipOpenCurrentFile
+ Return UNZ_CRCERROR if all the file was read but the CRC is not good
+*/
+extern int ZEXPORT unzCloseCurrentFile (unzFile file)
+{
+ int err=UNZ_OK;
+
+ unz64_s* s;
+ file_in_zip64_read_info_s* pfile_in_zip_read_info;
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+ if (pfile_in_zip_read_info==NULL)
+ return UNZ_PARAMERROR;
+
+
+ if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
+ (!pfile_in_zip_read_info->raw))
+ {
+ if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
+ err=UNZ_CRCERROR;
+ }
+
+
+ TRYFREE(pfile_in_zip_read_info->read_buffer);
+ pfile_in_zip_read_info->read_buffer = NULL;
+ if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED)
+ inflateEnd(&pfile_in_zip_read_info->stream);
+#ifdef HAVE_BZIP2
+ else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED)
+ BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream);
+#endif
+
+
+ pfile_in_zip_read_info->stream_initialised = 0;
+ TRYFREE(pfile_in_zip_read_info);
+
+ s->pfile_in_zip_read=NULL;
+
+ return err;
+}
+
+
+/*
+ Get the global comment string of the ZipFile, in the szComment buffer.
+ uSizeBuf is the size of the szComment buffer.
+ return the number of byte copied or an error code <0
+*/
+extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf)
+{
+ unz64_s* s;
+ uLong uReadThis ;
+ if (file==NULL)
+ return (int)UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+
+ uReadThis = uSizeBuf;
+ if (uReadThis>s->gi.size_comment)
+ uReadThis = s->gi.size_comment;
+
+ if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ return UNZ_ERRNO;
+
+ if (uReadThis>0)
+ {
+ *szComment='\0';
+ if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
+ return UNZ_ERRNO;
+ }
+
+ if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
+ *(szComment+s->gi.size_comment)='\0';
+ return (int)uReadThis;
+}
+
+/* Additions by RX '2004 */
+extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file)
+{
+ unz64_s* s;
+
+ if (file==NULL)
+ return 0; //UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ if (!s->current_file_ok)
+ return 0;
+ if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
+ if (s->num_file==s->gi.number_entry)
+ return 0;
+ return s->pos_in_central_dir;
+}
+
+extern uLong ZEXPORT unzGetOffset (unzFile file)
+{
+ ZPOS64_T offset64;
+
+ if (file==NULL)
+ return 0; //UNZ_PARAMERROR;
+ offset64 = unzGetOffset64(file);
+ return (uLong)offset64;
+}
+
+extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos)
+{
+ unz64_s* s;
+ int err;
+
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+
+ s->pos_in_central_dir = pos;
+ s->num_file = s->gi.number_entry; /* hack */
+ err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
+ &s->cur_file_info_internal,
+ NULL,0,NULL,0,NULL,0);
+ s->current_file_ok = (err == UNZ_OK);
+ return err;
+}
+
+extern int ZEXPORT unzSetOffset (unzFile file, uLong pos)
+{
+ return unzSetOffset64(file,pos);
+}
--- /dev/null
+/* unzip.h -- IO for uncompress .zip files using zlib
+ Version 1.1, February 14h, 2010
+ part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Modifications of Unzip for Zip64
+ Copyright (C) 2007-2008 Even Rouault
+
+ Modifications for Zip64 support on both zip and unzip
+ Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+ For more info read MiniZip_info.txt
+
+ ---------------------------------------------------------------------------------
+
+ Condition of use and distribution are the same than zlib :
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ ---------------------------------------------------------------------------------
+
+ Changes
+
+ See header of unzip64.c
+
+*/
+
+#ifndef _unz64_H
+#define _unz64_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _ZLIB_H
+#include "zlib.h"
+#endif
+
+#ifndef _ZLIBIOAPI_H
+#include "ioapi.h"
+#endif
+
+#ifdef HAVE_BZIP2
+#include "bzlib.h"
+#endif
+
+#define Z_BZIP2ED 12
+
+#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
+/* like the STRICT of WIN32, we define a pointer that cannot be converted
+ from (void*) without cast */
+typedef struct TagunzFile__ { int unused; } unzFile__;
+typedef unzFile__ *unzFile;
+#else
+typedef voidp unzFile;
+#endif
+
+
+#define UNZ_OK (0)
+#define UNZ_END_OF_LIST_OF_FILE (-100)
+#define UNZ_ERRNO (Z_ERRNO)
+#define UNZ_EOF (0)
+#define UNZ_PARAMERROR (-102)
+#define UNZ_BADZIPFILE (-103)
+#define UNZ_INTERNALERROR (-104)
+#define UNZ_CRCERROR (-105)
+
+/* tm_unz contain date/time info */
+typedef struct tm_unz_s
+{
+ uInt tm_sec; /* seconds after the minute - [0,59] */
+ uInt tm_min; /* minutes after the hour - [0,59] */
+ uInt tm_hour; /* hours since midnight - [0,23] */
+ uInt tm_mday; /* day of the month - [1,31] */
+ uInt tm_mon; /* months since January - [0,11] */
+ uInt tm_year; /* years - [1980..2044] */
+} tm_unz;
+
+/* unz_global_info structure contain global data about the ZIPfile
+ These data comes from the end of central dir */
+typedef struct unz_global_info64_s
+{
+ ZPOS64_T number_entry; /* total number of entries in
+ the central dir on this disk */
+ uLong size_comment; /* size of the global comment of the zipfile */
+} unz_global_info64;
+
+typedef struct unz_global_info_s
+{
+ uLong number_entry; /* total number of entries in
+ the central dir on this disk */
+ uLong size_comment; /* size of the global comment of the zipfile */
+} unz_global_info;
+
+/* unz_file_info contain information about a file in the zipfile */
+typedef struct unz_file_info64_s
+{
+ uLong version; /* version made by 2 bytes */
+ uLong version_needed; /* version needed to extract 2 bytes */
+ uLong flag; /* general purpose bit flag 2 bytes */
+ uLong compression_method; /* compression method 2 bytes */
+ uLong dosDate; /* last mod file date in Dos fmt 4 bytes */
+ uLong crc; /* crc-32 4 bytes */
+ ZPOS64_T compressed_size; /* compressed size 8 bytes */
+ ZPOS64_T uncompressed_size; /* uncompressed size 8 bytes */
+ uLong size_filename; /* filename length 2 bytes */
+ uLong size_file_extra; /* extra field length 2 bytes */
+ uLong size_file_comment; /* file comment length 2 bytes */
+
+ uLong disk_num_start; /* disk number start 2 bytes */
+ uLong internal_fa; /* internal file attributes 2 bytes */
+ uLong external_fa; /* external file attributes 4 bytes */
+
+ tm_unz tmu_date;
+} unz_file_info64;
+
+typedef struct unz_file_info_s
+{
+ uLong version; /* version made by 2 bytes */
+ uLong version_needed; /* version needed to extract 2 bytes */
+ uLong flag; /* general purpose bit flag 2 bytes */
+ uLong compression_method; /* compression method 2 bytes */
+ uLong dosDate; /* last mod file date in Dos fmt 4 bytes */
+ uLong crc; /* crc-32 4 bytes */
+ uLong compressed_size; /* compressed size 4 bytes */
+ uLong uncompressed_size; /* uncompressed size 4 bytes */
+ uLong size_filename; /* filename length 2 bytes */
+ uLong size_file_extra; /* extra field length 2 bytes */
+ uLong size_file_comment; /* file comment length 2 bytes */
+
+ uLong disk_num_start; /* disk number start 2 bytes */
+ uLong internal_fa; /* internal file attributes 2 bytes */
+ uLong external_fa; /* external file attributes 4 bytes */
+
+ tm_unz tmu_date;
+} unz_file_info;
+
+extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
+ const char* fileName2,
+ int iCaseSensitivity));
+/*
+ Compare two filename (fileName1,fileName2).
+ If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
+ If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
+ or strcasecmp)
+ If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
+ (like 1 on Unix, 2 on Windows)
+*/
+
+
+extern unzFile ZEXPORT unzOpen OF((const char *path));
+extern unzFile ZEXPORT unzOpen64 OF((const void *path));
+/*
+ Open a Zip file. path contain the full pathname (by example,
+ on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer
+ "zlib/zlib113.zip".
+ If the zipfile cannot be opened (file don't exist or in not valid), the
+ return value is NULL.
+ Else, the return value is a unzFile Handle, usable with other function
+ of this unzip package.
+ the "64" function take a const void* pointer, because the path is just the
+ value passed to the open64_file_func callback.
+ Under Windows, if UNICODE is defined, using fill_fopen64_filefunc, the path
+ is a pointer to a wide unicode string (LPCTSTR is LPCWSTR), so const char*
+ does not describe the reality
+*/
+
+
+extern unzFile ZEXPORT unzOpen2 OF((const char *path,
+ zlib_filefunc_def* pzlib_filefunc_def));
+/*
+ Open a Zip file, like unzOpen, but provide a set of file low level API
+ for read/write the zip file (see ioapi.h)
+*/
+
+extern unzFile ZEXPORT unzOpen2_64 OF((const void *path,
+ zlib_filefunc64_def* pzlib_filefunc_def));
+/*
+ Open a Zip file, like unz64Open, but provide a set of file low level API
+ for read/write the zip file (see ioapi.h)
+*/
+
+extern int ZEXPORT unzClose OF((unzFile file));
+/*
+ Close a ZipFile opened with unzipOpen.
+ If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
+ these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
+ return UNZ_OK if there is no problem. */
+
+extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
+ unz_global_info *pglobal_info));
+
+extern int ZEXPORT unzGetGlobalInfo64 OF((unzFile file,
+ unz_global_info64 *pglobal_info));
+/*
+ Write info about the ZipFile in the *pglobal_info structure.
+ No preparation of the structure is needed
+ return UNZ_OK if there is no problem. */
+
+
+extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
+ char *szComment,
+ uLong uSizeBuf));
+/*
+ Get the global comment string of the ZipFile, in the szComment buffer.
+ uSizeBuf is the size of the szComment buffer.
+ return the number of byte copied or an error code <0
+*/
+
+
+/***************************************************************************/
+/* Unzip package allow you browse the directory of the zipfile */
+
+extern int ZEXPORT unzGoToFirstFile OF((unzFile file));
+/*
+ Set the current file of the zipfile to the first file.
+ return UNZ_OK if there is no problem
+*/
+
+extern int ZEXPORT unzGoToNextFile OF((unzFile file));
+/*
+ Set the current file of the zipfile to the next file.
+ return UNZ_OK if there is no problem
+ return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
+*/
+
+extern int ZEXPORT unzLocateFile OF((unzFile file,
+ const char *szFileName,
+ int iCaseSensitivity));
+/*
+ Try locate the file szFileName in the zipfile.
+ For the iCaseSensitivity signification, see unzStringFileNameCompare
+
+ return value :
+ UNZ_OK if the file is found. It becomes the current file.
+ UNZ_END_OF_LIST_OF_FILE if the file is not found
+*/
+
+
+/* ****************************************** */
+/* Ryan supplied functions */
+/* unz_file_info contain information about a file in the zipfile */
+typedef struct unz_file_pos_s
+{
+ uLong pos_in_zip_directory; /* offset in zip file directory */
+ uLong num_of_file; /* # of file */
+} unz_file_pos;
+
+extern int ZEXPORT unzGetFilePos(
+ unzFile file,
+ unz_file_pos* file_pos);
+
+extern int ZEXPORT unzGoToFilePos(
+ unzFile file,
+ unz_file_pos* file_pos);
+
+typedef struct unz64_file_pos_s
+{
+ ZPOS64_T pos_in_zip_directory; /* offset in zip file directory */
+ ZPOS64_T num_of_file; /* # of file */
+} unz64_file_pos;
+
+extern int ZEXPORT unzGetFilePos64(
+ unzFile file,
+ unz64_file_pos* file_pos);
+
+extern int ZEXPORT unzGoToFilePos64(
+ unzFile file,
+ const unz64_file_pos* file_pos);
+
+/* ****************************************** */
+
+extern int ZEXPORT unzGetCurrentFileInfo64 OF((unzFile file,
+ unz_file_info64 *pfile_info,
+ char *szFileName,
+ uLong fileNameBufferSize,
+ void *extraField,
+ uLong extraFieldBufferSize,
+ char *szComment,
+ uLong commentBufferSize));
+
+extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
+ unz_file_info *pfile_info,
+ char *szFileName,
+ uLong fileNameBufferSize,
+ void *extraField,
+ uLong extraFieldBufferSize,
+ char *szComment,
+ uLong commentBufferSize));
+/*
+ Get Info about the current file
+ if pfile_info!=NULL, the *pfile_info structure will contain somes info about
+ the current file
+ if szFileName!=NULL, the filemane string will be copied in szFileName
+ (fileNameBufferSize is the size of the buffer)
+ if extraField!=NULL, the extra field information will be copied in extraField
+ (extraFieldBufferSize is the size of the buffer).
+ This is the Central-header version of the extra field
+ if szComment!=NULL, the comment string of the file will be copied in szComment
+ (commentBufferSize is the size of the buffer)
+*/
+
+
+/** Addition for GDAL : START */
+
+extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file));
+
+/** Addition for GDAL : END */
+
+
+/***************************************************************************/
+/* for reading the content of the current zipfile, you can open it, read data
+ from it, and close it (you can close it before reading all the file)
+ */
+
+extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));
+/*
+ Open for reading data the current file in the zipfile.
+ If there is no error, the return value is UNZ_OK.
+*/
+
+extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file,
+ const char* password));
+/*
+ Open for reading data the current file in the zipfile.
+ password is a crypting password
+ If there is no error, the return value is UNZ_OK.
+*/
+
+extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file,
+ int* method,
+ int* level,
+ int raw));
+/*
+ Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
+ if raw==1
+ *method will receive method of compression, *level will receive level of
+ compression
+ note : you can set level parameter as NULL (if you did not want known level,
+ but you CANNOT set method parameter as NULL
+*/
+
+extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file,
+ int* method,
+ int* level,
+ int raw,
+ const char* password));
+/*
+ Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
+ if raw==1
+ *method will receive method of compression, *level will receive level of
+ compression
+ note : you can set level parameter as NULL (if you did not want known level,
+ but you CANNOT set method parameter as NULL
+*/
+
+
+extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));
+/*
+ Close the file in zip opened with unzOpenCurrentFile
+ Return UNZ_CRCERROR if all the file was read but the CRC is not good
+*/
+
+extern int ZEXPORT unzReadCurrentFile OF((unzFile file,
+ voidp buf,
+ unsigned len));
+/*
+ Read bytes from the current file (opened by unzOpenCurrentFile)
+ buf contain buffer where data must be copied
+ len the size of buf.
+
+ return the number of byte copied if somes bytes are copied
+ return 0 if the end of file was reached
+ return <0 with error code if there is an error
+ (UNZ_ERRNO for IO error, or zLib error for uncompress error)
+*/
+
+extern z_off_t ZEXPORT unztell OF((unzFile file));
+
+extern ZPOS64_T ZEXPORT unztell64 OF((unzFile file));
+/*
+ Give the current position in uncompressed data
+*/
+
+extern int ZEXPORT unzeof OF((unzFile file));
+/*
+ return 1 if the end of file was reached, 0 elsewhere
+*/
+
+extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
+ voidp buf,
+ unsigned len));
+/*
+ Read extra field from the current file (opened by unzOpenCurrentFile)
+ This is the local-header version of the extra field (sometimes, there is
+ more info in the local-header version than in the central-header)
+
+ if buf==NULL, it return the size of the local extra field
+
+ if buf!=NULL, len is the size of the buffer, the extra header is copied in
+ buf.
+ the return value is the number of bytes copied in buf, or (if <0)
+ the error code
+*/
+
+/***************************************************************************/
+
+/* Get the current file offset */
+extern ZPOS64_T ZEXPORT unzGetOffset64 (unzFile file);
+extern uLong ZEXPORT unzGetOffset (unzFile file);
+
+/* Set the current file offset */
+extern int ZEXPORT unzSetOffset64 (unzFile file, ZPOS64_T pos);
+extern int ZEXPORT unzSetOffset (unzFile file, uLong pos);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _unz64_H */
--- /dev/null
+/* zip.c -- IO on .zip files using zlib
+ Version 1.1, February 14h, 2010
+ part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Modifications for Zip64 support
+ Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+ For more info read MiniZip_info.txt
+
+ Changes
+ Oct-2009 - Mathias Svensson - Remove old C style function prototypes
+ Oct-2009 - Mathias Svensson - Added Zip64 Support when creating new file archives
+ Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get better overview of some functions.
+ Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data
+ It is used when recreting zip archive with RAW when deleting items from a zip.
+ ZIP64 data is automaticly added to items that needs it, and existing ZIP64 data need to be removed.
+ Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required)
+ Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
+
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "zlib.h"
+#include "zip.h"
+
+#ifdef STDC
+# include <stddef.h>
+# include <string.h>
+# include <stdlib.h>
+#endif
+#ifdef NO_ERRNO_H
+ extern int errno;
+#else
+# include <errno.h>
+#endif
+
+
+#ifndef local
+# define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+#ifndef VERSIONMADEBY
+# define VERSIONMADEBY (0x0) /* platform depedent */
+#endif
+
+#ifndef Z_BUFSIZE
+#define Z_BUFSIZE (64*1024) //(16384)
+#endif
+
+#ifndef Z_MAXFILENAMEINZIP
+#define Z_MAXFILENAMEINZIP (256)
+#endif
+
+#ifndef ALLOC
+# define ALLOC(size) (malloc(size))
+#endif
+#ifndef TRYFREE
+# define TRYFREE(p) {if (p) free(p);}
+#endif
+
+/*
+#define SIZECENTRALDIRITEM (0x2e)
+#define SIZEZIPLOCALHEADER (0x1e)
+*/
+
+/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
+
+
+// NOT sure that this work on ALL platform
+#define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32))
+
+#ifndef SEEK_CUR
+#define SEEK_CUR 1
+#endif
+
+#ifndef SEEK_END
+#define SEEK_END 2
+#endif
+
+#ifndef SEEK_SET
+#define SEEK_SET 0
+#endif
+
+#ifndef DEF_MEM_LEVEL
+#if MAX_MEM_LEVEL >= 8
+# define DEF_MEM_LEVEL 8
+#else
+# define DEF_MEM_LEVEL MAX_MEM_LEVEL
+#endif
+#endif
+const char zip_copyright[] =" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
+
+
+#define SIZEDATA_INDATABLOCK (4096-(4*4))
+
+#define LOCALHEADERMAGIC (0x04034b50)
+#define CENTRALHEADERMAGIC (0x02014b50)
+#define ENDHEADERMAGIC (0x06054b50)
+#define ZIP64ENDHEADERMAGIC (0x6064b50)
+#define ZIP64ENDLOCHEADERMAGIC (0x7064b50)
+
+#define FLAG_LOCALHEADER_OFFSET (0x06)
+#define CRC_LOCALHEADER_OFFSET (0x0e)
+
+#define SIZECENTRALHEADER (0x2e) /* 46 */
+
+typedef struct linkedlist_datablock_internal_s
+{
+ struct linkedlist_datablock_internal_s* next_datablock;
+ uLong avail_in_this_block;
+ uLong filled_in_this_block;
+ uLong unused; /* for future use and alignement */
+ unsigned char data[SIZEDATA_INDATABLOCK];
+} linkedlist_datablock_internal;
+
+typedef struct linkedlist_data_s
+{
+ linkedlist_datablock_internal* first_block;
+ linkedlist_datablock_internal* last_block;
+} linkedlist_data;
+
+
+typedef struct
+{
+ z_stream stream; /* zLib stream structure for inflate */
+#ifdef HAVE_BZIP2
+ bz_stream bstream; /* bzLib stream structure for bziped */
+#endif
+
+ int stream_initialised; /* 1 is stream is initialised */
+ uInt pos_in_buffered_data; /* last written byte in buffered_data */
+
+ ZPOS64_T pos_local_header; /* offset of the local header of the file
+ currenty writing */
+ char* central_header; /* central header data for the current file */
+ uLong size_centralExtra;
+ uLong size_centralheader; /* size of the central header for cur file */
+ uLong size_centralExtraFree; /* Extra bytes allocated to the centralheader but that are not used */
+ uLong flag; /* flag of the file currently writing */
+
+ int method; /* compression method of file currenty wr.*/
+ int raw; /* 1 for directly writing raw data */
+ Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/
+ uLong dosDate;
+ uLong crc32;
+ int encrypt;
+ int zip64; /* Add ZIP64 extened information in the extra field */
+ ZPOS64_T pos_zip64extrainfo;
+ ZPOS64_T totalCompressedData;
+ ZPOS64_T totalUncompressedData;
+#ifndef NOCRYPT
+ unsigned long keys[3]; /* keys defining the pseudo-random sequence */
+ const unsigned long* pcrc_32_tab;
+ int crypt_header_size;
+#endif
+} curfile64_info;
+
+typedef struct
+{
+ zlib_filefunc64_32_def z_filefunc;
+ voidpf filestream; /* io structore of the zipfile */
+ linkedlist_data central_dir;/* datablock with central dir in construction*/
+ int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/
+ curfile64_info ci; /* info on the file curretly writing */
+
+ ZPOS64_T begin_pos; /* position of the beginning of the zipfile */
+ ZPOS64_T add_position_when_writting_offset;
+ ZPOS64_T number_entry;
+
+#ifndef NO_ADDFILEINEXISTINGZIP
+ char *globalcomment;
+#endif
+
+} zip64_internal;
+
+
+#ifndef NOCRYPT
+#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED
+#include "crypt.h"
+#endif
+
+local linkedlist_datablock_internal* allocate_new_datablock()
+{
+ linkedlist_datablock_internal* ldi;
+ ldi = (linkedlist_datablock_internal*)
+ ALLOC(sizeof(linkedlist_datablock_internal));
+ if (ldi!=NULL)
+ {
+ ldi->next_datablock = NULL ;
+ ldi->filled_in_this_block = 0 ;
+ ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;
+ }
+ return ldi;
+}
+
+local void free_datablock(linkedlist_datablock_internal* ldi)
+{
+ while (ldi!=NULL)
+ {
+ linkedlist_datablock_internal* ldinext = ldi->next_datablock;
+ TRYFREE(ldi);
+ ldi = ldinext;
+ }
+}
+
+local void init_linkedlist(linkedlist_data* ll)
+{
+ ll->first_block = ll->last_block = NULL;
+}
+
+local void free_linkedlist(linkedlist_data* ll)
+{
+ free_datablock(ll->first_block);
+ ll->first_block = ll->last_block = NULL;
+}
+
+
+local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len)
+{
+ linkedlist_datablock_internal* ldi;
+ const unsigned char* from_copy;
+
+ if (ll==NULL)
+ return ZIP_INTERNALERROR;
+
+ if (ll->last_block == NULL)
+ {
+ ll->first_block = ll->last_block = allocate_new_datablock();
+ if (ll->first_block == NULL)
+ return ZIP_INTERNALERROR;
+ }
+
+ ldi = ll->last_block;
+ from_copy = (unsigned char*)buf;
+
+ while (len>0)
+ {
+ uInt copy_this;
+ uInt i;
+ unsigned char* to_copy;
+
+ if (ldi->avail_in_this_block==0)
+ {
+ ldi->next_datablock = allocate_new_datablock();
+ if (ldi->next_datablock == NULL)
+ return ZIP_INTERNALERROR;
+ ldi = ldi->next_datablock ;
+ ll->last_block = ldi;
+ }
+
+ if (ldi->avail_in_this_block < len)
+ copy_this = (uInt)ldi->avail_in_this_block;
+ else
+ copy_this = (uInt)len;
+
+ to_copy = &(ldi->data[ldi->filled_in_this_block]);
+
+ for (i=0;i<copy_this;i++)
+ *(to_copy+i)=*(from_copy+i);
+
+ ldi->filled_in_this_block += copy_this;
+ ldi->avail_in_this_block -= copy_this;
+ from_copy += copy_this ;
+ len -= copy_this;
+ }
+ return ZIP_OK;
+}
+
+
+
+/****************************************************************************/
+
+#ifndef NO_ADDFILEINEXISTINGZIP
+/* ===========================================================================
+ Inputs a long in LSB order to the given file
+ nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T)
+*/
+
+local int zip64local_putValue OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte));
+local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte)
+{
+ unsigned char buf[8];
+ int n;
+ for (n = 0; n < nbByte; n++)
+ {
+ buf[n] = (unsigned char)(x & 0xff);
+ x >>= 8;
+ }
+ if (x != 0)
+ { /* data overflow - hack for ZIP64 (X Roche) */
+ for (n = 0; n < nbByte; n++)
+ {
+ buf[n] = 0xff;
+ }
+ }
+
+ if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte)
+ return ZIP_ERRNO;
+ else
+ return ZIP_OK;
+}
+
+local void zip64local_putValue_inmemory OF((void* dest, ZPOS64_T x, int nbByte));
+local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte)
+{
+ unsigned char* buf=(unsigned char*)dest;
+ int n;
+ for (n = 0; n < nbByte; n++) {
+ buf[n] = (unsigned char)(x & 0xff);
+ x >>= 8;
+ }
+
+ if (x != 0)
+ { /* data overflow - hack for ZIP64 */
+ for (n = 0; n < nbByte; n++)
+ {
+ buf[n] = 0xff;
+ }
+ }
+}
+
+/****************************************************************************/
+
+
+local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm)
+{
+ uLong year = (uLong)ptm->tm_year;
+ if (year>=1980)
+ year-=1980;
+ else if (year>=80)
+ year-=80;
+ return
+ (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) |
+ ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));
+}
+
+
+/****************************************************************************/
+
+local int zip64local_getByte OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi));
+
+local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,voidpf filestream,int* pi)
+{
+ unsigned char c;
+ int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
+ if (err==1)
+ {
+ *pi = (int)c;
+ return ZIP_OK;
+ }
+ else
+ {
+ if (ZERROR64(*pzlib_filefunc_def,filestream))
+ return ZIP_ERRNO;
+ else
+ return ZIP_EOF;
+ }
+}
+
+
+/* ===========================================================================
+ Reads a long in LSB order from the given gz_stream. Sets
+*/
+local int zip64local_getShort OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));
+
+local int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)
+{
+ uLong x ;
+ int i = 0;
+ int err;
+
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x = (uLong)i;
+
+ if (err==ZIP_OK)
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x += ((uLong)i)<<8;
+
+ if (err==ZIP_OK)
+ *pX = x;
+ else
+ *pX = 0;
+ return err;
+}
+
+local int zip64local_getLong OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));
+
+local int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)
+{
+ uLong x ;
+ int i = 0;
+ int err;
+
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x = (uLong)i;
+
+ if (err==ZIP_OK)
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x += ((uLong)i)<<8;
+
+ if (err==ZIP_OK)
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x += ((uLong)i)<<16;
+
+ if (err==ZIP_OK)
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x += ((uLong)i)<<24;
+
+ if (err==ZIP_OK)
+ *pX = x;
+ else
+ *pX = 0;
+ return err;
+}
+
+local int zip64local_getLong64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX));
+
+
+local int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)
+{
+ ZPOS64_T x;
+ int i = 0;
+ int err;
+
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x = (ZPOS64_T)i;
+
+ if (err==ZIP_OK)
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x += ((ZPOS64_T)i)<<8;
+
+ if (err==ZIP_OK)
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x += ((ZPOS64_T)i)<<16;
+
+ if (err==ZIP_OK)
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x += ((ZPOS64_T)i)<<24;
+
+ if (err==ZIP_OK)
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x += ((ZPOS64_T)i)<<32;
+
+ if (err==ZIP_OK)
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x += ((ZPOS64_T)i)<<40;
+
+ if (err==ZIP_OK)
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x += ((ZPOS64_T)i)<<48;
+
+ if (err==ZIP_OK)
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x += ((ZPOS64_T)i)<<56;
+
+ if (err==ZIP_OK)
+ *pX = x;
+ else
+ *pX = 0;
+
+ return err;
+}
+
+#ifndef BUFREADCOMMENT
+#define BUFREADCOMMENT (0x400)
+#endif
+/*
+ Locate the Central directory of a zipfile (at the end, just before
+ the global comment)
+*/
+local ZPOS64_T zip64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
+
+local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
+{
+ unsigned char* buf;
+ ZPOS64_T uSizeFile;
+ ZPOS64_T uBackRead;
+ ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
+ ZPOS64_T uPosFound=0;
+
+ if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
+ return 0;
+
+
+ uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
+
+ if (uMaxBack>uSizeFile)
+ uMaxBack = uSizeFile;
+
+ buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
+ if (buf==NULL)
+ return 0;
+
+ uBackRead = 4;
+ while (uBackRead<uMaxBack)
+ {
+ uLong uReadSize;
+ ZPOS64_T uReadPos ;
+ int i;
+ if (uBackRead+BUFREADCOMMENT>uMaxBack)
+ uBackRead = uMaxBack;
+ else
+ uBackRead+=BUFREADCOMMENT;
+ uReadPos = uSizeFile-uBackRead ;
+
+ uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
+ (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
+ if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ break;
+
+ if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
+ break;
+
+ for (i=(int)uReadSize-3; (i--)>0;)
+ if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
+ ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
+ {
+ uPosFound = uReadPos+i;
+ break;
+ }
+
+ if (uPosFound!=0)
+ break;
+ }
+ TRYFREE(buf);
+ return uPosFound;
+}
+
+/*
+Locate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before
+the global comment)
+*/
+local ZPOS64_T zip64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
+
+local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
+{
+ unsigned char* buf;
+ ZPOS64_T uSizeFile;
+ ZPOS64_T uBackRead;
+ ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
+ ZPOS64_T uPosFound=0;
+ uLong uL;
+ ZPOS64_T relativeOffset;
+
+ if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
+ return 0;
+
+ uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
+
+ if (uMaxBack>uSizeFile)
+ uMaxBack = uSizeFile;
+
+ buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
+ if (buf==NULL)
+ return 0;
+
+ uBackRead = 4;
+ while (uBackRead<uMaxBack)
+ {
+ uLong uReadSize;
+ ZPOS64_T uReadPos;
+ int i;
+ if (uBackRead+BUFREADCOMMENT>uMaxBack)
+ uBackRead = uMaxBack;
+ else
+ uBackRead+=BUFREADCOMMENT;
+ uReadPos = uSizeFile-uBackRead ;
+
+ uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
+ (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
+ if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ break;
+
+ if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
+ break;
+
+ for (i=(int)uReadSize-3; (i--)>0;)
+ {
+ // Signature "0x07064b50" Zip64 end of central directory locater
+ if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
+ {
+ uPosFound = uReadPos+i;
+ break;
+ }
+ }
+
+ if (uPosFound!=0)
+ break;
+ }
+
+ TRYFREE(buf);
+ if (uPosFound == 0)
+ return 0;
+
+ /* Zip64 end of central directory locator */
+ if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ return 0;
+
+ /* the signature, already checked */
+ if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
+ return 0;
+
+ /* number of the disk with the start of the zip64 end of central directory */
+ if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
+ return 0;
+ if (uL != 0)
+ return 0;
+
+ /* relative offset of the zip64 end of central directory record */
+ if (zip64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=ZIP_OK)
+ return 0;
+
+ /* total number of disks */
+ if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
+ return 0;
+ if (uL != 1)
+ return 0;
+
+ /* Goto Zip64 end of central directory record */
+ if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ return 0;
+
+ /* the signature */
+ if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
+ return 0;
+
+ if (uL != 0x06064b50) // signature of 'Zip64 end of central directory'
+ return 0;
+
+ return relativeOffset;
+}
+
+int LoadCentralDirectoryRecord(zip64_internal* pziinit)
+{
+ int err=ZIP_OK;
+ ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
+
+ ZPOS64_T size_central_dir; /* size of the central directory */
+ ZPOS64_T offset_central_dir; /* offset of start of central directory */
+ ZPOS64_T central_pos;
+ uLong uL;
+
+ uLong number_disk; /* number of the current dist, used for
+ spaning ZIP, unsupported, always 0*/
+ uLong number_disk_with_CD; /* number the the disk with central dir, used
+ for spaning ZIP, unsupported, always 0*/
+ ZPOS64_T number_entry;
+ ZPOS64_T number_entry_CD; /* total number of entries in
+ the central dir
+ (same than number_entry on nospan) */
+ uLong VersionMadeBy;
+ uLong VersionNeeded;
+ uLong size_comment;
+
+ int hasZIP64Record = 0;
+
+ // check first if we find a ZIP64 record
+ central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream);
+ if(central_pos > 0)
+ {
+ hasZIP64Record = 1;
+ }
+ else if(central_pos == 0)
+ {
+ central_pos = zip64local_SearchCentralDir(&pziinit->z_filefunc,pziinit->filestream);
+ }
+
+/* disable to allow appending to empty ZIP archive
+ if (central_pos==0)
+ err=ZIP_ERRNO;
+*/
+
+ if(hasZIP64Record)
+ {
+ ZPOS64_T sizeEndOfCentralDirectory;
+ if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)
+ err=ZIP_ERRNO;
+
+ /* the signature, already checked */
+ if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)
+ err=ZIP_ERRNO;
+
+ /* size of zip64 end of central directory record */
+ if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &sizeEndOfCentralDirectory)!=ZIP_OK)
+ err=ZIP_ERRNO;
+
+ /* version made by */
+ if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionMadeBy)!=ZIP_OK)
+ err=ZIP_ERRNO;
+
+ /* version needed to extract */
+ if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionNeeded)!=ZIP_OK)
+ err=ZIP_ERRNO;
+
+ /* number of this disk */
+ if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)
+ err=ZIP_ERRNO;
+
+ /* number of the disk with the start of the central directory */
+ if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)
+ err=ZIP_ERRNO;
+
+ /* total number of entries in the central directory on this disk */
+ if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &number_entry)!=ZIP_OK)
+ err=ZIP_ERRNO;
+
+ /* total number of entries in the central directory */
+ if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&number_entry_CD)!=ZIP_OK)
+ err=ZIP_ERRNO;
+
+ if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))
+ err=ZIP_BADZIPFILE;
+
+ /* size of the central directory */
+ if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&size_central_dir)!=ZIP_OK)
+ err=ZIP_ERRNO;
+
+ /* offset of start of central directory with respect to the
+ starting disk number */
+ if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&offset_central_dir)!=ZIP_OK)
+ err=ZIP_ERRNO;
+
+ // TODO..
+ // read the comment from the standard central header.
+ size_comment = 0;
+ }
+ else
+ {
+ // Read End of central Directory info
+ if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ err=ZIP_ERRNO;
+
+ /* the signature, already checked */
+ if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)
+ err=ZIP_ERRNO;
+
+ /* number of this disk */
+ if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)
+ err=ZIP_ERRNO;
+
+ /* number of the disk with the start of the central directory */
+ if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)
+ err=ZIP_ERRNO;
+
+ /* total number of entries in the central dir on this disk */
+ number_entry = 0;
+ if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
+ err=ZIP_ERRNO;
+ else
+ number_entry = uL;
+
+ /* total number of entries in the central dir */
+ number_entry_CD = 0;
+ if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
+ err=ZIP_ERRNO;
+ else
+ number_entry_CD = uL;
+
+ if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))
+ err=ZIP_BADZIPFILE;
+
+ /* size of the central directory */
+ size_central_dir = 0;
+ if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
+ err=ZIP_ERRNO;
+ else
+ size_central_dir = uL;
+
+ /* offset of start of central directory with respect to the starting disk number */
+ offset_central_dir = 0;
+ if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
+ err=ZIP_ERRNO;
+ else
+ offset_central_dir = uL;
+
+
+ /* zipfile global comment length */
+ if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &size_comment)!=ZIP_OK)
+ err=ZIP_ERRNO;
+ }
+
+ if ((central_pos<offset_central_dir+size_central_dir) &&
+ (err==ZIP_OK))
+ err=ZIP_BADZIPFILE;
+
+ if (err!=ZIP_OK)
+ {
+ ZCLOSE64(pziinit->z_filefunc, pziinit->filestream);
+ return ZIP_ERRNO;
+ }
+
+ if (size_comment>0)
+ {
+ pziinit->globalcomment = (char*)ALLOC(size_comment+1);
+ if (pziinit->globalcomment)
+ {
+ size_comment = ZREAD64(pziinit->z_filefunc, pziinit->filestream, pziinit->globalcomment,size_comment);
+ pziinit->globalcomment[size_comment]=0;
+ }
+ }
+
+ byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir);
+ pziinit->add_position_when_writting_offset = byte_before_the_zipfile;
+
+ {
+ ZPOS64_T size_central_dir_to_read = size_central_dir;
+ size_t buf_size = SIZEDATA_INDATABLOCK;
+ void* buf_read = (void*)ALLOC(buf_size);
+ if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0)
+ err=ZIP_ERRNO;
+
+ while ((size_central_dir_to_read>0) && (err==ZIP_OK))
+ {
+ ZPOS64_T read_this = SIZEDATA_INDATABLOCK;
+ if (read_this > size_central_dir_to_read)
+ read_this = size_central_dir_to_read;
+
+ if (ZREAD64(pziinit->z_filefunc, pziinit->filestream,buf_read,(uLong)read_this) != read_this)
+ err=ZIP_ERRNO;
+
+ if (err==ZIP_OK)
+ err = add_data_in_datablock(&pziinit->central_dir,buf_read, (uLong)read_this);
+
+ size_central_dir_to_read-=read_this;
+ }
+ TRYFREE(buf_read);
+ }
+ pziinit->begin_pos = byte_before_the_zipfile;
+ pziinit->number_entry = number_entry_CD;
+
+ if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET) != 0)
+ err=ZIP_ERRNO;
+
+ return err;
+}
+
+
+#endif /* !NO_ADDFILEINEXISTINGZIP*/
+
+
+/************************************************************/
+extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def)
+{
+ zip64_internal ziinit;
+ zip64_internal* zi;
+ int err=ZIP_OK;
+
+ ziinit.z_filefunc.zseek32_file = NULL;
+ ziinit.z_filefunc.ztell32_file = NULL;
+ if (pzlib_filefunc64_32_def==NULL)
+ fill_fopen64_filefunc(&ziinit.z_filefunc.zfile_func64);
+ else
+ ziinit.z_filefunc = *pzlib_filefunc64_32_def;
+
+ ziinit.filestream = ZOPEN64(ziinit.z_filefunc,
+ pathname,
+ (append == APPEND_STATUS_CREATE) ?
+ (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) :
+ (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING));
+
+ if (ziinit.filestream == NULL)
+ return NULL;
+
+ if (append == APPEND_STATUS_CREATEAFTER)
+ ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END);
+
+ ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream);
+ ziinit.in_opened_file_inzip = 0;
+ ziinit.ci.stream_initialised = 0;
+ ziinit.number_entry = 0;
+ ziinit.add_position_when_writting_offset = 0;
+ init_linkedlist(&(ziinit.central_dir));
+
+
+
+ zi = (zip64_internal*)ALLOC(sizeof(zip64_internal));
+ if (zi==NULL)
+ {
+ ZCLOSE64(ziinit.z_filefunc,ziinit.filestream);
+ return NULL;
+ }
+
+ /* now we add file in a zipfile */
+# ifndef NO_ADDFILEINEXISTINGZIP
+ ziinit.globalcomment = NULL;
+ if (append == APPEND_STATUS_ADDINZIP)
+ {
+ // Read and Cache Central Directory Records
+ err = LoadCentralDirectoryRecord(&ziinit);
+ }
+
+ if (globalcomment)
+ {
+ *globalcomment = ziinit.globalcomment;
+ }
+# endif /* !NO_ADDFILEINEXISTINGZIP*/
+
+ if (err != ZIP_OK)
+ {
+# ifndef NO_ADDFILEINEXISTINGZIP
+ TRYFREE(ziinit.globalcomment);
+# endif /* !NO_ADDFILEINEXISTINGZIP*/
+ TRYFREE(zi);
+ return NULL;
+ }
+ else
+ {
+ *zi = ziinit;
+ return (zipFile)zi;
+ }
+}
+
+extern zipFile ZEXPORT zipOpen2 (const char *pathname, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def)
+{
+ if (pzlib_filefunc32_def != NULL)
+ {
+ zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
+ fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
+ return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill);
+ }
+ else
+ return zipOpen3(pathname, append, globalcomment, NULL);
+}
+
+extern zipFile ZEXPORT zipOpen2_64 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def)
+{
+ if (pzlib_filefunc_def != NULL)
+ {
+ zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
+ zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
+ zlib_filefunc64_32_def_fill.ztell32_file = NULL;
+ zlib_filefunc64_32_def_fill.zseek32_file = NULL;
+ return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill);
+ }
+ else
+ return zipOpen3(pathname, append, globalcomment, NULL);
+}
+
+
+
+extern zipFile ZEXPORT zipOpen (const char* pathname, int append)
+{
+ return zipOpen3((const void*)pathname,append,NULL,NULL);
+}
+
+extern zipFile ZEXPORT zipOpen64 (const void* pathname, int append)
+{
+ return zipOpen3(pathname,append,NULL,NULL);
+}
+
+int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local)
+{
+ /* write the local header */
+ int err;
+ uInt size_filename = (uInt)strlen(filename);
+ uInt size_extrafield = size_extrafield_local;
+
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC, 4);
+
+ if (err==ZIP_OK)
+ {
+ if(zi->ci.zip64)
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);/* version needed to extract */
+ else
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */
+ }
+
+ if (err==ZIP_OK)
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2);
+
+ if (err==ZIP_OK)
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2);
+
+ if (err==ZIP_OK)
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);
+
+ // CRC / Compressed size / Uncompressed size will be filled in later and rewritten later
+ if (err==ZIP_OK)
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */
+ if (err==ZIP_OK)
+ {
+ if(zi->ci.zip64)
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* compressed size, unknown */
+ else
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */
+ }
+ if (err==ZIP_OK)
+ {
+ if(zi->ci.zip64)
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* uncompressed size, unknown */
+ else
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */
+ }
+
+ if (err==ZIP_OK)
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2);
+
+ if(zi->ci.zip64)
+ {
+ size_extrafield += 20;
+ }
+
+ if (err==ZIP_OK)
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield,2);
+
+ if ((err==ZIP_OK) && (size_filename > 0))
+ {
+ if (ZWRITE64(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename)
+ err = ZIP_ERRNO;
+ }
+
+ if ((err==ZIP_OK) && (size_extrafield_local > 0))
+ {
+ if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local)
+ err = ZIP_ERRNO;
+ }
+
+
+ if ((err==ZIP_OK) && (zi->ci.zip64))
+ {
+ // write the Zip64 extended info
+ short HeaderID = 1;
+ short DataSize = 16;
+ ZPOS64_T CompressedSize = 0;
+ ZPOS64_T UncompressedSize = 0;
+
+ // Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file)
+ zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream);
+
+ err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)HeaderID,2);
+ err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)DataSize,2);
+
+ err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize,8);
+ err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize,8);
+ }
+
+ return err;
+}
+
+/*
+ NOTE.
+ When writing RAW the ZIP64 extended information in extrafield_local and extrafield_global needs to be stripped
+ before calling this function it can be done with zipRemoveExtraInfoBlock
+
+ It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize
+ unnecessary allocations.
+ */
+extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
+ const void* extrafield_local, uInt size_extrafield_local,
+ const void* extrafield_global, uInt size_extrafield_global,
+ const char* comment, int method, int level, int raw,
+ int windowBits,int memLevel, int strategy,
+ const char* password, uLong crcForCrypting,
+ uLong versionMadeBy, uLong flagBase, int zip64)
+{
+ zip64_internal* zi;
+ uInt size_filename;
+ uInt size_comment;
+ uInt i;
+ int err = ZIP_OK;
+
+# ifdef NOCRYPT
+ if (password != NULL)
+ return ZIP_PARAMERROR;
+# endif
+
+ if (file == NULL)
+ return ZIP_PARAMERROR;
+
+#ifdef HAVE_BZIP2
+ if ((method!=0) && (method!=Z_DEFLATED) && (method!=Z_BZIP2ED))
+ return ZIP_PARAMERROR;
+#else
+ if ((method!=0) && (method!=Z_DEFLATED))
+ return ZIP_PARAMERROR;
+#endif
+
+ zi = (zip64_internal*)file;
+
+ if (zi->in_opened_file_inzip == 1)
+ {
+ err = zipCloseFileInZip (file);
+ if (err != ZIP_OK)
+ return err;
+ }
+
+ if (filename==NULL)
+ filename="-";
+
+ if (comment==NULL)
+ size_comment = 0;
+ else
+ size_comment = (uInt)strlen(comment);
+
+ size_filename = (uInt)strlen(filename);
+
+ if (zipfi == NULL)
+ zi->ci.dosDate = 0;
+ else
+ {
+ if (zipfi->dosDate != 0)
+ zi->ci.dosDate = zipfi->dosDate;
+ else
+ zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date);
+ }
+
+ zi->ci.flag = flagBase;
+ if ((level==8) || (level==9))
+ zi->ci.flag |= 2;
+ if ((level==2))
+ zi->ci.flag |= 4;
+ if ((level==1))
+ zi->ci.flag |= 6;
+ if (password != NULL)
+ zi->ci.flag |= 1;
+
+ zi->ci.crc32 = 0;
+ zi->ci.method = method;
+ zi->ci.encrypt = 0;
+ zi->ci.stream_initialised = 0;
+ zi->ci.pos_in_buffered_data = 0;
+ zi->ci.raw = raw;
+ zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream);
+
+ zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment;
+ zi->ci.size_centralExtraFree = 32; // Extra space we have reserved in case we need to add ZIP64 extra info data
+
+ zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree);
+
+ zi->ci.size_centralExtra = size_extrafield_global;
+ zip64local_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
+ /* version info */
+ zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)versionMadeBy,2);
+ zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2);
+ zip64local_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
+ zip64local_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
+ zip64local_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
+ zip64local_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/
+ zip64local_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/
+ zip64local_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/
+ zip64local_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
+ zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
+ zip64local_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
+ zip64local_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/
+
+ if (zipfi==NULL)
+ zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);
+ else
+ zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);
+
+ if (zipfi==NULL)
+ zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);
+ else
+ zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);
+
+ if(zi->ci.pos_local_header >= 0xffffffff)
+ zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4);
+ else
+ zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writting_offset,4);
+
+ for (i=0;i<size_filename;i++)
+ *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
+
+ for (i=0;i<size_extrafield_global;i++)
+ *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =
+ *(((const char*)extrafield_global)+i);
+
+ for (i=0;i<size_comment;i++)
+ *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
+ size_extrafield_global+i) = *(comment+i);
+ if (zi->ci.central_header == NULL)
+ return ZIP_INTERNALERROR;
+
+ zi->ci.zip64 = zip64;
+ zi->ci.totalCompressedData = 0;
+ zi->ci.totalUncompressedData = 0;
+ zi->ci.pos_zip64extrainfo = 0;
+
+ err = Write_LocalFileHeader(zi, filename, size_extrafield_local, extrafield_local);
+
+#ifdef HAVE_BZIP2
+ zi->ci.bstream.avail_in = (uInt)0;
+ zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
+ zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
+ zi->ci.bstream.total_in_hi32 = 0;
+ zi->ci.bstream.total_in_lo32 = 0;
+ zi->ci.bstream.total_out_hi32 = 0;
+ zi->ci.bstream.total_out_lo32 = 0;
+#endif
+
+ zi->ci.stream.avail_in = (uInt)0;
+ zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
+ zi->ci.stream.next_out = zi->ci.buffered_data;
+ zi->ci.stream.total_in = 0;
+ zi->ci.stream.total_out = 0;
+ zi->ci.stream.data_type = Z_BINARY;
+
+#ifdef HAVE_BZIP2
+ if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED || zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
+#else
+ if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
+#endif
+ {
+ if(zi->ci.method == Z_DEFLATED)
+ {
+ zi->ci.stream.zalloc = (alloc_func)0;
+ zi->ci.stream.zfree = (free_func)0;
+ zi->ci.stream.opaque = (voidpf)0;
+
+ if (windowBits>0)
+ windowBits = -windowBits;
+
+ err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy);
+
+ if (err==Z_OK)
+ zi->ci.stream_initialised = Z_DEFLATED;
+ }
+ else if(zi->ci.method == Z_BZIP2ED)
+ {
+#ifdef HAVE_BZIP2
+ // Init BZip stuff here
+ zi->ci.bstream.bzalloc = 0;
+ zi->ci.bstream.bzfree = 0;
+ zi->ci.bstream.opaque = (voidpf)0;
+
+ err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0,35);
+ if(err == BZ_OK)
+ zi->ci.stream_initialised = Z_BZIP2ED;
+#endif
+ }
+
+ }
+
+# ifndef NOCRYPT
+ zi->ci.crypt_header_size = 0;
+ if ((err==Z_OK) && (password != NULL))
+ {
+ unsigned char bufHead[RAND_HEAD_LEN];
+ unsigned int sizeHead;
+ zi->ci.encrypt = 1;
+ zi->ci.pcrc_32_tab = get_crc_table();
+ /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
+
+ sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting);
+ zi->ci.crypt_header_size = sizeHead;
+
+ if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)
+ err = ZIP_ERRNO;
+ }
+# endif
+
+ if (err==Z_OK)
+ zi->in_opened_file_inzip = 1;
+ return err;
+}
+
+extern int ZEXPORT zipOpenNewFileInZip4 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
+ const void* extrafield_local, uInt size_extrafield_local,
+ const void* extrafield_global, uInt size_extrafield_global,
+ const char* comment, int method, int level, int raw,
+ int windowBits,int memLevel, int strategy,
+ const char* password, uLong crcForCrypting,
+ uLong versionMadeBy, uLong flagBase)
+{
+ return zipOpenNewFileInZip4_64 (file, filename, zipfi,
+ extrafield_local, size_extrafield_local,
+ extrafield_global, size_extrafield_global,
+ comment, method, level, raw,
+ windowBits, memLevel, strategy,
+ password, crcForCrypting, versionMadeBy, flagBase, 0);
+}
+
+extern int ZEXPORT zipOpenNewFileInZip3 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
+ const void* extrafield_local, uInt size_extrafield_local,
+ const void* extrafield_global, uInt size_extrafield_global,
+ const char* comment, int method, int level, int raw,
+ int windowBits,int memLevel, int strategy,
+ const char* password, uLong crcForCrypting)
+{
+ return zipOpenNewFileInZip4_64 (file, filename, zipfi,
+ extrafield_local, size_extrafield_local,
+ extrafield_global, size_extrafield_global,
+ comment, method, level, raw,
+ windowBits, memLevel, strategy,
+ password, crcForCrypting, VERSIONMADEBY, 0, 0);
+}
+
+extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
+ const void* extrafield_local, uInt size_extrafield_local,
+ const void* extrafield_global, uInt size_extrafield_global,
+ const char* comment, int method, int level, int raw,
+ int windowBits,int memLevel, int strategy,
+ const char* password, uLong crcForCrypting, int zip64)
+{
+ return zipOpenNewFileInZip4_64 (file, filename, zipfi,
+ extrafield_local, size_extrafield_local,
+ extrafield_global, size_extrafield_global,
+ comment, method, level, raw,
+ windowBits, memLevel, strategy,
+ password, crcForCrypting, VERSIONMADEBY, 0, zip64);
+}
+
+extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi,
+ const void* extrafield_local, uInt size_extrafield_local,
+ const void* extrafield_global, uInt size_extrafield_global,
+ const char* comment, int method, int level, int raw)
+{
+ return zipOpenNewFileInZip4_64 (file, filename, zipfi,
+ extrafield_local, size_extrafield_local,
+ extrafield_global, size_extrafield_global,
+ comment, method, level, raw,
+ -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
+ NULL, 0, VERSIONMADEBY, 0, 0);
+}
+
+extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
+ const void* extrafield_local, uInt size_extrafield_local,
+ const void* extrafield_global, uInt size_extrafield_global,
+ const char* comment, int method, int level, int raw, int zip64)
+{
+ return zipOpenNewFileInZip4_64 (file, filename, zipfi,
+ extrafield_local, size_extrafield_local,
+ extrafield_global, size_extrafield_global,
+ comment, method, level, raw,
+ -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
+ NULL, 0, VERSIONMADEBY, 0, zip64);
+}
+
+extern int ZEXPORT zipOpenNewFileInZip64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
+ const void* extrafield_local, uInt size_extrafield_local,
+ const void*extrafield_global, uInt size_extrafield_global,
+ const char* comment, int method, int level, int zip64)
+{
+ return zipOpenNewFileInZip4_64 (file, filename, zipfi,
+ extrafield_local, size_extrafield_local,
+ extrafield_global, size_extrafield_global,
+ comment, method, level, 0,
+ -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
+ NULL, 0, VERSIONMADEBY, 0, zip64);
+}
+
+extern int ZEXPORT zipOpenNewFileInZip (zipFile file, const char* filename, const zip_fileinfo* zipfi,
+ const void* extrafield_local, uInt size_extrafield_local,
+ const void*extrafield_global, uInt size_extrafield_global,
+ const char* comment, int method, int level)
+{
+ return zipOpenNewFileInZip4_64 (file, filename, zipfi,
+ extrafield_local, size_extrafield_local,
+ extrafield_global, size_extrafield_global,
+ comment, method, level, 0,
+ -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
+ NULL, 0, VERSIONMADEBY, 0, 0);
+}
+
+local int zip64FlushWriteBuffer(zip64_internal* zi)
+{
+ int err=ZIP_OK;
+
+ if (zi->ci.encrypt != 0)
+ {
+#ifndef NOCRYPT
+ uInt i;
+ int t;
+ for (i=0;i<zi->ci.pos_in_buffered_data;i++)
+ zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t);
+#endif
+ }
+
+ if (ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data)
+ err = ZIP_ERRNO;
+
+ zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data;
+
+#ifdef HAVE_BZIP2
+ if(zi->ci.method == Z_BZIP2ED)
+ {
+ zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32;
+ zi->ci.bstream.total_in_lo32 = 0;
+ zi->ci.bstream.total_in_hi32 = 0;
+ }
+ else
+#endif
+ {
+ zi->ci.totalUncompressedData += zi->ci.stream.total_in;
+ zi->ci.stream.total_in = 0;
+ }
+
+
+ zi->ci.pos_in_buffered_data = 0;
+
+ return err;
+}
+
+extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned int len)
+{
+ zip64_internal* zi;
+ int err=ZIP_OK;
+
+ if (file == NULL)
+ return ZIP_PARAMERROR;
+ zi = (zip64_internal*)file;
+
+ if (zi->in_opened_file_inzip == 0)
+ return ZIP_PARAMERROR;
+
+ zi->ci.crc32 = crc32(zi->ci.crc32,buf,(uInt)len);
+
+#ifdef HAVE_BZIP2
+ if(zi->ci.method == Z_BZIP2ED && (!zi->ci.raw))
+ {
+ zi->ci.bstream.next_in = (void*)buf;
+ zi->ci.bstream.avail_in = len;
+ err = BZ_RUN_OK;
+
+ while ((err==BZ_RUN_OK) && (zi->ci.bstream.avail_in>0))
+ {
+ if (zi->ci.bstream.avail_out == 0)
+ {
+ if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
+ err = ZIP_ERRNO;
+ zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
+ zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
+ }
+
+
+ if(err != BZ_RUN_OK)
+ break;
+
+ if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
+ {
+ uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32;
+// uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32;
+ err=BZ2_bzCompress(&zi->ci.bstream, BZ_RUN);
+
+ zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ;
+ }
+ }
+
+ if(err == BZ_RUN_OK)
+ err = ZIP_OK;
+ }
+ else
+#endif
+ {
+ zi->ci.stream.next_in = (Bytef*)buf;
+ zi->ci.stream.avail_in = len;
+
+ while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
+ {
+ if (zi->ci.stream.avail_out == 0)
+ {
+ if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
+ err = ZIP_ERRNO;
+ zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
+ zi->ci.stream.next_out = zi->ci.buffered_data;
+ }
+
+
+ if(err != ZIP_OK)
+ break;
+
+ if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
+ {
+ uLong uTotalOutBefore = zi->ci.stream.total_out;
+ err=deflate(&zi->ci.stream, Z_NO_FLUSH);
+ if(uTotalOutBefore > zi->ci.stream.total_out)
+ {
+ int bBreak = 0;
+ bBreak++;
+ }
+
+ zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
+ }
+ else
+ {
+ uInt copy_this,i;
+ if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
+ copy_this = zi->ci.stream.avail_in;
+ else
+ copy_this = zi->ci.stream.avail_out;
+
+ for (i = 0; i < copy_this; i++)
+ *(((char*)zi->ci.stream.next_out)+i) =
+ *(((const char*)zi->ci.stream.next_in)+i);
+ {
+ zi->ci.stream.avail_in -= copy_this;
+ zi->ci.stream.avail_out-= copy_this;
+ zi->ci.stream.next_in+= copy_this;
+ zi->ci.stream.next_out+= copy_this;
+ zi->ci.stream.total_in+= copy_this;
+ zi->ci.stream.total_out+= copy_this;
+ zi->ci.pos_in_buffered_data += copy_this;
+ }
+ }
+ }// while(...)
+ }
+
+ return err;
+}
+
+extern int ZEXPORT zipCloseFileInZipRaw (zipFile file, uLong uncompressed_size, uLong crc32)
+{
+ return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32);
+}
+
+extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_size, uLong crc32)
+{
+ zip64_internal* zi;
+ ZPOS64_T compressed_size;
+ uLong invalidValue = 0xffffffff;
+ short datasize = 0;
+ int err=ZIP_OK;
+
+ if (file == NULL)
+ return ZIP_PARAMERROR;
+ zi = (zip64_internal*)file;
+
+ if (zi->in_opened_file_inzip == 0)
+ return ZIP_PARAMERROR;
+ zi->ci.stream.avail_in = 0;
+
+ if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
+ {
+ while (err==ZIP_OK)
+ {
+ uLong uTotalOutBefore;
+ if (zi->ci.stream.avail_out == 0)
+ {
+ if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
+ err = ZIP_ERRNO;
+ zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
+ zi->ci.stream.next_out = zi->ci.buffered_data;
+ }
+ uTotalOutBefore = zi->ci.stream.total_out;
+ err=deflate(&zi->ci.stream, Z_FINISH);
+ zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
+ }
+ }
+ else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
+ {
+#ifdef HAVE_BZIP2
+ err = BZ_FINISH_OK;
+ while (err==BZ_FINISH_OK)
+ {
+ uLong uTotalOutBefore;
+ if (zi->ci.bstream.avail_out == 0)
+ {
+ if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
+ err = ZIP_ERRNO;
+ zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
+ zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
+ }
+ uTotalOutBefore = zi->ci.bstream.total_out_lo32;
+ err=BZ2_bzCompress(&zi->ci.bstream, BZ_FINISH);
+ if(err == BZ_STREAM_END)
+ err = Z_STREAM_END;
+
+ zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore);
+ }
+
+ if(err == BZ_FINISH_OK)
+ err = ZIP_OK;
+#endif
+ }
+
+ if (err==Z_STREAM_END)
+ err=ZIP_OK; /* this is normal */
+
+ if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
+ {
+ if (zip64FlushWriteBuffer(zi)==ZIP_ERRNO)
+ err = ZIP_ERRNO;
+ }
+
+ if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
+ {
+ int tmp_err = deflateEnd(&zi->ci.stream);
+ if (err == ZIP_OK)
+ err = tmp_err;
+ zi->ci.stream_initialised = 0;
+ }
+#ifdef HAVE_BZIP2
+ else if((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
+ {
+ int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream);
+ if (err==ZIP_OK)
+ err = tmperr;
+ zi->ci.stream_initialised = 0;
+ }
+#endif
+
+ if (!zi->ci.raw)
+ {
+ crc32 = (uLong)zi->ci.crc32;
+ uncompressed_size = zi->ci.totalUncompressedData;
+ }
+ compressed_size = zi->ci.totalCompressedData;
+
+# ifndef NOCRYPT
+ compressed_size += zi->ci.crypt_header_size;
+# endif
+
+ // update Current Item crc and sizes,
+ if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff)
+ {
+ /*version Made by*/
+ zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)45,2);
+ /*version needed*/
+ zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)45,2);
+
+ }
+
+ zip64local_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/
+
+
+ if(compressed_size >= 0xffffffff)
+ zip64local_putValue_inmemory(zi->ci.central_header+20, invalidValue,4); /*compr size*/
+ else
+ zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/
+
+ /// set internal file attributes field
+ if (zi->ci.stream.data_type == Z_ASCII)
+ zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);
+
+ if(uncompressed_size >= 0xffffffff)
+ zip64local_putValue_inmemory(zi->ci.central_header+24, invalidValue,4); /*uncompr size*/
+ else
+ zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/
+
+ // Add ZIP64 extra info field for uncompressed size
+ if(uncompressed_size >= 0xffffffff)
+ datasize += 8;
+
+ // Add ZIP64 extra info field for compressed size
+ if(compressed_size >= 0xffffffff)
+ datasize += 8;
+
+ // Add ZIP64 extra info field for relative offset to local file header of current file
+ if(zi->ci.pos_local_header >= 0xffffffff)
+ datasize += 8;
+
+ if(datasize > 0)
+ {
+ char* p = NULL;
+
+ if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree)
+ {
+ // we can not write more data to the buffer that we have room for.
+ return ZIP_BADZIPFILE;
+ }
+
+ p = zi->ci.central_header + zi->ci.size_centralheader;
+
+ // Add Extra Information Header for 'ZIP64 information'
+ zip64local_putValue_inmemory(p, 0x0001, 2); // HeaderID
+ p += 2;
+ zip64local_putValue_inmemory(p, datasize, 2); // DataSize
+ p += 2;
+
+ if(uncompressed_size >= 0xffffffff)
+ {
+ zip64local_putValue_inmemory(p, uncompressed_size, 8);
+ p += 8;
+ }
+
+ if(compressed_size >= 0xffffffff)
+ {
+ zip64local_putValue_inmemory(p, compressed_size, 8);
+ p += 8;
+ }
+
+ if(zi->ci.pos_local_header >= 0xffffffff)
+ {
+ zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8);
+ p += 8;
+ }
+
+ // Update how much extra free space we got in the memory buffer
+ // and increase the centralheader size so the new ZIP64 fields are included
+ // ( 4 below is the size of HeaderID and DataSize field )
+ zi->ci.size_centralExtraFree -= datasize + 4;
+ zi->ci.size_centralheader += datasize + 4;
+
+ // Update the extra info size field
+ zi->ci.size_centralExtra += datasize + 4;
+ zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2);
+ }
+
+ if (err==ZIP_OK)
+ err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader);
+
+ free(zi->ci.central_header);
+
+ if (err==ZIP_OK)
+ {
+ // Update the LocalFileHeader with the new values.
+
+ ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
+
+ if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ err = ZIP_ERRNO;
+
+ if (err==ZIP_OK)
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
+
+ if(uncompressed_size >= 0xffffffff)
+ {
+ if(zi->ci.pos_zip64extrainfo > 0)
+ {
+ // Update the size in the ZIP64 extended field.
+ if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ err = ZIP_ERRNO;
+
+ if (err==ZIP_OK) /* compressed size, unknown */
+ err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8);
+
+ if (err==ZIP_OK) /* uncompressed size, unknown */
+ err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8);
+ }
+ }
+ else
+ {
+ if (err==ZIP_OK) /* compressed size, unknown */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
+
+ if (err==ZIP_OK) /* uncompressed size, unknown */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
+ }
+
+ if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ err = ZIP_ERRNO;
+ }
+
+ zi->number_entry ++;
+ zi->in_opened_file_inzip = 0;
+
+ return err;
+}
+
+extern int ZEXPORT zipCloseFileInZip (zipFile file)
+{
+ return zipCloseFileInZipRaw (file,0,0);
+}
+
+int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip)
+{
+ int err = ZIP_OK;
+ ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writting_offset;
+
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEADERMAGIC,4);
+
+ /*num disks*/
+ if (err==ZIP_OK) /* number of the disk with the start of the central directory */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
+
+ /*relative offset*/
+ if (err==ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream, pos,8);
+
+ /*total disks*/ /* Do not support spawning of disk so always say 1 here*/
+ if (err==ZIP_OK) /* number of the disk with the start of the central directory */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)1,4);
+
+ return err;
+}
+
+int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
+{
+ int err = ZIP_OK;
+
+ uLong Zip64DataSize = 44;
+
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDHEADERMAGIC,4);
+
+ if (err==ZIP_OK) /* size of this 'zip64 end of central directory' */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); // why ZPOS64_T of this ?
+
+ if (err==ZIP_OK) /* version made by */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);
+
+ if (err==ZIP_OK) /* version needed */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);
+
+ if (err==ZIP_OK) /* number of this disk */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
+
+ if (err==ZIP_OK) /* number of the disk with the start of the central directory */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
+
+ if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
+ err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
+
+ if (err==ZIP_OK) /* total number of entries in the central dir */
+ err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
+
+ if (err==ZIP_OK) /* size of the central directory */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)size_centraldir,8);
+
+ if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
+ {
+ ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8);
+ }
+ return err;
+}
+int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
+{
+ int err = ZIP_OK;
+
+ /*signature*/
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4);
+
+ if (err==ZIP_OK) /* number of this disk */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
+
+ if (err==ZIP_OK) /* number of the disk with the start of the central directory */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
+
+ if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
+ {
+ {
+ if(zi->number_entry >= 0xFFFF)
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record
+ else
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
+ }
+ }
+
+ if (err==ZIP_OK) /* total number of entries in the central dir */
+ {
+ if(zi->number_entry >= 0xFFFF)
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record
+ else
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
+ }
+
+ if (err==ZIP_OK) /* size of the central directory */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4);
+
+ if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
+ {
+ ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
+ if(pos >= 0xffffffff)
+ {
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4);
+ }
+ else
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4);
+ }
+
+ return err;
+}
+
+int Write_GlobalComment(zip64_internal* zi, const char* global_comment)
+{
+ int err = ZIP_OK;
+ uInt size_global_comment = 0;
+
+ if(global_comment != NULL)
+ size_global_comment = (uInt)strlen(global_comment);
+
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2);
+
+ if (err == ZIP_OK && size_global_comment > 0)
+ {
+ if (ZWRITE64(zi->z_filefunc,zi->filestream, global_comment, size_global_comment) != size_global_comment)
+ err = ZIP_ERRNO;
+ }
+ return err;
+}
+
+extern int ZEXPORT zipClose (zipFile file, const char* global_comment)
+{
+ zip64_internal* zi;
+ int err = 0;
+ uLong size_centraldir = 0;
+ ZPOS64_T centraldir_pos_inzip;
+ ZPOS64_T pos;
+
+ if (file == NULL)
+ return ZIP_PARAMERROR;
+
+ zi = (zip64_internal*)file;
+
+ if (zi->in_opened_file_inzip == 1)
+ {
+ err = zipCloseFileInZip (file);
+ }
+
+#ifndef NO_ADDFILEINEXISTINGZIP
+ if (global_comment==NULL)
+ global_comment = zi->globalcomment;
+#endif
+
+ centraldir_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
+
+ if (err==ZIP_OK)
+ {
+ linkedlist_datablock_internal* ldi = zi->central_dir.first_block;
+ while (ldi!=NULL)
+ {
+ if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))
+ {
+ if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->filled_in_this_block) != ldi->filled_in_this_block)
+ err = ZIP_ERRNO;
+ }
+
+ size_centraldir += ldi->filled_in_this_block;
+ ldi = ldi->next_datablock;
+ }
+ }
+ free_linkedlist(&(zi->central_dir));
+
+ pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
+ if(pos >= 0xffffffff)
+ {
+ ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream);
+ Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
+
+ Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos);
+ }
+
+ if (err==ZIP_OK)
+ err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
+
+ if(err == ZIP_OK)
+ err = Write_GlobalComment(zi, global_comment);
+
+ if (ZCLOSE64(zi->z_filefunc,zi->filestream) != 0)
+ if (err == ZIP_OK)
+ err = ZIP_ERRNO;
+
+#ifndef NO_ADDFILEINEXISTINGZIP
+ TRYFREE(zi->globalcomment);
+#endif
+ TRYFREE(zi);
+
+ return err;
+}
+
+extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHeader)
+{
+ char* p = pData;
+ int size = 0;
+ char* pNewHeader;
+ char* pTmp;
+ short header;
+ short dataSize;
+
+ int retVal = ZIP_OK;
+
+ if(pData == NULL || *dataLen < 4)
+ return ZIP_PARAMERROR;
+
+ pNewHeader = (char*)ALLOC(*dataLen);
+ pTmp = pNewHeader;
+
+ while(p < (pData + *dataLen))
+ {
+ header = *(short*)p;
+ dataSize = *(((short*)p)+1);
+
+ if( header == sHeader ) // Header found.
+ {
+ p += dataSize + 4; // skip it. do not copy to temp buffer
+ }
+ else
+ {
+ // Extra Info block should not be removed, So copy it to the temp buffer.
+ memcpy(pTmp, p, dataSize + 4);
+ p += dataSize + 4;
+ size += dataSize + 4;
+ }
+
+ }
+
+ if(size < *dataLen)
+ {
+ // clean old extra info block.
+ memset(pData,0, *dataLen);
+
+ // copy the new extra info block over the old
+ if(size > 0)
+ memcpy(pData, pNewHeader, size);
+
+ // set the new extra info size
+ *dataLen = size;
+
+ retVal = ZIP_OK;
+ }
+ else
+ retVal = ZIP_ERRNO;
+
+ TRYFREE(pNewHeader);
+
+ return retVal;
+}
--- /dev/null
+/* zip.h -- IO on .zip files using zlib
+ Version 1.1, February 14h, 2010
+ part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Modifications for Zip64 support
+ Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+ For more info read MiniZip_info.txt
+
+ ---------------------------------------------------------------------------
+
+ Condition of use and distribution are the same than zlib :
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ ---------------------------------------------------------------------------
+
+ Changes
+
+ See header of zip.h
+
+*/
+
+#ifndef _zip12_H
+#define _zip12_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//#define HAVE_BZIP2
+
+#ifndef _ZLIB_H
+#include "zlib.h"
+#endif
+
+#ifndef _ZLIBIOAPI_H
+#include "ioapi.h"
+#endif
+
+#ifdef HAVE_BZIP2
+#include "bzlib.h"
+#endif
+
+#define Z_BZIP2ED 12
+
+#if defined(STRICTZIP) || defined(STRICTZIPUNZIP)
+/* like the STRICT of WIN32, we define a pointer that cannot be converted
+ from (void*) without cast */
+typedef struct TagzipFile__ { int unused; } zipFile__;
+typedef zipFile__ *zipFile;
+#else
+typedef voidp zipFile;
+#endif
+
+#define ZIP_OK (0)
+#define ZIP_EOF (0)
+#define ZIP_ERRNO (Z_ERRNO)
+#define ZIP_PARAMERROR (-102)
+#define ZIP_BADZIPFILE (-103)
+#define ZIP_INTERNALERROR (-104)
+
+#ifndef DEF_MEM_LEVEL
+# if MAX_MEM_LEVEL >= 8
+# define DEF_MEM_LEVEL 8
+# else
+# define DEF_MEM_LEVEL MAX_MEM_LEVEL
+# endif
+#endif
+/* default memLevel */
+
+/* tm_zip contain date/time info */
+typedef struct tm_zip_s
+{
+ uInt tm_sec; /* seconds after the minute - [0,59] */
+ uInt tm_min; /* minutes after the hour - [0,59] */
+ uInt tm_hour; /* hours since midnight - [0,23] */
+ uInt tm_mday; /* day of the month - [1,31] */
+ uInt tm_mon; /* months since January - [0,11] */
+ uInt tm_year; /* years - [1980..2044] */
+} tm_zip;
+
+typedef struct
+{
+ tm_zip tmz_date; /* date in understandable format */
+ uLong dosDate; /* if dos_date == 0, tmu_date is used */
+/* uLong flag; */ /* general purpose bit flag 2 bytes */
+
+ uLong internal_fa; /* internal file attributes 2 bytes */
+ uLong external_fa; /* external file attributes 4 bytes */
+} zip_fileinfo;
+
+typedef const char* zipcharpc;
+
+
+#define APPEND_STATUS_CREATE (0)
+#define APPEND_STATUS_CREATEAFTER (1)
+#define APPEND_STATUS_ADDINZIP (2)
+
+extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append));
+extern zipFile ZEXPORT zipOpen64 OF((const void *pathname, int append));
+/*
+ Create a zipfile.
+ pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on
+ an Unix computer "zlib/zlib113.zip".
+ if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip
+ will be created at the end of the file.
+ (useful if the file contain a self extractor code)
+ if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will
+ add files in existing zip (be sure you don't add file that doesn't exist)
+ If the zipfile cannot be opened, the return value is NULL.
+ Else, the return value is a zipFile Handle, usable with other function
+ of this zip package.
+*/
+
+/* Note : there is no delete function into a zipfile.
+ If you want delete file into a zipfile, you must open a zipfile, and create another
+ Of couse, you can use RAW reading and writing to copy the file you did not want delte
+*/
+
+extern zipFile ZEXPORT zipOpen2 OF((const char *pathname,
+ int append,
+ zipcharpc* globalcomment,
+ zlib_filefunc_def* pzlib_filefunc_def));
+
+extern zipFile ZEXPORT zipOpen2_64 OF((const void *pathname,
+ int append,
+ zipcharpc* globalcomment,
+ zlib_filefunc64_def* pzlib_filefunc_def));
+
+extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file,
+ const char* filename,
+ const zip_fileinfo* zipfi,
+ const void* extrafield_local,
+ uInt size_extrafield_local,
+ const void* extrafield_global,
+ uInt size_extrafield_global,
+ const char* comment,
+ int method,
+ int level));
+
+extern int ZEXPORT zipOpenNewFileInZip64 OF((zipFile file,
+ const char* filename,
+ const zip_fileinfo* zipfi,
+ const void* extrafield_local,
+ uInt size_extrafield_local,
+ const void* extrafield_global,
+ uInt size_extrafield_global,
+ const char* comment,
+ int method,
+ int level,
+ int zip64));
+
+/*
+ Open a file in the ZIP for writing.
+ filename : the filename in zip (if NULL, '-' without quote will be used
+ *zipfi contain supplemental information
+ if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local
+ contains the extrafield data the the local header
+ if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global
+ contains the extrafield data the the local header
+ if comment != NULL, comment contain the comment string
+ method contain the compression method (0 for store, Z_DEFLATED for deflate)
+ level contain the level of compression (can be Z_DEFAULT_COMPRESSION)
+ zip64 is set to 1 if a zip64 extended information block should be added to the local file header.
+ this MUST be '1' if the uncompressed size is >= 0xffffffff.
+
+*/
+
+
+extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file,
+ const char* filename,
+ const zip_fileinfo* zipfi,
+ const void* extrafield_local,
+ uInt size_extrafield_local,
+ const void* extrafield_global,
+ uInt size_extrafield_global,
+ const char* comment,
+ int method,
+ int level,
+ int raw));
+
+
+extern int ZEXPORT zipOpenNewFileInZip2_64 OF((zipFile file,
+ const char* filename,
+ const zip_fileinfo* zipfi,
+ const void* extrafield_local,
+ uInt size_extrafield_local,
+ const void* extrafield_global,
+ uInt size_extrafield_global,
+ const char* comment,
+ int method,
+ int level,
+ int raw,
+ int zip64));
+/*
+ Same than zipOpenNewFileInZip, except if raw=1, we write raw file
+ */
+
+extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file,
+ const char* filename,
+ const zip_fileinfo* zipfi,
+ const void* extrafield_local,
+ uInt size_extrafield_local,
+ const void* extrafield_global,
+ uInt size_extrafield_global,
+ const char* comment,
+ int method,
+ int level,
+ int raw,
+ int windowBits,
+ int memLevel,
+ int strategy,
+ const char* password,
+ uLong crcForCrypting));
+
+extern int ZEXPORT zipOpenNewFileInZip3_64 OF((zipFile file,
+ const char* filename,
+ const zip_fileinfo* zipfi,
+ const void* extrafield_local,
+ uInt size_extrafield_local,
+ const void* extrafield_global,
+ uInt size_extrafield_global,
+ const char* comment,
+ int method,
+ int level,
+ int raw,
+ int windowBits,
+ int memLevel,
+ int strategy,
+ const char* password,
+ uLong crcForCrypting,
+ int zip64
+ ));
+
+/*
+ Same than zipOpenNewFileInZip2, except
+ windowBits,memLevel,,strategy : see parameter strategy in deflateInit2
+ password : crypting password (NULL for no crypting)
+ crcForCrypting : crc of file to compress (needed for crypting)
+ */
+
+extern int ZEXPORT zipOpenNewFileInZip4 OF((zipFile file,
+ const char* filename,
+ const zip_fileinfo* zipfi,
+ const void* extrafield_local,
+ uInt size_extrafield_local,
+ const void* extrafield_global,
+ uInt size_extrafield_global,
+ const char* comment,
+ int method,
+ int level,
+ int raw,
+ int windowBits,
+ int memLevel,
+ int strategy,
+ const char* password,
+ uLong crcForCrypting,
+ uLong versionMadeBy,
+ uLong flagBase
+ ));
+
+
+extern int ZEXPORT zipOpenNewFileInZip4_64 OF((zipFile file,
+ const char* filename,
+ const zip_fileinfo* zipfi,
+ const void* extrafield_local,
+ uInt size_extrafield_local,
+ const void* extrafield_global,
+ uInt size_extrafield_global,
+ const char* comment,
+ int method,
+ int level,
+ int raw,
+ int windowBits,
+ int memLevel,
+ int strategy,
+ const char* password,
+ uLong crcForCrypting,
+ uLong versionMadeBy,
+ uLong flagBase,
+ int zip64
+ ));
+/*
+ Same than zipOpenNewFileInZip4, except
+ versionMadeBy : value for Version made by field
+ flag : value for flag field (compression level info will be added)
+ */
+
+
+extern int ZEXPORT zipWriteInFileInZip OF((zipFile file,
+ const void* buf,
+ unsigned len));
+/*
+ Write data in the zipfile
+*/
+
+extern int ZEXPORT zipCloseFileInZip OF((zipFile file));
+/*
+ Close the current file in the zipfile
+*/
+
+extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file,
+ uLong uncompressed_size,
+ uLong crc32));
+
+extern int ZEXPORT zipCloseFileInZipRaw64 OF((zipFile file,
+ ZPOS64_T uncompressed_size,
+ uLong crc32));
+
+/*
+ Close the current file in the zipfile, for file opened with
+ parameter raw=1 in zipOpenNewFileInZip2
+ uncompressed_size and crc32 are value for the uncompressed size
+*/
+
+extern int ZEXPORT zipClose OF((zipFile file,
+ const char* global_comment));
+/*
+ Close the zipfile
+*/
+
+
+extern int ZEXPORT zipRemoveExtraInfoBlock OF((char* pData, int* dataLen, short sHeader));
+/*
+ zipRemoveExtraInfoBlock - Added by Mathias Svensson
+
+ Remove extra information block from a extra information data for the local file header or central directory header
+
+ It is needed to remove ZIP64 extra information blocks when before data is written if using RAW mode.
+
+ 0x0001 is the signature header for the ZIP64 extra information blocks
+
+ usage.
+ Remove ZIP64 Extra information from a central director extra field data
+ zipRemoveExtraInfoBlock(pCenDirExtraFieldData, &nCenDirExtraFieldDataLen, 0x0001);
+
+ Remove ZIP64 Extra information from a Local File Header extra field data
+ zipRemoveExtraInfoBlock(pLocalHeaderExtraFieldData, &nLocalHeaderExtraFieldDataLen, 0x0001);
+*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _zip64_H */
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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)
+
+#
+# Logs
+#
+
+
+OPTION(DPL_LOG "DPL logs status" OFF)
+
+IF(DPL_LOG)
+ MESSAGE(STATUS "Logging enabled for DPL")
+ ADD_DEFINITIONS("-DDPL_LOGS_ENABLED")
+ELSE(DPL_LOG)
+ MESSAGE(STATUS "Logging disabled for DPL")
+ENDIF(DPL_LOG)
+ADD_DEFINITIONS("-DSEPARATED_SINGLETON_IMPLEMENTATION")
+
+# Gtk
+OPTION(DISABLE_GTK "Disable GTK stuff" ON)
+
+#
+# Build type
+#
+
+SET(CMAKE_BUILD_TYPE "Release")
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
+SET(CMAKE_CXX_FLAGS "-O2 -g -fPIC -D_FORTIFY_SOURCE=0")
+
+#
+# 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 "========================================")
+
+#
+# Build 3rd party libraries first
+#
+ADD_SUBDIRECTORY(3rdparty)
+
+#
+# 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 DPL 3rd party include directory
+SET(DPL_3RDPARTY_INCLUDE_DIR
+ ${PROJECT_SOURCE_DIR}/3rdparty)
+
+# 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_DPL_POPUP "lib${PROJECT_NAME}-popup-efl")
+SET(TARGET_WRT_DAO_RW_LIB "dpl-wrt-dao-rw")
+SET(TARGET_WRT_DAO_RO_LIB "dpl-wrt-dao-ro")
+SET(TARGET_DPL_UTILS_EFL "lib${PROJECT_NAME}-utils-efl")
+SET(TARGET_ACE_DAO_RO_LIB "dpl-ace-dao-ro")
+SET(TARGET_ACE_DAO_RW_LIB "dpl-ace-dao-rw")
+SET(TARGET_ACE_LIB "dpl-ace")
+SET(TARGET_VCORE_LIB "dpl-vcore")
+
+ADD_SUBDIRECTORY(modules)
+
+ADD_SUBDIRECTORY(build)
+ADD_SUBDIRECTORY(tests)
+ADD_SUBDIRECTORY(etc)
+
--- /dev/null
+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.
--- /dev/null
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
\ No newline at end of file
--- /dev/null
+#!/bin/sh
+
+./dpl-tests-core --output=text
+./dpl-tests-dbus --output=text
+./dpl-tests-db --output=text
+./dpl-tests-event --output=text
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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(vcore)
+ADD_SUBDIRECTORY(ace)
+ADD_SUBDIRECTORY(widget_dao)
+ADD_SUBDIRECTORY(popup)
+ADD_SUBDIRECTORY(utils)
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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_FILE(dpl-ace-dao-ro.pc.in dpl-ace-dao-ro.pc @ONLY)
+CONFIGURE_FILE(dpl-ace-dao-rw.pc.in dpl-ace-dao-rw.pc @ONLY)
+CONFIGURE_FILE(dpl-ace.pc.in dpl-ace.pc @ONLY)
+INSTALL(FILES
+ ${CMAKE_BINARY_DIR}/build/ace/dpl-ace-dao-ro.pc
+ ${CMAKE_BINARY_DIR}/build/ace/dpl-ace-dao-rw.pc
+ ${CMAKE_BINARY_DIR}/build/ace/dpl-ace.pc
+ DESTINATION
+ lib/pkgconfig
+ )
+
--- /dev/null
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${prefix}/lib
+includedir=${prefix}/include/dpl-efl
+
+Name: dpl-ace-dao-ro
+Description: dpl-ace-dao-ro
+Version: @VERSION@
+Requires: dpl-efl openssl
+Libs: -ldpl-ace-dao-ro -L${libdir}
+Cflags: -I${includedir}
--- /dev/null
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${prefix}/lib
+includedir=${prefix}/include/dpl-elf
+
+Name: dpl-aco-dao-rw
+Description: dpl-ace-dao-rw
+Version: @VERSION@
+Requires: dpl-ace-dao-ro
+Libs: -ldpl-ace-dao-rw -L${libdir}
+Cflags: -I${includedir}
--- /dev/null
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${prefix}/lib
+includedir=${prefix}/include/dpl-efl
+
+Name: dpl-ace
+Description: dpl-ace
+Version: @VERSION@
+Requires: dpl-efl openssl
+Libs: -ldpl-ace -L${libdir}
+Cflags: -I${includedir}
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# @file CMakeLists.txt
+# @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+# @version 1.0
+# @brief
+#
+
+# Check required modules
+INCLUDE(FindPkgConfig)
+PKG_CHECK_MODULES(SYS_EFL
+ ecore
+ appcore-efl
+ openssl
+ dlog
+ vconf
+ libpcrecpp
+ icu-uc
+ REQUIRED)
+
+# Add core include directories
+INCLUDE_DIRECTORIES(
+ ${DPL_LOG_INCLUDE_DIR}
+ ${DPL_CORE_INCLUDE_DIR}
+ ${DPL_3RDPARTY_INCLUDE_DIR}
+ ${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")
+
+# Link with 3rd party libraries
+LINK_DIRECTORIES(${PROJECT_SOURCE_DIR}/3rdparty)
+
+TARGET_LINK_LIBRARIES(${TARGET_DPL_EFL} lib3rdparty)
+
+# Target library properties
+SET_TARGET_PROPERTIES(${TARGET_DPL_EFL} PROPERTIES
+ SOVERSION ${VERSION}
+ CLEAN_DIRECT_OUTPUT 1
+ OUTPUT_NAME ${DPL_EFL_LIBRARY})
+
+# Install libraries
+INSTALL(TARGETS ${TARGET_DPL_EFL}
+ DESTINATION lib
+ PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
+
+# 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 3rdparty headers
+INSTALL(FILES ${DPL_3RDPARTY_HEADERS}
+ DESTINATION include/dpl-efl/dpl/3rdparty/fastdelegate)
+
+# Install pkgconfig script
+INSTALL(FILES dpl-efl.pc
+ DESTINATION lib/pkgconfig)
--- /dev/null
+!!!options!!! stop
+EFL support
--- /dev/null
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${prefix}/lib
+includedir=${prefix}/include
+
+Name: dpl-efl
+Description: DPL - EFL based
+Version: 1.0.0
+Requires: ecore appcore-efl openssl dlog vconf
+Libs: -L${libdir} -ldpl-efl
+Cflags: -I${includedir}/dpl-efl
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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}
+ ${SYS_EFL_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 ${VERSION}
+ CLEAN_DIRECT_OUTPUT 1
+ OUTPUT_NAME ${DPL_EFL_DB_LIBRARY})
+
+# Install libraries
+INSTALL(TARGETS ${TARGET_DPL_DB_EFL}
+ DESTINATION lib
+ PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
+
+# Install detail headers
+INSTALL(FILES ${DPL_DB_HEADERS}
+ DESTINATION include/dpl-efl/dpl/db)
+
+# Install pkgconfig script
+INSTALL(FILES dpl-db-efl.pc
+ DESTINATION lib/pkgconfig)
--- /dev/null
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${prefix}/lib
+includedir=${prefix}/include
+
+Name: dpl-db-efl
+Description: DPL DB - EFL based
+Version: 1.0.0
+Requires: dpl-efl sqlite3 db-util
+Libs: -L${libdir} -ldpl-db-efl
+Cflags: -I${includedir}/dpl-efl
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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
+ REQUIRED)
+
+# Add core include directories
+INCLUDE_DIRECTORIES(
+ ${DPL_LOG_INCLUDE_DIR}
+ ${DPL_CORE_INCLUDE_DIR}
+ ${DPL_DBUS_INCLUDE_DIR}
+ ${DPL_EVENT_INCLUDE_DIR}
+ ${SYS_EFL_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 ${VERSION}
+ CLEAN_DIRECT_OUTPUT 1
+ OUTPUT_NAME ${DPL_EFL_DBUS_LIBRARY})
+
+# Install libraries
+INSTALL(TARGETS ${TARGET_DPL_DBUS_EFL}
+ DESTINATION lib
+ PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
+
+# Install detail headers
+INSTALL(FILES ${DPL_DBUS_HEADERS}
+ DESTINATION include/dpl-efl/dpl/dbus)
+
+# Install pkgconfig script
+INSTALL(FILES dpl-dbus-efl.pc
+ DESTINATION lib/pkgconfig)
--- /dev/null
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${prefix}/lib
+includedir=${prefix}/include
+
+Name: dpl-dbus-efl
+Description: DPL DBus - EFL based
+Version: 1.0.0
+Requires: dbus-1 dpl-efl dpl-event-efl
+Libs: -L${libdir} -ldpl-dbus-efl
+Cflags: -I${includedir}/dpl-efl
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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
+ heynoti
+ REQUIRED
+)
+
+# Add core include directories
+INCLUDE_DIRECTORIES(
+ ${DPL_LOG_INCLUDE_DIR}
+ ${DPL_CORE_INCLUDE_DIR}
+ ${DPL_EVENT_INCLUDE_DIR}
+ ${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 ${VERSION}
+ CLEAN_DIRECT_OUTPUT 1
+ OUTPUT_NAME ${DPL_EFL_EVENT_LIBRARY})
+
+# Install libraries
+INSTALL(TARGETS ${TARGET_DPL_EVENT_EFL}
+ DESTINATION lib
+ PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
+
+# Install detail headers
+INSTALL(FILES ${DPL_EVENT_HEADERS}
+ DESTINATION include/dpl-efl/dpl/event)
+
+# Install pkgconfig script
+INSTALL(FILES dpl-event-efl.pc
+ DESTINATION lib/pkgconfig)
--- /dev/null
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${prefix}/lib
+includedir=${prefix}/include
+
+Name: dpl-event-efl
+Description: DPL Event - EFL based
+Version: 1.0.0
+Requires: dpl-efl ecore appcore-efl vconf heynoti
+Libs: -L${libdir} -ldpl-event-efl
+Cflags: -I${includedir}/dpl-efl
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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}
+ ${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 ${VERSION}
+ CLEAN_DIRECT_OUTPUT 1
+ OUTPUT_NAME ${DPL_EFL_LOG_LIBRARY})
+
+# Install libraries
+INSTALL(TARGETS ${TARGET_DPL_LOG_EFL}
+ DESTINATION lib
+ PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
+
+INSTALL(FILES ${DPL_LOG_HEADERS}
+ DESTINATION include/dpl-efl/dpl/log)
+
+# Install pkgconfig script
+INSTALL(FILES dpl-log-efl.pc
+ DESTINATION lib/pkgconfig)
--- /dev/null
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${prefix}/lib
+includedir=${prefix}/include
+
+Name: dpl-log-efl
+Description: DPL Log Engine - EFL based
+Version: 1.0.0
+Requires: dpl-efl dlog
+Libs: -L${libdir} -ldpl-log-efl
+Cflags: -I${includedir}/dpl-efl
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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
+#
+
+# Check required modules
+INCLUDE(FindPkgConfig)
+PKG_CHECK_MODULES(SYS_POPUP
+ elementary
+ REQUIRED)
+
+# Add core include directories
+INCLUDE_DIRECTORIES(
+ ${DPL_LOG_INCLUDE_DIR}
+ ${DPL_CORE_INCLUDE_DIR}
+ ${DPL_POPUP_INCLUDE_DIR}
+ ${DPL_EVENT_INCLUDE_DIR}
+ ${SYS_EFL_INCLUDE_DIRS})
+
+LINK_DIRECTORIES(
+ ${SYS_POPUP_LIBRARY_DIRS}
+)
+
+# Base EFL based DPL library
+SET(DPL_POPUP_LIBRARY "${PROJECT_NAME}-popup-efl")
+
+# Build shared library
+
+ADD_LIBRARY(${TARGET_DPL_POPUP} SHARED ${DPL_POPUP_SOURCES})
+
+TARGET_LINK_LIBRARIES(${TARGET_DPL_POPUP}
+ ${SYS_POPUP_LIBRARIES}
+ ${TARGET_DPL_EFL}
+)
+
+# Target library properties
+SET_TARGET_PROPERTIES(${TARGET_DPL_POPUP} PROPERTIES
+ SOVERSION ${VERSION}
+ CLEAN_DIRECT_OUTPUT 1
+ OUTPUT_NAME ${DPL_POPUP_LIBRARY})
+
+# Install libraries
+INSTALL(TARGETS ${TARGET_DPL_POPUP}
+ DESTINATION lib
+ PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
+
+# Install detail headers
+INSTALL(FILES ${DPL_POPUP_HEADERS}
+ DESTINATION include/dpl-efl/dpl/popup)
+
+# Install pkgconfig script
+INSTALL(FILES dpl-popup-efl.pc
+ DESTINATION lib/pkgconfig)
--- /dev/null
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${prefix}/lib
+includedir=${prefix}/include
+
+Name: dpl-popup-efl
+Description: DPL Popup functionality - EFL based
+Version: 1.0.0
+Requires: dpl-efl
+Libs: -L${libdir} -ldpl-popup-efl
+Cflags: -I${includedir}/dpl-efl
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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}
+ ${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 ${VERSION}
+ CLEAN_DIRECT_OUTPUT 1
+ OUTPUT_NAME ${DPL_EFL_RPC_LIBRARY})
+
+# Install libraries
+INSTALL(TARGETS ${TARGET_DPL_RPC_EFL}
+ DESTINATION lib
+ PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
+
+# Install detail headers
+INSTALL(FILES ${DPL_RPC_HEADERS}
+ DESTINATION include/dpl-efl/dpl/rpc)
+
+# Install pkgconfig script
+INSTALL(FILES dpl-rpc-efl.pc
+ DESTINATION lib/pkgconfig)
--- /dev/null
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${prefix}/lib
+includedir=${prefix}/include
+
+Name: dpl-rpc-efl
+Description: DPL RPC - EFL based
+Version: 1.0.0
+Requires: dpl-efl dpl-event-efl dpl-socket-efl
+Libs: -L${libdir} -ldpl-rpc-efl
+Cflags: -I${includedir}/dpl-efl
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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}
+ ${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 ${VERSION}
+ CLEAN_DIRECT_OUTPUT 1
+ OUTPUT_NAME ${DPL_EFL_SOCKET_LIBRARY})
+
+# Install libraries
+INSTALL(TARGETS ${TARGET_DPL_SOCKET_EFL}
+ DESTINATION lib
+ PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
+
+# Install detail headers
+INSTALL(FILES ${DPL_SOCKET_HEADERS}
+ DESTINATION include/dpl-efl/dpl/socket)
+
+# Install pkgconfig script
+INSTALL(FILES dpl-socket-efl.pc
+ DESTINATION lib/pkgconfig)
--- /dev/null
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${prefix}/lib
+includedir=${prefix}/include
+
+Name: dpl-socket-efl
+Description: DPL Socket - EFL based
+Version: 1.0.0
+Requires: dpl-efl dpl-event-efl
+Libs: -L${libdir} -ldpl-socket-efl
+Cflags: -I${includedir}/dpl-efl
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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
+ REQUIRED)
+
+
+# Add core include directories
+INCLUDE_DIRECTORIES(
+ ${DPL_LOG_INCLUDE_DIR}
+ ${DPL_CORE_INCLUDE_DIR}
+ ${DPL_TEST_ENGINE_INCLUDE_DIR}
+ ${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 library properties
+SET_TARGET_PROPERTIES(${TARGET_DPL_TEST_ENGINE_EFL} PROPERTIES
+ SOVERSION ${VERSION}
+ CLEAN_DIRECT_OUTPUT 1
+ OUTPUT_NAME ${DPL_EFL_TEST_ENGINE_LIBRARY})
+
+# Install libraries
+INSTALL(TARGETS ${TARGET_DPL_TEST_ENGINE_EFL}
+ DESTINATION lib
+ PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
+
+# Install detail headers
+INSTALL(FILES ${DPL_TEST_ENGINE_HEADERS}
+ DESTINATION include/dpl-efl/dpl/test)
+
+# Install pkgconfig script
+INSTALL(FILES dpl-test-efl.pc
+ DESTINATION lib/pkgconfig)
--- /dev/null
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${prefix}/lib
+includedir=${prefix}/include
+
+Name: dpl-test-efl
+Description: DPL Test Engine - EFL based
+Version: 1.0.0
+Requires: dpl-efl
+Libs: -L${libdir} -ldpl-test-efl
+Cflags: -I${includedir}/dpl-efl
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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}
+ ${SYS_EFL_UTILS_INCLUDE_DIRS}
+ ${DPL_UTILS_INCLUDE_DIR}
+ ${DPL_LOCALIZATION_INCLUDE_DIR}
+)
+
+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 ${VERSION}
+ CLEAN_DIRECT_OUTPUT 1
+ OUTPUT_NAME ${DPL_EFL_UTILS_LIBRARY})
+
+# Install libraries
+INSTALL(TARGETS ${TARGET_DPL_UTILS_EFL}
+ DESTINATION lib
+ PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
+
+# 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
+INSTALL(FILES dpl-utils-efl.pc
+ DESTINATION lib/pkgconfig)
--- /dev/null
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${prefix}/lib
+includedir=${prefix}/include
+
+Name: dpl-utils-efl
+Description: DPL UTILS - EFL based
+Version: 1.0.0
+Requires: dpl-efl
+Libs: -L${libdir} -ldpl-utils-efl
+Cflags: -I${includedir}/dpl-efl
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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_FILE(dpl-vcore.pc.in dpl-vcore.pc @ONLY)
+INSTALL(FILES ${CMAKE_BINARY_DIR}/build/vcore/dpl-vcore.pc DESTINATION lib/pkgconfig)
--- /dev/null
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${prefix}/lib
+includedir=${prefix}/include/dpl-efl/dpl/vcore
+
+Name: dpl-vcore
+Description: dpl-vcore
+Version: @VERSION@
+Requires: libxml-2.0 openssl libsoup-2.4
+Libs: -ldpl-vcore -L${libdir}
+Cflags: -I${includedir}
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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_FILE(dpl-wrt-dao-ro.pc.in dpl-wrt-dao-ro.pc @ONLY)
+CONFIGURE_FILE(dpl-wrt-dao-rw.pc.in dpl-wrt-dao-rw.pc @ONLY)
+INSTALL(FILES
+ ${CMAKE_BINARY_DIR}/build/widget_dao/dpl-wrt-dao-ro.pc
+ ${CMAKE_BINARY_DIR}/build/widget_dao/dpl-wrt-dao-rw.pc
+ DESTINATION
+ lib/pkgconfig)
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+Debian folder (rules, control etc.)
--- /dev/null
+dpl for Debian
+--------------
+
+<possible notes regarding this package - if none, delete this file>
+
+ -- unknown <pdobrowolski@unknown> Tue, 23 Mar 2010 11:40:32 +0100
--- /dev/null
+wrt-commons (0.2.18) unstable; urgency=low
+
+ * Boilerplate update
+
+ * Git : tizen2/pkgs/w/wrt-commons
+ * Tag : wrt-commons_0.2.18
+
+ -- Tae-Jeong Lee <taejeong.lee@samsung.com> Thu, 23 Feb 2012 16:12:49 +0900
+
+wrt-commons (0.2.17) unstable; urgency=low
+
+ * debianize
+
+ * Git : tizen2/pkgs/w/wrt-commons
+ * Tag : wrt-commons_0.2.17
+
+ -- Yunchan Cho <yunchan.cho@samsung.com> Wed, 22 Feb 2012 16:57:31 +0900
+
+wrt-commons (0.2.16) unstable; urgency=low
+
+ * Init changelog
+
+ * Git : tizen2/pkgs/w/wrt-commons
+ * Tag : wrt-commons_0.2.16
+
+ -- Pawel Sikorski <p.sikorski@samsung.com> Mon, 13 Feb 2012 16:04:58 +0100
--- /dev/null
+Source: wrt-commons
+Section: devel
+Priority: extra
+Maintainer: Lukasz Wrzosek<l.wrzosek@samsung.com>, Taejeong.lee <taejeong.lee@samsung.com>
+Standards-Version: 3.7.2
+Uploaders: Yunchan Cho <yunchan.cho@samsung.com>,Przemyslaw Dobrowolski <p.dobrowolsk@samsung.com>, Pawel Sikorski <p.sikorski@samsung.com>, Zbigniew Kostrzewa <z.kostrzewa@samsung.com>
+Build-Depends: debhelper (>= 5), libecore-dev, libslp-setting-dev (>=0.2.5-2), libheynoti-dev, libappcore-efl-dev, libssl-dev, libsqlite3-dev, dlog-dev (>= 0.2.14-0), libglib2.0-dev, libslp-db-util-dev (>= 0.1.0-23), zlib1g-dev, libpcre-dev, libicu-dev, libxmlsec1-dev, openssl, libxml2-dev, libsoup2.4-dev, libcert-svc-dev, libiri-dev, libidn11-dev, libslp-tapi-dev
+# If you want to build version of gtk, comment out above one live and use the following one line
+#Build-Depends: debhelper (>= 5), libecore-dev, libslp-setting-dev (>=0.2.5-2), libheynoti-dev, libappcore-efl-dev, libssl-dev, libsqlite3-dev, dlog-dev (>= 0.2.14-0), libglib2.0-dev, libslp-db-util-dev (>= 0.1.0-23), libgtk2.0-dev, zlib1g-dev, libpcre-dev, libicu-dev
+
+Package: wrt-commons
+Section: libs
+Provides: dpl-efl
+Conflicts: dpl-efl
+Replaces: dpl-efl
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Description: Design patterns library - EFL based
+ Design patterns library is a collection of useful C++ utilities
+ to easily develop window applications.
+
+# If you want to build version of gtk, comment out the following lines
+#Package: dpl-gtk
+#Section: libs
+#Architecture: any
+#Depends: ${shlibs:Depends}, ${misc:Depends}
+#Description: Design patterns library - GTK based
+# Design patterns library is a collection of useful C++ utilities
+# to easily develop window applications.
+
+Package: wrt-commons-dev
+XB-Public-Package: no
+Section: devel
+Provides: dpl-efl-dev
+Conflicts: dpl-efl-dev
+Replaces: dpl-efl-dev
+Architecture: any
+Depends: wrt-commons (= ${Source-Version}), libecore-dev, libslp-setting-dev (>=0.2.5-2), libheynoti-dev, libappcore-efl-dev, libssl-dev, libsqlite3-dev, dlog-dev (>= 0.2.14-0), libslp-db-util-dev (>= 0.1.0-23), zlib1g-dev, libpcre-dev
+Description: Design patterns library - EFL based developer files
+ Design patterns library is a collection of useful C++ utilities
+ to easily develop window applications. The most important part of
+ library is full MVC support. It also supports event-based architecture,
+ adds wrappers for many packages and provides many basic C++ utilities
+ as RAII objects, singletons, and many other.
+
+# If you want to build version of gtk, comment out the following lines
+#Package: dpl-gtk-dev
+#XB-Public-Package: no
+#Section: devel
+#Architecture: any
+#Depends: dpl-gtk (= ${Source-Version}), libglib2.0-dev, libgtk2.0-dev, libssl-dev, libsqlite3-dev, dlog-dev (>= 0.2.14-0), libslp-db-util-dev (>= 0.1.0-23), zlib1g-dev, libpcre-dev
+#Description: Design patterns library - GTK based developer files
+# Design patterns library is a collection of useful C++ utilities
+# to easily develop window applications. The most important part of
+# library is full MVC support. It also supports event-based architecture,
+# adds wrappers for many packages and provides many basic C++ utilities
+# as RAII objects, singletons, and many other.
+
+#Package: wrt-commons-test
+#Section: libs
+#Provides: dpl-test
+#Conflicts: dpl-test
+#Replaces: dpl-test
+#Architecture: any
+#Depends: wrt-commons (= ${Source-Version})
+#Description: Test programs.
+
+Package: wrt-commons-dbg
+Section: debug
+Provides: dpl-dbg
+Conflicts: dpl-dbg
+Replaces: dpl-dbg
+Architecture: any
+Depends: wrt-commons (= ${Source-Version})
+# If you want to build version of gtk, comment out above one live and use the following one line
+#Depends: wrt-commons (= ${Source-Version}), dpl-gtk (= ${Source-Version})
+Description: Design patterns library - Debug files
+ Design patterns library is a collection of useful C++ utilities
+ to easily develop window applications. The most important part of
+ library is full MVC support. It also supports event-based architecture,
+ adds wrappers for many packages and provides many basic C++ utilities
+ as RAII objects, singletons, and many other.
+
--- /dev/null
+#!/usr/bin/make -f
+
+#export DH_VERBOSE=1
+PACKAGE_VERSION ?= $(shell sed -n "1 p" debian/changelog | sed 's/.*([0-9]*.\([0-9]*\).*).*/\1/')
+CFLAGS = -Wall -g
+LDFLAGS = -Wl,--as-needed -Wl,--hash-style=both
+
+ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
+ CFLAGS += -O0
+else
+ CFLAGS += -O2
+endif
+
+ifneq (,$(findstring yes,$(DPL_LOG)))
+ DPL_LOGS_STATUS = "ON"
+else
+ DPL_LOGS_STATUS = "OFF"
+endif
+
+BUILD_DIR = cmake-build
+
+configure: configure-stamp
+configure-stamp:
+ dh_testdir
+ rm -rf $(BUILD_DIR)
+ mkdir $(BUILD_DIR)
+ ( cd $(BUILD_DIR); cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DDPL_LOG=$(DPL_LOGS_STATUS) -DVERSION=${PACKAGE_VERSION}; )
+ touch configure-stamp
+
+build: build-stamp
+build-stamp: configure-stamp
+ dh_testdir
+ ( cd $(BUILD_DIR); $(MAKE) -j 4 )
+ touch $@
+
+clean:
+ dh_testdir
+ dh_testroot
+ rm -f build-stamp configure-stamp
+ rm -rf $(BUILD_DIR)
+ dh_clean
+
+install: build
+ dh_testdir
+ dh_testroot
+ dh_clean -k
+ dh_installdirs
+ ( cd $(BUILD_DIR); $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install )
+ cd ..
+
+binary-indep: build install
+
+binary-arch: build install
+ dh_testdir
+ dh_testroot
+ dh_installchangelogs
+ dh_installdocs
+ dh_installexamples
+ dh_install --sourcedir=debian/tmp
+# dh_installmenu
+# dh_installdebconf
+# dh_installlogrotate
+# dh_installemacsen
+# dh_installpam
+# dh_installmime
+# dh_installinit
+# dh_installcron
+# dh_installinfo
+ dh_installman
+ dh_link
+ dh_strip --dbg-package=wrt-commons-dbg
+ dh_compress
+ dh_fixperms
+# dh_perl
+# dh_python
+ dh_makeshlibs
+ dh_installdeb
+ dh_shlibdeps
+ dh_gencontrol
+ dh_md5sums
+ dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install configure
--- /dev/null
+usr/include
+usr/include/dpl-efl
+usr/include/dpl-efl/dpl
+usr/include/dpl-efl/dpl/3rdparty
+usr/include/dpl-efl/dpl/3rdparty/fastdelegate
--- /dev/null
+usr/include/dpl-efl/*
+usr/lib/pkgconfig/*.pc
--- /dev/null
+/usr/bin/dpl-test*
+/usr/bin/dpl-dbus-test-service
+/usr/etc/ace/policy*
+/usr/etc/ace/attr*
+/usr/etc/ace/general*
+/usr/etc/ace/undefined*
+/usr/etc/ace/CMTest/*
+/opt/apps/widget/tests/vcore_widget_uncompressed/*
+/opt/apps/widget/tests/vcore_keys/*
+/opt/apps/widget/tests/vcore_certs/*
+/opt/apps/wrt/wrt-commons/tests/*
+/usr/share/dbus-1/services/org.tizen.DBusTestService.service
+/opt/apps/widget/tests/localization/*
--- /dev/null
+usr/lib/*.so*
+/usr/share/wrt-engine/*
+/usr/bin/wrt_reset_db.sh
+/usr/bin/wrt_create_clean_db.sh
+/usr/etc/ace/config*
+/usr/etc/ace/bondixml*
+/usr/etc/ace/demo.*
+/usr/etc/ace/WACPolicy.xml
+/usr/etc/ace/UnrestrictedPolicy.xml
+/opt/share/cert-svc/certs/code-signing/wac/*
--- /dev/null
+#!/bin/sh
+
+if [ -z ${2} ]; then
+ echo "This is new install of wrt-commons"
+ echo "Calling /usr/bin/wrt_reset_db.sh"
+ /usr/bin/wrt_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_`
+ ACE_OLD_DB_VERSION=`sqlite3 /opt/dbspace/.ace.db ".tables" | grep "DB_VERSION_"`
+ ACE_NEW_DB_VERSION=`cat /usr/share/wrt-engine/ace_db.sql | tr '[:blank:]' '\n' | grep DB_VERSION_`
+ VCORE_OLD_DB_VERSION=`sqlite3 /opt/dbspace/.vcore.db ".tables" | grep "DB_VERSION_"`
+ VCORE_NEW_DB_VERSION=`cat /usr/share/wrt-engine/vcore_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}"
+ echo "OLD ace database version ${ACE_OLD_DB_VERSION}"
+ echo "NEW ace database version ${ACE_NEW_DB_VERSION}"
+ echo "OLD vcore database version ${VCORE_OLD_DB_VERSION}"
+ echo "NEW vcore database version ${VCORE_NEW_DB_VERSION}"
+
+
+ if [ ${WRT_OLD_DB_VERSION} -a ${WRT_NEW_DB_VERSION} -a ${ACE_OLD_DB_VERSION} -a ${ACE_NEW_DB_VERSION} -a ${VCORE_OLD_DB_VERSION} -a ${VCORE_NEW_DB_VERSION} ]
+ then
+ if [ ${WRT_NEW_DB_VERSION} = ${WRT_OLD_DB_VERSION} -a ${ACE_NEW_DB_VERSION} = ${ACE_OLD_DB_VERSION} -a ${VCORE_OLD_DB_VERSION} = ${VCORE_NEW_DB_VERSION} ]
+ then
+ echo "Equal database detected so db installation ignored"
+ else
+ echo "Calling /usr/bin/wrt_reset_db.sh"
+ /usr/bin/wrt_reset_db.sh
+ fi
+ else
+ echo "Calling /usr/bin/wrt_reset_db.sh"
+ /usr/bin/wrt_reset_db.sh
+ fi
+fi
+
+mkdir -p /usr/etc/ace
+mkdir -p /usr/apps/org.tizen.policy
+
+# 3. configurations
+chown root:root /usr/etc/ace/config.xml
+
+# DBUS services fix
+# WARNING: THIS IS TEMPORARY SOLUTION, AS THIS SHOULD NOT BE OUR
+# RESPONSIBILITY!!! WE HAVE TO CONTACT TO DBUS MAINAINERS
+
+if [ -f /var/lib/dbus/machine-id ]; then
+ echo "machine-id exists"
+else
+ if [ -f /usr/var/lib/dbus/machine-id ]; then
+ echo "machine-id exists"
+ else
+ echo "Creating machine-id"
+ mkdir -p /usr/var/lib/dbus/
+ dbus-uuidgen > /usr/var/lib/dbus/machine-id
+ dbus-uuidgen --ensure=/usr/var/lib/dbus/machine-id
+ fi
+ mkdir -p /var/lib/dbus/
+ cp /usr/var/lib/dbus/machine-id /var/lib/dbus/
+fi
+
+echo "[WRT] wrt-commons postinst done ..."
--- /dev/null
+#!/usr/bin/env python
+
+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)
+
--- /dev/null
+Documentation
--- /dev/null
+# 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
--- /dev/null
+
+SET(ETC_DIR ${PROJECT_SOURCE_DIR}/etc)
+
+INSTALL(FILES
+ ${ETC_DIR}/wrt_reset_db.sh
+ ${ETC_DIR}/wrt_create_clean_db.sh
+ DESTINATION /usr/bin
+ )
+
+INSTALL(FILES
+ ${ETC_DIR}/schema.xsd
+ DESTINATION share/wrt-engine
+ )
+
+INSTALL(FILES
+ ${ETC_DIR}/fingerprint_list.xsd
+ DESTINATION share/wrt-engine/
+ )
+
+INSTALL(FILES
+ ${ETC_DIR}/fingerprint_list.xml
+ DESTINATION share/wrt-engine/
+ )
+
+ADD_SUBDIRECTORY(certificates)
--- /dev/null
+This directory contain confiration scripts, config files, certificates and all other data that don't fit to other directories.
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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)
+# @author Yunchan Cho (yunchan.cho@samsung.com)
+# @version 1.0
+# @brief
+#
+
+SET(CERT_DIR ${PROJECT_SOURCE_DIR}/etc/certificates)
+
+INSTALL(FILES
+ ${CERT_DIR}/wac.root.preproduction.pem
+ ${CERT_DIR}/wac.root.production.pem
+ ${CERT_DIR}/wac.publisherid.pem
+ ${CERT_DIR}/tizen.root.preproduction.cert.pem
+ DESTINATION /opt/share/cert-svc/certs/code-signing/wac/
+ )
--- /dev/null
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ b3:cb:d1:5b:de:6e:66:95
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=KR, ST=Suwon, O=Samsung Electronics, OU=SLP, CN=SLP WebApp Temporary CA/emailAddress=yunchan.cho@samsung.com
+ Validity
+ Not Before: Dec 8 10:27:32 2011 GMT
+ Not After : Nov 30 10:27:32 2021 GMT
+ Subject: C=KR, ST=Suwon, O=Samsung Electronics, OU=SLP, CN=SLP WebApp Temporary CA/emailAddress=yunchan.cho@samsung.com
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (1024 bit)
+ Modulus:
+ 00:cb:46:b8:94:81:b1:83:d7:29:05:2a:33:01:9e:
+ 66:15:f8:be:bb:95:17:dd:7a:c4:c2:f5:d9:e4:aa:
+ fd:c8:8d:a9:48:65:fc:3d:dc:47:d7:2a:2f:5e:c7:
+ 1f:22:ed:e0:98:e6:43:6d:74:82:ca:7d:22:9c:60:
+ 44:18:cd:ca:d6:6b:16:ca:ed:63:c9:7a:f1:00:df:
+ e4:6b:33:47:2f:78:75:61:d7:c9:29:3e:a9:ee:76:
+ dd:2e:fe:9d:e7:3c:0d:02:f4:e9:2d:46:74:49:52:
+ ef:a0:d6:9d:4d:08:65:ea:6b:35:72:a5:08:d8:46:
+ 46:03:99:7c:66:8c:60:c4:91
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 47:A8:8F:CD:1F:22:BA:69:85:13:55:21:2D:C2:19:2D:5F:FF:DC:03
+ X509v3 Authority Key Identifier:
+ keyid:47:A8:8F:CD:1F:22:BA:69:85:13:55:21:2D:C2:19:2D:5F:FF:DC:03
+
+ X509v3 Basic Constraints:
+ CA:TRUE
+ Signature Algorithm: sha1WithRSAEncryption
+ c2:c4:62:f2:ec:6f:2b:05:9c:09:cc:ae:e9:77:a9:1d:66:6b:
+ 03:7b:01:3a:e6:29:bb:2a:b8:15:d8:a1:7d:9b:05:b4:8c:cb:
+ ae:c7:eb:68:c0:e3:29:c7:e7:5a:ca:1a:0c:3a:ab:91:80:4f:
+ 9b:36:d4:45:b4:7b:2c:ef:f3:fd:cb:84:84:85:42:3d:ec:18:
+ 3f:5f:9e:b1:1f:8d:0a:57:89:51:e4:eb:7e:da:e9:79:82:61:
+ 38:ad:ca:94:43:71:00:73:13:b9:e9:ef:bc:68:c5:ff:5e:0a:
+ f6:b9:2a:3d:1d:21:77:22:d0:4e:e7:ad:da:31:0b:51:fa:44:
+ cd:fa
+-----BEGIN CERTIFICATE-----
+MIIC9jCCAl+gAwIBAgIJALPL0VvebmaVMA0GCSqGSIb3DQEBBQUAMIGTMQswCQYD
+VQQGEwJLUjEOMAwGA1UECAwFU3V3b24xHDAaBgNVBAoME1NhbXN1bmcgRWxlY3Ry
+b25pY3MxDDAKBgNVBAsMA1NMUDEgMB4GA1UEAwwXU0xQIFdlYkFwcCBUZW1wb3Jh
+cnkgQ0ExJjAkBgkqhkiG9w0BCQEWF3l1bmNoYW4uY2hvQHNhbXN1bmcuY29tMB4X
+DTExMTIwODEwMjczMloXDTIxMTEzMDEwMjczMlowgZMxCzAJBgNVBAYTAktSMQ4w
+DAYDVQQIDAVTdXdvbjEcMBoGA1UECgwTU2Ftc3VuZyBFbGVjdHJvbmljczEMMAoG
+A1UECwwDU0xQMSAwHgYDVQQDDBdTTFAgV2ViQXBwIFRlbXBvcmFyeSBDQTEmMCQG
+CSqGSIb3DQEJARYXeXVuY2hhbi5jaG9Ac2Ftc3VuZy5jb20wgZ8wDQYJKoZIhvcN
+AQEBBQADgY0AMIGJAoGBAMtGuJSBsYPXKQUqMwGeZhX4vruVF916xML12eSq/ciN
+qUhl/D3cR9cqL17HHyLt4JjmQ210gsp9IpxgRBjNytZrFsrtY8l68QDf5GszRy94
+dWHXySk+qe523S7+nec8DQL06S1GdElS76DWnU0IZeprNXKlCNhGRgOZfGaMYMSR
+AgMBAAGjUDBOMB0GA1UdDgQWBBRHqI/NHyK6aYUTVSEtwhktX//cAzAfBgNVHSME
+GDAWgBRHqI/NHyK6aYUTVSEtwhktX//cAzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3
+DQEBBQUAA4GBAMLEYvLsbysFnAnMrul3qR1mawN7ATrmKbsquBXYoX2bBbSMy67H
+62jA4ynH51rKGgw6q5GAT5s21EW0eyzv8/3LhISFQj3sGD9fnrEfjQpXiVHk637a
+6XmCYTitypRDcQBzE7np77xoxf9eCva5Kj0dIXci0E7nrdoxC1H6RM36
+-----END CERTIFICATE-----
--- /dev/null
+-----BEGIN CERTIFICATE-----
+MIID9DCCAtygAwIBAgIOZscBAQACO65mNg72468wDQYJKoZIhvcNAQEFBQAwgZQx
+CzAJBgNVBAYTAkRFMRwwGgYDVQQKExNUQyBUcnVzdENlbnRlciBHbWJIMTEwLwYD
+VQQLEyhQcmUtUHJvZHVjdGlvbiBUQyBUcnVzdENlbnRlciBDbGFzcyAyIENBMTQw
+MgYDVQQDEytQcmUtUHJvZHVjdGlvbiBUQyBUcnVzdENlbnRlciBDbGFzcyAyIENB
+IElJMB4XDTA2MDYwODE0MTYwMVoXDTI1MTIzMTIyNTk1OVowgZQxCzAJBgNVBAYT
+AkRFMRwwGgYDVQQKExNUQyBUcnVzdENlbnRlciBHbWJIMTEwLwYDVQQLEyhQcmUt
+UHJvZHVjdGlvbiBUQyBUcnVzdENlbnRlciBDbGFzcyAyIENBMTQwMgYDVQQDEytQ
+cmUtUHJvZHVjdGlvbiBUQyBUcnVzdENlbnRlciBDbGFzcyAyIENBIElJMIIBIjAN
+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3Ewnr8E24AqXnf1Lu7w/g79Hht+W
+lvWQg7cPC7685oj0htT0SmDy94uQaC3qRzBJktLKCyuniABykhdTr04rGWgzqD8n
+EzcFCt5k0gF39l3ND/JL+S2YJK/f/xc884hjcLsHUU7cAd6mDlVkOszFK86DNbu0
+noz0y1y462RIOvPCjkYl/GJ5zL62bdDbgFqrWMPZ54JFG0Rj1v575ygfOd2LwOXe
+xjzqfYI4JOx9frKWakPTehW+0UY5UdF0cMvHuLJie9H0vOobR4vtkenbS283b6j7
+0WCoU/BeAr4qskvMs9WwkwDquO4XnzYQDsEVgjBu4H2W0ihNUYJbRo8wtQIDAQAB
+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQU
+DTX6+fYyziPR1HZxViaGOj66QOYwDQYJKoZIhvcNAQEFBQADggEBALZ0pfjOfePn
+D/6QDCt+cjQ5+U4eKcOlJMXrpEAlnC6oAnN1hqbOQaj44aIAbNap36E/Hl9s0Uga
+c4nz73o5uPvdDmbWzNnMz6ey5NU0XXNzHxQWFdb0+Z7Cho5txoZjjynYXmyQc3RJ
+rrPI+6Uej6sEv15ZGirjABza6pNJ+2NLojLyUb+8et3OCLS+wJ4qrX/5uwgL50Lt
+0M2iPdZv+gjZwNmNWYIflYrSXa3ujclH+EAkkk/G1JxPzhVI3cII3y2DUZQAPCcX
+XQDXIX2zJo7bYaUYJhlEeiGX17cdXMXDT1tbXKKg2mRIga1K4lknn9U/vzkjMJXL
+GA38dUZRZ2Y=
+-----END CERTIFICATE-----
--- /dev/null
+-----BEGIN CERTIFICATE-----
+MIIDijCCAnKgAwIBAgIOMwoBAQAuBBKsIqIni7QwDQYJKoZIhvcNAQELBQAwYDEL
+MAkGA1UEBhMCR0IxJTAjBgNVBAoMHFdBQyBBcHBsaWNhdGlvbiBTZXJ2aWNlcyBM
+dGQxKjAoBgNVBAMMIVdBQyBBcHBsaWNhdGlvbiBTZXJ2aWNlcyBMdGQgVEVTVDAe
+Fw0xMTAzMDMxNTA3MTlaFw0zNjAzMDMxNTA3MTlaMGAxCzAJBgNVBAYTAkdCMSUw
+IwYDVQQKDBxXQUMgQXBwbGljYXRpb24gU2VydmljZXMgTHRkMSowKAYDVQQDDCFX
+QUMgQXBwbGljYXRpb24gU2VydmljZXMgTHRkIFRFU1QwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQC1PB3UrpAQgLSVqHRPhHqdDJsjKQe/CT9oS4lA+mI/
+vkhAvam/EvcNrNHcLVvSph+Mj0d2Y2J9wkcNW7fS3qZJXtpMNU36r7XdBk9kiYhc
+PwJbckCo9Pp8YFxkuR6xV6Cc4o54mO2mumxDQ1hbwCsc5CT7yQz0FVVhCE01X6JJ
+D61DvqmAzCUpehmEXthNV/s/o8fL+I2mD75p8vNDyIZHSJX59czO3PriT3tH2h+0
+tQx7NEWG70fQEU2CzcH9UngPYU7xXqNOhT9GmI/yL3HTeYGNH3i5VHrBjxeTF11t
+IWSUDWQX1W0Y7TbN06XcGcuqPgjZ9xMcV7S4OiCBJz5nAgMBAAGjQjBAMA8GA1Ud
+EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBQp5dzy2tJEArpT
+qcQWNXG6J7y5WTANBgkqhkiG9w0BAQsFAAOCAQEAoXuyi8AjMx2yKVpss7xpVi5v
+aUjcHU3AlptjNCFrXI6Bw+KJGNo8ydYlEASRd5dL/pJ6/V+UuUt9EngjUSdYOZGB
+OgCeB2sJI8EZSay2LLhOCmkAxltC94Y/KRzkKqsYvNc6yvF85d+d4gbokf4APjmR
+1TSlZLZsVhwfR0k0mer2rHQGE5Ljezdk7ZGeEMLdn6WFScwjo980EI0OqEoJU3on
++1TTBYudZ4o3qMgHiFwJafUJ6i3zuYbi9x86zMqeI4dJTbsTKLM0QV8vIdzI9fkV
+t1tO/uBBAsNFUv8PAYwP4AFyGvyJbR4uxwxuQZKrltgjSTkPGYR14JtrGk7Y9g==
+-----END CERTIFICATE-----
+
--- /dev/null
+-----BEGIN CERTIFICATE-----
+MIIDgTCCAmmgAwIBAgIPAKTxAAEALtiV8/+rhB6+MA0GCSqGSIb3DQEBCwUAMFsx
+CzAJBgNVBAYTAkdCMSUwIwYDVQQKDBxXQUMgQXBwbGljYXRpb24gU2VydmljZXMg
+THRkMSUwIwYDVQQDDBxXQUMgQXBwbGljYXRpb24gU2VydmljZXMgTHRkMB4XDTEx
+MDMxNDE0MDEwNFoXDTM2MDMxNDE0MDEwNFowWzELMAkGA1UEBhMCR0IxJTAjBgNV
+BAoMHFdBQyBBcHBsaWNhdGlvbiBTZXJ2aWNlcyBMdGQxJTAjBgNVBAMMHFdBQyBB
+cHBsaWNhdGlvbiBTZXJ2aWNlcyBMdGQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
+ggEKAoIBAQDCf6RHUPVBUY4YXYMdrmt5yO95eRCOG6vJtI9w0UM2w/2fihD5SMYa
+3cCVam4j6F8FSspMIx+4CTCwdDSUixBGENwGEhD4qxqqV3KTObmxmYbELa97S1IP
+qwoFelzUX6e+qHmYHi+eu/hONeiZaPBLtUtCd6ppCd5ACrD/kf/Ug/tfUtngozjG
+sJ1UB10Ezi3fKs3OkkZMuecJvjWmDpRAyvIeeV8xfzeyn+DMpvhnI9RrSY0j4huE
+ud6Lzzg0jV8+m54v0j7hv9klyNcGiZ+bmHr0LIyAtT+uktcms/4p3V9j01SI9Tmw
+HcHKDXnM6kuThWpr6DR9KFSZ8zD2Nx5nAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB
+Af8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBT5bKdU2+CGE17R+o/rMCZHHMn+
+WzANBgkqhkiG9w0BAQsFAAOCAQEAXmO+J5suIGuzbfYBoTdr8gahFfWEbhm1y6mJ
+eZAc+Mf5L+In20p+Oj5uy6LsTmJsE9VE/+gi1eALKl9EhgYhET2ZlAzRFCN5dTWv
+NTAFxJfGMkn2U5iW+luJ+lejyYBqEEFRpzwhXZbVDZQLim4CU75H75KzFkUgTulG
+5M6U/Plt6S1rKgMkeYiR27W4C2NZMFXYqctt0m+eKEa3ueZE9pYUxqVcvQKSI017
+Nbc1kSkcuSKFV2Bk2T5dh5jQvywykdWLubAe6XiiC5CIT31kcSX6AlVhgNxWRRKP
+QFO7lWqxnQMR2Or38ve7oSg1oL5Sx80fcbp3ovaYSKt5jnVWfg==
+-----END CERTIFICATE-----
+
--- /dev/null
+<CertificateSet>
+ <CertificateDomain name="wacpublisher">
+ <FingerprintSHA1>AF:90:29:D2:B2:E1:6F:D6:7E:7E:EC:8E:BE:74:FA:4C:00:9C:49:FE</FingerprintSHA1><!-- root.cert.pem w3c signature tests -->
+ <FingerprintSHA1>A6:00:BC:53:AC:37:5B:6A:03:C3:7A:8A:E0:1B:87:8B:82:94:9B:C2</FingerprintSHA1><!-- wac.publisher.pem -->
+ <FingerprintSHA1>C2:C4:B5:72:9A:CF:D9:72:C5:DE:C1:E1:30:FF:74:7F:7A:AF:27:12</FingerprintSHA1><!-- root_cacert.pem certificate for internal tests -->
+ </CertificateDomain>
+ <CertificateDomain name="wacroot">
+ <FingerprintSHA1>AF:90:29:D2:B2:E1:6F:D6:7E:7E:EC:8E:BE:74:FA:4C:00:9C:49:FE</FingerprintSHA1><!-- root.cert.pem w3c signature tests -->
+ <FingerprintSHA1>C2:C4:B5:72:9A:CF:D9:72:C5:DE:C1:E1:30:FF:74:7F:7A:AF:27:12</FingerprintSHA1><!-- root_cacert.pem certificate for internal tests -->
+ <FingerprintSHA1>A0:59:D3:37:E8:C8:2E:7F:38:84:7D:21:A9:9E:19:A9:8E:EC:EB:E1</FingerprintSHA1><!-- wac.root.production.pem -->
+ <FingerprintSHA1>8D:1F:CB:31:68:11:DA:22:59:26:58:13:6C:C6:72:C9:F0:DE:84:2A</FingerprintSHA1><!-- wac.root.preproduction.pem -->
+ </CertificateDomain>
+ <CertificateDomain name="developer">
+ <FingerprintSHA1>4A:9D:7A:4B:3B:29:D4:69:0A:70:B3:80:EC:A9:44:6B:03:7C:9A:38</FingerprintSHA1><!-- operator.root.cert.pem internal tests-->
+ </CertificateDomain>
+ <CertificateDomain name="wacmember">
+ </CertificateDomain>
+ <CertificateDomain name="tizenmember">
+ <FingerprintSHA1>AD:A1:44:89:6A:35:6D:17:01:E9:6F:46:C6:00:7B:78:BE:2E:D9:4E</FingerprintSHA1><!-- tizen.root.preproduction.cert.pem for internal test of SDK -->
+ </CertificateDomain>
+</CertificateSet>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+<xs:element name="CertificateSet" type="CertificateSetType" />
+<xs:complexType name="CertificateSetType">
+ <xs:sequence>
+ <xs:element ref="CertificateDomain" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+</xs:complexType>
+
+<xs:element name="CertificateDomain" type="CertificateDomainType" />
+<xs:complexType name="CertificateDomainType">
+ <xs:sequence>
+ <xs:element ref="FingerprintSHA1" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:attribute name="name" type="xs:string" use="required" />
+</xs:complexType>
+
+<xs:element name="FingerprintSHA1" type="xs:string"/>
+
+</xs:schema>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE schema
+ PUBLIC "-//W3C//DTD XMLSchema 200102//EN" "http://www.w3.org/2001/XMLSchema.dtd"
+ [
+ <!ATTLIST schema
+ xmlns:ds CDATA #FIXED "http://www.w3.org/2000/09/xmldsig#">
+ <!ENTITY dsig 'http://www.w3.org/2000/09/xmldsig#'>
+ <!ENTITY % p ''>
+ <!ENTITY % s ''>
+ ]>
+
+<!-- Schema for XML Signatures
+ http://www.w3.org/2000/09/xmldsig#
+ $Revision: 1.1 $ on $Date: 2002/02/08 20:32:26 $ by $Author: reagle $
+
+ Copyright 2001 The Internet Society and W3C (Massachusetts Institute
+ of Technology, Institut National de Recherche en Informatique et en
+ Automatique, Keio University). All Rights Reserved.
+ http://www.w3.org/Consortium/Legal/
+
+ This document is governed by the W3C Software License [1] as described
+ in the FAQ [2].
+
+ [1] http://www.w3.org/Consortium/Legal/copyright-software-19980720
+ [2] http://www.w3.org/Consortium/Legal/IPR-FAQ-20000620.html#DTD
+-->
+
+
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
+ targetNamespace="http://www.w3.org/2000/09/xmldsig#"
+ version="0.1" elementFormDefault="qualified">
+
+<!-- Basic Types Defined for Signatures -->
+
+<simpleType name="CryptoBinary">
+ <restriction base="base64Binary">
+ </restriction>
+</simpleType>
+
+<!-- Start Signature -->
+
+<element name="Signature" type="ds:SignatureType"/>
+<complexType name="SignatureType">
+ <sequence>
+ <element ref="ds:SignedInfo"/>
+ <element ref="ds:SignatureValue"/>
+ <element ref="ds:KeyInfo" minOccurs="0"/>
+ <element ref="ds:Object" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="Id" type="ID" use="optional"/>
+</complexType>
+
+ <element name="SignatureValue" type="ds:SignatureValueType"/>
+ <complexType name="SignatureValueType">
+ <simpleContent>
+ <extension base="base64Binary">
+ <attribute name="Id" type="ID" use="optional"/>
+ </extension>
+ </simpleContent>
+ </complexType>
+
+<!-- Start SignedInfo -->
+
+<element name="SignedInfo" type="ds:SignedInfoType"/>
+<complexType name="SignedInfoType">
+ <sequence>
+ <element ref="ds:CanonicalizationMethod"/>
+ <element ref="ds:SignatureMethod"/>
+ <element ref="ds:Reference" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="Id" type="ID" use="optional"/>
+</complexType>
+
+ <element name="CanonicalizationMethod" type="ds:CanonicalizationMethodType"/>
+ <complexType name="CanonicalizationMethodType" mixed="true">
+ <sequence>
+ <any namespace="##any" minOccurs="0" maxOccurs="unbounded"/>
+ <!-- (0,unbounded) elements from (1,1) namespace -->
+ </sequence>
+ <attribute name="Algorithm" type="anyURI" use="required"/>
+ </complexType>
+
+ <element name="SignatureMethod" type="ds:SignatureMethodType"/>
+ <complexType name="SignatureMethodType" mixed="true">
+ <sequence>
+ <element name="HMACOutputLength" minOccurs="0" type="ds:HMACOutputLengthType"/>
+ <any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
+ <!-- (0,unbounded) elements from (1,1) external namespace -->
+ </sequence>
+ <attribute name="Algorithm" type="anyURI" use="required"/>
+ </complexType>
+
+<!-- Start Reference -->
+
+<element name="Reference" type="ds:ReferenceType"/>
+<complexType name="ReferenceType">
+ <sequence>
+ <element ref="ds:Transforms" minOccurs="0"/>
+ <element ref="ds:DigestMethod"/>
+ <element ref="ds:DigestValue"/>
+ </sequence>
+ <attribute name="Id" type="ID" use="optional"/>
+ <attribute name="URI" type="anyURI" use="optional"/>
+ <attribute name="Type" type="anyURI" use="optional"/>
+</complexType>
+
+ <element name="Transforms" type="ds:TransformsType"/>
+ <complexType name="TransformsType">
+ <sequence>
+ <element ref="ds:Transform" maxOccurs="unbounded"/>
+ </sequence>
+ </complexType>
+
+ <element name="Transform" type="ds:TransformType"/>
+ <complexType name="TransformType" mixed="true">
+ <choice minOccurs="0" maxOccurs="unbounded">
+ <any namespace="##other" processContents="lax"/>
+ <!-- (1,1) elements from (0,unbounded) namespaces -->
+ <element name="XPath" type="string"/>
+ </choice>
+ <attribute name="Algorithm" type="anyURI" use="required"/>
+ </complexType>
+
+<!-- End Reference -->
+
+<element name="DigestMethod" type="ds:DigestMethodType"/>
+<complexType name="DigestMethodType" mixed="true">
+ <sequence>
+ <any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="Algorithm" type="anyURI" use="required"/>
+</complexType>
+
+<element name="DigestValue" type="ds:DigestValueType"/>
+<simpleType name="DigestValueType">
+ <restriction base="base64Binary"/>
+</simpleType>
+
+<!-- End SignedInfo -->
+
+<!-- Start KeyInfo -->
+
+<element name="KeyInfo" type="ds:KeyInfoType"/>
+<complexType name="KeyInfoType" mixed="true">
+ <choice maxOccurs="unbounded">
+ <element ref="ds:KeyName"/>
+ <element ref="ds:KeyValue"/>
+ <element ref="ds:RetrievalMethod"/>
+ <element ref="ds:X509Data"/>
+ <element ref="ds:PGPData"/>
+ <element ref="ds:SPKIData"/>
+ <element ref="ds:MgmtData"/>
+ <any processContents="lax" namespace="##other"/>
+ <!-- (1,1) elements from (0,unbounded) namespaces -->
+ </choice>
+ <attribute name="Id" type="ID" use="optional"/>
+</complexType>
+
+ <element name="KeyName" type="string"/>
+ <element name="MgmtData" type="string"/>
+
+ <element name="KeyValue" type="ds:KeyValueType"/>
+ <complexType name="KeyValueType" mixed="true">
+ <choice>
+ <element ref="ds:DSAKeyValue"/>
+ <element ref="ds:RSAKeyValue"/>
+ <element ref="ds:ECKeyValue"/>
+ <any namespace="##other" processContents="lax"/>
+ </choice>
+ </complexType>
+
+<!-- ECDSA KEY DEFINITIONS -->
+
+ <element name="ECKeyValue" type="ds:ECKeyValueType"/>
+ <complexType name="ECKeyValueType">
+ <sequence>
+ <choice>
+ <element name="ECParameters" type="ds:ECParametersType"/>
+ <element name="NamedCurve" type="ds:NamedCurveType"/>
+ </choice>
+ <element name="PublicKey" type="ds:ECPointType"/>
+ </sequence>
+ <attribute name="Id" type="ID" use="optional"/>
+ </complexType>
+
+ <complexType name="NamedCurveType">
+ <attribute name="URI" type="anyURI" use="required"/>
+ </complexType>
+
+ <simpleType name="ECPointType">
+ <restriction base="ds:CryptoBinary"/>
+ </simpleType>
+
+ <element name="RetrievalMethod" type="ds:RetrievalMethodType"/>
+ <complexType name="RetrievalMethodType">
+ <sequence>
+ <element ref="ds:Transforms" minOccurs="0"/>
+ </sequence>
+ <attribute name="URI" type="anyURI"/>
+ <attribute name="Type" type="anyURI" use="optional"/>
+ </complexType>
+
+ <complexType name="ECParametersType">
+ <sequence>
+ <element name="FieldID" type="ds:FieldIDType"/>
+ <element name="Curve" type="ds:CurveType"/>
+ <element name="Base" type="ds:ECPointType"/>
+ <element name="Order" type="ds:CryptoBinary"/>
+ <element name="CoFactor" type="integer" minOccurs="0"/>
+ <element name="ValidationData" type="ds:ECValidationDataType" minOccurs="0"/>
+ </sequence>
+ </complexType>
+
+ <complexType name="FieldIDType">
+ <choice>
+ <element ref="ds:Prime"/>
+ <element ref="ds:TnB"/>
+ <element ref="ds:PnB"/>
+ <element ref="ds:GnB"/>
+ <any namespace="##other" processContents="lax"/>
+ </choice>
+ </complexType>
+
+ <element name="Prime" type="ds:PrimeFieldParamsType"/>
+ <complexType name="PrimeFieldParamsType">
+ <sequence>
+ <element name="P" type="ds:CryptoBinary"/>
+ </sequence>
+ </complexType>
+
+ <element name="GnB" type="ds:CharTwoFieldParamsType"/>
+ <complexType name="CharTwoFieldParamsType">
+ <sequence>
+ <element name="M" type="positiveInteger"/>
+ </sequence>
+ </complexType>
+
+ <element name="TnB" type="ds:TnBFieldParamsType"/>
+ <complexType name="TnBFieldParamsType">
+ <complexContent>
+ <extension base="ds:CharTwoFieldParamsType">
+ <sequence>
+ <element name="K" type="positiveInteger"/>
+ </sequence>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <element name="PnB" type="ds:PnBFieldParamsType"/>
+ <complexType name="PnBFieldParamsType">
+ <complexContent>
+ <extension base="ds:CharTwoFieldParamsType">
+ <sequence>
+ <element name="K1" type="positiveInteger"/>
+ <element name="K2" type="positiveInteger"/>
+ <element name="K3" type="positiveInteger"/>
+ </sequence>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <complexType name="CurveType">
+ <sequence>
+ <element name="A" type="ds:CryptoBinary"/>
+ <element name="B" type="ds:CryptoBinary"/>
+ </sequence>
+ </complexType>
+
+ <complexType name="ECValidationDataType">
+ <sequence>
+ <element name="seed" type="ds:CryptoBinary"/>
+ </sequence>
+ <attribute name="hashAlgorithm" type="anyURI" use="required"/>
+ </complexType>
+
+
+<!-- Start X509Data -->
+
+<element name="X509Data" type="ds:X509DataType"/>
+<complexType name="X509DataType">
+ <sequence maxOccurs="unbounded">
+ <choice>
+ <element name="X509IssuerSerial" type="ds:X509IssuerSerialType"/>
+ <element name="X509SKI" type="base64Binary"/>
+ <element name="X509SubjectName" type="string"/>
+ <element name="X509Certificate" type="base64Binary"/>
+ <element name="X509CRL" type="base64Binary"/>
+ <any namespace="##other" processContents="lax"/>
+ </choice>
+ </sequence>
+</complexType>
+
+<complexType name="X509IssuerSerialType">
+ <sequence>
+ <element name="X509IssuerName" type="string"/>
+ <element name="X509SerialNumber" type="integer"/>
+ </sequence>
+</complexType>
+
+<!-- End X509Data -->
+
+<!-- Begin PGPData -->
+
+<element name="PGPData" type="ds:PGPDataType"/>
+<complexType name="PGPDataType">
+ <choice>
+ <sequence>
+ <element name="PGPKeyID" type="base64Binary"/>
+ <element name="PGPKeyPacket" type="base64Binary" minOccurs="0"/>
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded"/>
+ </sequence>
+ <sequence>
+ <element name="PGPKeyPacket" type="base64Binary"/>
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded"/>
+ </sequence>
+ </choice>
+</complexType>
+
+<!-- End PGPData -->
+
+<!-- Begin SPKIData -->
+
+<element name="SPKIData" type="ds:SPKIDataType"/>
+<complexType name="SPKIDataType">
+ <sequence maxOccurs="unbounded">
+ <element name="SPKISexp" type="base64Binary"/>
+ <any namespace="##other" processContents="lax" minOccurs="0"/>
+ </sequence>
+</complexType>
+
+<!-- End SPKIData -->
+
+<!-- End KeyInfo -->
+
+<!-- Start Object (Manifest, SignatureProperty) -->
+
+<element name="Object" type="ds:ObjectType"/>
+<complexType name="ObjectType" mixed="true">
+ <sequence minOccurs="0" maxOccurs="unbounded">
+ <any namespace="##any" processContents="lax"/>
+ </sequence>
+ <attribute name="Id" type="ID" use="optional"/>
+ <attribute name="MimeType" type="string" use="optional"/> <!-- add a grep facet -->
+ <attribute name="Encoding" type="anyURI" use="optional"/>
+</complexType>
+
+<element name="Manifest" type="ds:ManifestType"/>
+<complexType name="ManifestType">
+ <sequence>
+ <element ref="ds:Reference" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="Id" type="ID" use="optional"/>
+</complexType>
+
+<element name="SignatureProperties" type="ds:SignaturePropertiesType"/>
+<complexType name="SignaturePropertiesType">
+ <sequence>
+ <element ref="ds:SignatureProperty" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="Id" type="ID" use="optional"/>
+</complexType>
+
+ <element name="SignatureProperty" type="ds:SignaturePropertyType"/>
+ <complexType name="SignaturePropertyType" mixed="true">
+ <choice maxOccurs="unbounded">
+ <any namespace="##other" processContents="lax"/>
+ <!-- (1,1) elements from (1,unbounded) namespaces -->
+ </choice>
+ <attribute name="Target" type="anyURI" use="required"/>
+ <attribute name="Id" type="ID" use="optional"/>
+ </complexType>
+
+<!-- End Object (Manifest, SignatureProperty) -->
+
+<!-- Start Algorithm Parameters -->
+
+<simpleType name="HMACOutputLengthType">
+ <restriction base="integer"/>
+</simpleType>
+
+<!-- Start KeyValue Element-types -->
+
+<element name="DSAKeyValue" type="ds:DSAKeyValueType"/>
+<complexType name="DSAKeyValueType">
+ <sequence>
+ <sequence minOccurs="0">
+ <element name="P" type="ds:CryptoBinary"/>
+ <element name="Q" type="ds:CryptoBinary"/>
+ </sequence>
+ <element name="G" type="ds:CryptoBinary" minOccurs="0"/>
+ <element name="Y" type="ds:CryptoBinary"/>
+ <element name="J" type="ds:CryptoBinary" minOccurs="0"/>
+ <sequence minOccurs="0">
+ <element name="Seed" type="ds:CryptoBinary"/>
+ <element name="PgenCounter" type="ds:CryptoBinary"/>
+ </sequence>
+ </sequence>
+</complexType>
+
+<element name="RSAKeyValue" type="ds:RSAKeyValueType"/>
+<complexType name="RSAKeyValueType">
+ <sequence>
+ <element name="Modulus" type="ds:CryptoBinary"/>
+ <element name="Exponent" type="ds:CryptoBinary"/>
+ </sequence>
+</complexType>
+
+<!-- End KeyValue Element-types -->
+
+<!-- End Signature -->
+
+</schema>
--- /dev/null
+#!/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.
+#
+for name in wrt ace vcore
+do
+ rm -f /opt/dbspace/.$name.db
+ rm -f /opt/dbspace/.$name.db-journal
+ SQL="PRAGMA journal_mode = PERSIST;"
+ sqlite3 /opt/dbspace/.$name.db "$SQL"
+ SQL=".read /usr/share/wrt-engine/"$name"_db.sql"
+ sqlite3 /opt/dbspace/.$name.db "$SQL"
+ touch /opt/dbspace/.$name.db-journal
+ chown root:6026 /opt/dbspace/.$name.db
+ chown root:6026 /opt/dbspace/.$name.db-journal
+ chmod 660 /opt/dbspace/.$name.db
+ chmod 660 /opt/dbspace/.$name.db-journal
+done
+
+
--- /dev/null
+#!/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_create_clean_db.sh
+
+rm -rf /opt/apps/widget/system/*
+
+# This directories contains test widgets and test keys. It shouldn't be removed.
+#rm -rf /opt/apps/widget/user/*
+#rm -rf /opt/apps/widget/data/*
+
+#Removing of widget desktop icons
+WIDGET_EXEC_PATH=/opt/apps/widget/exec
+WIDGET_DESKTOP_PATH=/opt/share/install-info/application
+WIDGET_ICON_PATH=/opt/share/icons/default/small
+WIDGET_EXECS="${WIDGET_EXEC_PATH}/*";
+
+for file in $WIDGET_EXECS; do
+ widget_id=${file#${WIDGET_EXEC_PATH}/};
+
+ widget_desktop_file="${WIDGET_DESKTOP_PATH}/org.tizen.${widget_id}.desktop";
+ if [ -f ${widget_desktop_file} ]; then
+ echo "rm -f $widget_desktop_file";
+ rm -f $widget_desktop_file;
+ fi
+
+ widget_icon_file="${WIDGET_ICON_PATH}/${widget_id}.*"
+ if [ -f ${widget_icon_file} ]; then
+ echo "rm -f $widget_icon_file";
+ rm -f $widget_icon_file;
+ fi
+done
+
+rm -rf /opt/apps/widget/exec/*
+touch /opt/apps/widget/plugin-installation-required
+
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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(event_delivery_test)
+ADD_SUBDIRECTORY(metronome)
+ADD_SUBDIRECTORY(copy)
--- /dev/null
+!!!options!!! stop
+Example code
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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})
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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;
+}
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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})
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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;
+}
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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})
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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;
+}
--- /dev/null
+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})
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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);
+}
+
--- /dev/null
+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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <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)
+ {
+ LogInfo("On method call: " << methodName);
+
+ if (g_strcmp0(methodName, "echo") == 0)
+ {
+ const gchar* arg = NULL;
+
+ g_variant_get(parameters, "(&s)", &arg);
+ LogInfo("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;
+}
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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 Jaroslaw Osmanski j.osmanski@samsung.com
+# @version 1.0
+# @brief
+#
+INCLUDE(FindPkgConfig)
+PKG_CHECK_MODULES(DPL_GTK "dpl-gtk" "gthread-2.0" REQUIRED)
+
+SET(EVENT_DELIVERY_SOURCES
+ event_delivery_test.cpp)
+
+ADD_DEFINITIONS("-D_DEBUG -g")
+
+INCLUDE_DIRECTORIES(${DPL_GTK_INCLUDE_DIRS})
+LINK_DIRECTORIES(${DPL_GTK_LIBRARY_DIRS})
+
+ADD_EXECUTABLE(event_delivery_test ${EVENT_DELIVERY_SOURCES})
+TARGET_LINK_LIBRARIES(event_delivery_test ${DPL_GTK_LIBRARIES})
+
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_delivery_server.h
+ * @author Jaroslaw Osmanski j.osmanski@samsung.com
+ * @version 1.0
+ * @brief This file is the implementation file of simple event delivery test
+ */
+#include <dpl/application.h>
+#include <dpl/controller.h>
+#include <dpl/event_delivery.h>
+#include <dpl/event_delivery_injector.h>
+#include <dpl/generic_event.h>
+#include <dpl/type_list.h>
+#include <iostream>
+
+namespace TestEvents
+{
+EVENT_DELIVERY_DECLARE_EVENT_MESSAGE_0(EmptyMessage)
+EVENT_DELIVERY_DECLARE_EVENT_MESSAGE_2(HelloWorldMessage, std::string, std::string)
+EVENT_DELIVERY_DECLARE_EVENT_MESSAGE_2(NumberMessage, int, float)
+EVENT_DELIVERY_DECLARE_EVENT_MESSAGE_4(TestMessage, int, int, int, int)
+
+EVENT_DELIVERY_IMPLEMENT_EVENT_MESSAGE(EmptyMessage)
+EVENT_DELIVERY_IMPLEMENT_EVENT_MESSAGE(HelloWorldMessage)
+EVENT_DELIVERY_IMPLEMENT_EVENT_MESSAGE(NumberMessage)
+EVENT_DELIVERY_IMPLEMENT_EVENT_MESSAGE(TestMessage)
+} // namespace TestEvents
+
+DECLARE_GENERIC_EVENT_0(StartEvent)
+DECLARE_GENERIC_EVENT_0(CloseEvent)
+DECLARE_GENERIC_EVENT_0(DeleteEvent)
+
+class MyListener :
+ public DPL::Application,
+ private DPL::Controller<DPL::TypeListDecl<DeleteEvent, CloseEvent>::Type>,
+ public DPL::EventListener<TestEvents::HelloWorldMessage>,
+ public DPL::EventListener<TestEvents::NumberMessage>
+{
+private:
+ class OneTimeListener :
+ public DPL::EventListener<TestEvents::EmptyMessage>
+ {
+ public:
+ OneTimeListener()
+ {
+ DPL::EventDeliverySystem::AddListener<TestEvents::EmptyMessage > (this);
+ }
+
+ ~OneTimeListener()
+ {
+ LogError("Deleting OneTimeListener");
+ DPL::EventDeliverySystem::RemoveListener<TestEvents::EmptyMessage > (this);
+ }
+
+ private:
+ void OnEventReceived(const TestEvents::EmptyMessage &message)
+ {
+ (void) message;
+ std::cout << "OneTimeListener empty message";
+
+ }
+ };
+
+ OneTimeListener * oneTimeListener;
+
+ virtual void OnEventReceived(const CloseEvent &event)
+ {
+ (void) event;
+ Quit();
+ }
+
+ virtual void OnEventReceived(const DeleteEvent &event)
+ {
+ (void) event;
+ delete oneTimeListener;
+ oneTimeListener = NULL;
+ }
+
+protected:
+
+ void OnEventReceived(const TestEvents::HelloWorldMessage &message)
+ {
+ std::cout << "Got HelloWorldMessage: " << message.GetArg0() << " : " << message.GetArg1() << std::endl;
+
+ if (oneTimeListener != NULL)
+ {
+ DPL::ControllerEventHandler<DeleteEvent>::PostTimedEvent(DeleteEvent(), 1);
+ }
+ }
+
+ void OnEventReceived(const TestEvents::NumberMessage &message)
+ {
+ std::cout << "Got NumberMessage: " << message.GetArg0() << ", " << message.GetArg1() << std::endl;
+ }
+
+public:
+
+ MyListener(int argc, char **argv)
+ : Application(argc, argv, "Listener")
+ {
+ Touch();
+
+ DPL::EventDeliverySystem::AddListener<TestEvents::HelloWorldMessage>(this);
+ DPL::EventDeliverySystem::AddListener<TestEvents::NumberMessage>(this);
+
+ DPL::ControllerEventHandler<CloseEvent>::PostTimedEvent(CloseEvent(), 8);
+ oneTimeListener = new OneTimeListener();
+ }
+
+ virtual ~MyListener()
+ {
+ DPL::EventDeliverySystem::RemoveListener<TestEvents::HelloWorldMessage > (this);
+ DPL::EventDeliverySystem::RemoveListener<TestEvents::NumberMessage > (this);
+ delete oneTimeListener;
+ }
+};
+
+class MyPusher :
+ public DPL::Application,
+ private DPL::Controller<DPL::TypeListDecl<StartEvent, CloseEvent>::Type>
+{
+private:
+ virtual void OnEventReceived(const CloseEvent &event)
+ {
+ (void) event;
+ Quit();
+ }
+
+ virtual void OnEventReceived(const StartEvent &event)
+ {
+ (void) event;
+ std::cout << "Publishing HelloWorldMessage..." << std::endl;
+ TestEvents::HelloWorldMessage hello("Hello cruel world !", "AAA BBB CCC");
+ DPL::EventDeliverySystem::Publish(hello);
+ std::cout << "HelloWorldMessage published." << std::endl;
+
+ std::cout << "Publishing NumberMessage message..." << std::endl;
+ TestEvents::NumberMessage number(13, 3.14f);
+ DPL::EventDeliverySystem::Publish(number);
+ std::cout << "NumberMessage published." << std::endl;
+
+ std::cout << "Publishing EmptyMessage..." << std::endl;
+ TestEvents::EmptyMessage empty;
+ DPL::EventDeliverySystem::Publish(empty);
+ std::cout << "EmptyMessage published." << std::endl;
+
+ }
+public:
+ MyPusher(int argc, char **argv)
+ : Application(argc, argv, "Pusher")
+ {
+ Touch();
+
+ DPL::ControllerEventHandler<StartEvent>::PostTimedEvent(StartEvent(), 2);
+ DPL::ControllerEventHandler<StartEvent>::PostTimedEvent(StartEvent(), 6);
+ DPL::ControllerEventHandler<CloseEvent>::PostTimedEvent(CloseEvent(), 8);
+ }
+
+ virtual ~MyPusher()
+ {
+ }
+};
+
+int main(int argc, char* argv[])
+{
+ switch (fork())
+ {
+ case 0:
+ {
+ MyPusher myPusher(argc, argv);
+ myPusher.Exec();
+ }
+ break;
+
+ case -1:
+ printf("fork() failed!");
+ break;
+
+ default:
+ {
+ MyListener myListener(argc, argv);
+ myListener.Exec();
+ }
+ break;
+ }
+
+ return 0;
+}
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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})
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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 <dpl/scoped_ptr.h>
+#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;
+
+ DPL::ScopedPtr<DPL::AbstractRPCConnection> m_rpcUnixConnection;
+ DPL::ScopedPtr<DPL::AbstractRPCConnection> m_rpcFakeConnection;
+
+ virtual void OnEventReceived(const AsyncCallEvent &event)
+ {
+ LogInfo("CLIENT: AsyncCallEvent received");
+
+ event.GetArg0().ConsumeArg(m_receivedData);
+ LogInfo("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;
+ LogInfo("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;
+ LogInfo("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);
+ LogInfo("CLIENT: Calling RPC function");
+ m_rpcFakeConnection->AsyncCall(proc);
+ }
+ }
+
+public:
+ virtual ~MyThread()
+ {
+ // Always quit thread
+ Quit();
+ }
+
+ virtual int ThreadEntry()
+ {
+ m_connections = 0;
+ // Attach RPC listeners
+ LogInfo("CLIENT: Attaching connection established event");
+ m_rpcUnixClient.DPL::EventSupport<ConnectionEstablishedEvent>::AddListener(this);
+ m_rpcFakeClient.DPL::EventSupport<ConnectionEstablishedEvent>::AddListener(this);
+
+ // Open connection to server
+ LogInfo("CLIENT: Opening connection to RPC");
+ m_rpcUnixClient.Open(UNIX_RPC_NAME);
+ m_rpcFakeClient.Open(FAKE_RPC_NAME);
+
+ // Start message loop
+ LogInfo("CLIENT: Starting thread event loop");
+ int ret = Exec();
+
+ if (m_rpcUnixConnection.Get()){
+ LogInfo("CLIENT: Removing Unix connection");
+ m_rpcUnixConnection->DPL::EventSupport<AsyncCallEvent>::RemoveListener(this);
+ m_rpcUnixConnection.Reset();
+ }
+
+ LogInfo("CLIENT: Closing");
+
+ if (m_rpcFakeConnection.Get()){
+ LogInfo("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
+ LogInfo("CLIENT: Detaching connection established event");
+ m_rpcUnixClient.DPL::EventSupport<ConnectionEstablishedEvent>::RemoveListener(this);
+ m_rpcFakeClient.DPL::EventSupport<ConnectionEstablishedEvent>::RemoveListener(this);
+
+ // Close RPC
+ LogInfo("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;
+
+ DPL::ScopedPtr<DPL::AbstractRPCConnection> m_rpcUnixConnection;
+ DPL::ScopedPtr<DPL::AbstractRPCConnection> m_rpcFakeConnection;
+
+ MyThread m_thread;
+
+ // Quit application event occurred
+ virtual void OnEventReceived(const QuitEvent &/*event*/){
+ // Close RPC now
+ LogInfo("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();
+ }
+
+ LogInfo("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);
+
+ LogInfo("SERVER: Server closed");
+
+ Quit();
+ }
+
+ virtual void OnEventReceived(const CloseThreadEvent &/*event*/){
+ m_thread.Quit();
+ }
+
+ virtual void OnEventReceived(const AsyncCallEvent &event)
+ {
+ LogInfo("SERVER: AsyncCallEvent received");
+
+ int value;
+ event.GetArg0().ConsumeArg(value);
+ LogInfo("SERVER: Result from client: " << value);
+
+ // send back data to client (via fake)
+ // Emit RPC function call
+ DPL::RPCFunction proc;
+ proc.AppendArg(value);
+ LogInfo("SERVER: Calling RPC function");
+ m_rpcUnixConnection->AsyncCall(proc);
+ }
+
+ virtual void OnEventReceived(const ConnectionEstablishedEvent &event)
+ {
+ // Save connection pointer
+ if (dynamic_cast<DPL::FakeRpcConnection *>(event.GetArg1())){
+ LogInfo("SERVER: Acquiring Fake RPC connection");
+ m_rpcFakeConnection.Reset(event.GetArg1());
+ m_rpcFakeConnection->DPL::EventSupport<AsyncCallEvent>::AddListener(this);
+ }
+ else{
+ LogInfo("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
+ LogInfo("SERVER: Attaching connection established event");
+ m_rpcUnixServer.DPL::EventSupport<ConnectionEstablishedEvent>::AddListener(this);
+ m_rpcFakeServer.DPL::EventSupport<ConnectionEstablishedEvent>::AddListener(this);
+
+ // Self touch
+ LogInfo("SERVER: Touching controller");
+ Touch();
+
+ // Open RPC server
+ LogInfo("SERVER: Opening server RPC");
+ m_rpcUnixServer.Open(UNIX_RPC_NAME);
+ m_rpcFakeServer.Open(FAKE_RPC_NAME);
+
+ // Run RPC client in thread
+ LogInfo("SERVER: Starting RPC client thread");
+ m_thread.Run();
+
+ // Quit application automatically in few seconds
+ LogInfo("SERVER: Sending control timed events");
+ DPL::ControllerEventHandler<CloseThreadEvent>::PostTimedEvent(CloseThreadEvent(), 2);
+ DPL::ControllerEventHandler<QuitEvent>::PostTimedEvent(QuitEvent(), 3);
+ }
+
+ virtual ~MyApplication()
+ {
+ // Quit thread
+ LogInfo("SERVER: Quitting thread");
+ }
+};
+
+int main(int argc, char *argv[])
+{
+ LogInfo("Starting");
+ MyApplication app(argc, argv);
+ return app.Exec();
+}
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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})
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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;
+ DPL::ScopedPtr<DPL::AbstractRPCConnection> m_rpcConnection;
+
+ virtual void OnEventReceived(const DPL::AbstractRPCConnectionEvents::AsyncCallEvent &event)
+ {
+ (void)event;
+
+ // Heart beat
+ LogInfo("* Got metronome signal *");
+ }
+
+ virtual void OnEventReceived(const DPL::AbstractRPCConnectionEvents::ConnectionClosedEvent &event)
+ {
+ (void)event;
+
+ LogInfo("Connection closed");
+
+ // Must quit
+ Quit();
+ }
+
+ virtual void OnEventReceived(const DPL::AbstractRPCConnectionEvents::ConnectionBrokenEvent &event)
+ {
+ (void)event;
+
+ LogInfo("Connection broken");
+
+ // Must quit
+ Quit();
+ }
+
+ virtual void OnEventReceived(const DPL::AbstractRPCConnectorEvents::ConnectionEstablishedEvent &event)
+ {
+ // Save connection pointer
+ LogInfo("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
+ LogInfo("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();
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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;
+
+ LogInfo("Connection closed");
+
+ // Remove connection from list
+ RemoveConnection(static_cast<DPL::AbstractRPCConnection *>(event.GetSender()));
+ }
+
+ virtual void OnEventReceived(const DPL::AbstractRPCConnectionEvents::ConnectionBrokenEvent &event)
+ {
+ (void)event;
+
+ LogInfo("Connection broken");
+
+ // Remove connection from list
+ RemoveConnection(static_cast<DPL::AbstractRPCConnection *>(event.GetSender()));
+ }
+
+ virtual void OnEventReceived(const DPL::AbstractRPCConnectorEvents::ConnectionEstablishedEvent &event)
+ {
+ // Save connection pointer
+ LogInfo("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
+ LogInfo("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();
+}
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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})
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <dpl/unix_socket_rpc_client.h>
+#include <dpl/unix_socket_rpc_server.h>
+#include <dpl/unix_socket_rpc_connection.h>
+#include <dpl/scoped_ptr.h>
+#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;
+ DPL::ScopedPtr<DPL::AbstractRPCConnection> m_rpcConnection;
+
+ virtual void OnEventReceived(const DPL::AbstractRPCConnectionEvents::AsyncCallEvent &event)
+ {
+ (void)event;
+
+ LogInfo("CLIENT: AsyncCallEvent received");
+
+ int value;
+ event.GetArg0().ConsumeArg(value);
+ LogInfo("CLIENT: Result from server: " << value);
+ }
+
+ virtual void OnEventReceived(const DPL::AbstractRPCConnectionEvents::ConnectionClosedEvent &event)
+ {
+ (void)event;
+ LogInfo("CLIENT: ConnectionClosedEvent received");
+ }
+
+ virtual void OnEventReceived(const DPL::AbstractRPCConnectionEvents::ConnectionBrokenEvent &event)
+ {
+ (void)event;
+ LogInfo("CLIENT: ConnectionBrokenEvent received");
+ }
+
+ virtual void OnEventReceived(const DPL::AbstractRPCConnectorEvents::ConnectionEstablishedEvent &event)
+ {
+ // Save connection pointer
+ LogInfo("CLIENT: Acquiring new connection");
+ m_rpcConnection.Reset(event.GetArg1());
+
+ // Attach listener to new connection
+ LogInfo("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);
+
+ LogInfo("CLIENT: Connection established");
+
+ // Emit RPC function call
+ DPL::RPCFunction proc;
+ proc.AppendArg((int)1111);
+ LogInfo("CLIENT: Calling RPC function");
+ m_rpcConnection->AsyncCall(proc);
+ }
+
+public:
+ virtual ~MyThread()
+ {
+ // Always quit thread
+ Quit();
+ }
+
+ virtual int ThreadEntry()
+ {
+ // Attach RPC listeners
+ LogInfo("CLIENT: Attaching connection established event");
+ m_rpcClient.DPL::EventSupport<DPL::AbstractRPCConnectorEvents::ConnectionEstablishedEvent>::AddListener(this);
+
+ // Open connection to server
+ LogInfo("CLIENT: Opening connection to RPC");
+ m_rpcClient.Open(RPC_NAME);
+
+ // Start message loop
+ LogInfo("CLIENT: Starting thread event loop");
+ int ret = Exec();
+
+ // Detach RPC listeners
+ if (m_rpcConnection.Get())
+ {
+ LogInfo("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);
+
+ LogInfo("CLIENT: Resetting connection");
+ m_rpcConnection.Reset();
+ }
+
+ // Detach RPC client listener
+ LogInfo("CLIENT: Detaching connection established event");
+ m_rpcClient.DPL::EventSupport<DPL::AbstractRPCConnectorEvents::ConnectionEstablishedEvent>::RemoveListener(this);
+
+ // Close RPC
+ LogInfo("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;
+ DPL::ScopedPtr<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;
+
+ LogInfo("SERVER: AsyncCallEvent received");
+
+ int value;
+ event.GetArg0().ConsumeArg(value);
+ LogInfo("SERVER: Result from client: " << value);
+ }
+
+ virtual void OnEventReceived(const DPL::AbstractRPCConnectionEvents::ConnectionClosedEvent &event)
+ {
+ (void)event;
+
+ LogInfo("SERVER: ConnectionClosedEvent received");
+
+ // Close RPC now
+ LogInfo("SERVER: Closing RPC connection on event...");
+
+ // Detach RPC connection listeners
+ if (m_rpcConnection.Get())
+ {
+ LogInfo("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);
+ }
+ LogInfo("SERVER: RPC connection closed");
+
+ LogInfo("SERVER: Closing RPC on event...");
+ m_rpcServer.CloseAll();
+ LogInfo("SERVER: RPC closed");
+ }
+
+ virtual void OnEventReceived(const DPL::AbstractRPCConnectionEvents::ConnectionBrokenEvent &event)
+ {
+ (void)event;
+ LogInfo("SERVER: ConnectionBrokenEvent received");
+ }
+
+ virtual void OnEventReceived(const DPL::AbstractRPCConnectorEvents::ConnectionEstablishedEvent &event)
+ {
+ // Save connection pointer
+ LogInfo("SERVER: Acquiring RPC connection");
+ m_rpcConnection.Reset(event.GetArg1());
+
+ // Attach event listeners
+ LogInfo("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);
+
+ LogInfo("SERVER: Connection established");
+
+ // Emit RPC function call
+ DPL::RPCFunction proc;
+ proc.AppendArg((int)2222);
+ LogInfo("SERVER: Calling RPC function");
+ m_rpcConnection->AsyncCall(proc);
+ }
+
+public:
+ MyApplication(int argc, char **argv)
+ : Application(argc, argv, "rpc")
+ {
+ // Attach RPC server listeners
+ LogInfo("SERVER: Attaching connection established event");
+ m_rpcServer.DPL::EventSupport<DPL::AbstractRPCConnectorEvents::ConnectionEstablishedEvent>::AddListener(this);
+
+ // Self touch
+ LogInfo("SERVER: Touching controller");
+ Touch();
+
+ // Open RPC server
+ LogInfo("SERVER: Opening server RPC");
+ m_rpcServer.Open(RPC_NAME);
+
+ // Run RPC client in thread
+ LogInfo("SERVER: Starting RPC client thread");
+ m_thread.Run();
+
+ // Quit application automatically in few seconds
+ LogInfo("SERVER: Sending control timed events");
+ DPL::ControllerEventHandler<CloseThreadEvent>::PostTimedEvent(CloseThreadEvent(), 2);
+ DPL::ControllerEventHandler<QuitEvent>::PostTimedEvent(QuitEvent(), 3);
+ }
+
+ virtual ~MyApplication()
+ {
+ // Quit thread
+ LogInfo("SERVER: Quitting thread");
+ m_thread.Quit();
+
+ // Close RPC server
+ LogInfo("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[])
+{
+ LogInfo("Starting");
+ MyApplication app(argc, argv);
+ return app.Exec();
+}
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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})
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <dpl/log/log.h>
+
+int main(int argc, char *argv[])
+{
+ (void)argc;
+ (void)argv;
+ LogInfo("Hello world!");
+ return 0;
+}
+
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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})
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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;
+}
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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})
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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;
+ LogInfo("Accept event occurred");
+
+ DPL::UnixSocket *client = static_cast<DPL::UnixSocket *>(m_socket.Accept());
+
+ LogInfo("Accepted client remote address: " << client->GetRemoteAddress().ToString());
+ LogInfo("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
+ LogInfo("Starting server...");
+
+ m_socket.Bind(DPL::Address(SOCKET_NAME));
+ m_socket.Listen(5);
+
+ LogInfo("Server started");
+
+ LogInfo("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;
+ LogInfo("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
+ LogInfo("Running threaded server");
+
+ // Run server in thread
+ thread.Run();
+
+ LogInfo("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();
+}
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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})
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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;
+ LogInfo("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;
+ LogInfo("Read!");
+
+ DPL::BinaryQueueAutoPtr data = m_socket.Read(100); // Bad: DLOG cannot log more than about 450 bytes...
+
+ Assert(data.get() != NULL);
+
+ if (data->Empty())
+ {
+ LogInfo("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")
+ {
+ LogInfo("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();
+ LogInfo("Connecting...");
+ m_socket.Connect(DPL::Address("en.wikipedia.org", 80));
+ }
+
+ virtual ~MyApplication()
+ {
+ LogInfo("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();
+}
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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})
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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;
+ LogInfo("First event occurred");
+ }
+
+ virtual void OnEventReceived(const SecondEvent &event)
+ {
+ (void)event;
+ LogInfo("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();
+}
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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(vcore)
+ADD_SUBDIRECTORY(ace)
+ADD_SUBDIRECTORY(widget_dao)
+include(popup/config.cmake)
+include(utils/config.cmake)
+include(localization/config.cmake)
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Path for all tests binary files
+
+######################################################################
+#DB ace
+ADD_CUSTOM_COMMAND(
+ OUTPUT ${CMAKE_BINARY_DIR}/modules/ace/database_checksum_ace.h
+ COMMAND ${CMAKE_SOURCE_DIR}/modules/ace/orm/gen_db_md5.sh
+ ARGS ${CMAKE_BINARY_DIR}/modules/ace/database_checksum_ace.h
+ ${CMAKE_SOURCE_DIR}/modules/ace/orm/ace_db
+ DEPENDS ${CMAKE_SOURCE_DIR}/modules/ace/orm/ace_db
+ ${CMAKE_SOURCE_DIR}/modules/ace/orm/gen_db_md5.sh
+ COMMENT "Generating ACE database checksum"
+ )
+ADD_CUSTOM_COMMAND( OUTPUT .ace.db
+ COMMAND rm -f ${CMAKE_CURRENT_BINARY_DIR}/.ace.db
+ COMMAND gcc -Wall -include ${CMAKE_BINARY_DIR}/modules/ace/database_checksum_ace.h -I${PROJECT_SOURCE_DIR}/modules/db/include -I${PROJECT_SOURCE_DIR}/modules/ace/orm -E ${PROJECT_SOURCE_DIR}/modules/ace/orm/ace_db_sql_generator.h | grep --invert-match "^#" > ${CMAKE_CURRENT_BINARY_DIR}/ace_db.sql
+ COMMAND sqlite3 ${CMAKE_CURRENT_BINARY_DIR}/.ace.db ".read ${CMAKE_CURRENT_BINARY_DIR}/ace_db.sql" || rm -f ${CMAKE_CURRENT_BINARY_DIR}/.ace.db
+ DEPENDS ${CMAKE_BINARY_DIR}/modules/ace/database_checksum_ace.h ${PROJECT_SOURCE_DIR}/modules/ace/orm/ace_db_sql_generator.h ${PROJECT_SOURCE_DIR}/modules/ace/orm/ace_db
+ )
+
+ADD_CUSTOM_COMMAND( OUTPUT .ace.db-journal
+ COMMAND touch
+ ARGS ${CMAKE_CURRENT_BINARY_DIR}/.ace.db-journal
+ )
+
+ADD_CUSTOM_TARGET(Sqlite3DbACE ALL DEPENDS .ace.db .ace.db-journal)
+
+INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/ace_db.sql
+ DESTINATION share/wrt-engine/
+ )
+
+###########################################################
+
+INCLUDE(FindPkgConfig)
+
+SET(ACE_TEST_PATH "/usr/apps/org.tizen.policy")
+
+INSTALL(FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/configuration/config.xml
+ ${CMAKE_CURRENT_SOURCE_DIR}/configuration/config.dtd
+ ${CMAKE_CURRENT_SOURCE_DIR}/configuration/bondixml.xsd
+ ${CMAKE_CURRENT_SOURCE_DIR}/configuration/demo.xml
+ ${CMAKE_CURRENT_SOURCE_DIR}/configuration/WACPolicy.xml
+ ${CMAKE_CURRENT_SOURCE_DIR}/configuration/UnrestrictedPolicy.xml
+ DESTINATION /usr/etc/ace
+ PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ GROUP_WRITE)
+
+add_subdirectory(dao)
+
+SET(ACE_LIB_DEPS_BASIC
+ ecore
+ appcore-efl
+ openssl
+ sqlite3
+ heynoti
+ dlog
+ vconf
+ db-util
+ libpcrecpp
+ icu-uc
+ libxml-2.0
+ )
+
+IF(SMACK_ENABLED)
+ LIST(APPEND ACE_LIB_DEPS_BASIC libprivilege-control)
+ENDIF(SMACK_ENABLED)
+
+PKG_CHECK_MODULES(ACE_LIB_DEPS ${ACE_LIB_DEPS_BASIC} REQUIRED)
+
+SET(WRT_ACE_DIR ${PROJECT_SOURCE_DIR}/modules/ace)
+
+SET(ACE_SOURCES
+ ${WRT_ACE_DIR}/engine/PolicyEvaluator.cpp
+ ${WRT_ACE_DIR}/engine/PolicyInformationPoint.cpp
+ ${WRT_ACE_DIR}/engine/CombinerImpl.cpp
+ ${WRT_ACE_DIR}/engine/parser.cpp
+ ${WRT_ACE_DIR}/engine/PolicyEnforcementPoint.cpp
+ ${WRT_ACE_DIR}/engine/SettingsLogic.cpp
+ ${WRT_ACE_DIR}/engine/Attribute.cpp
+ ${WRT_ACE_DIR}/engine/Condition.cpp
+ ${WRT_ACE_DIR}/engine/NodeFactory.cpp
+ ${WRT_ACE_DIR}/engine/Policy.cpp
+ ${WRT_ACE_DIR}/engine/Rule.cpp
+ ${WRT_ACE_DIR}/engine/Serializer.cpp
+ ${WRT_ACE_DIR}/engine/Subject.cpp
+ ${WRT_ACE_DIR}/engine/TreeNode.cpp
+ ${WRT_ACE_DIR}/engine/ConfigurationManager.cpp
+)
+
+INCLUDE_DIRECTORIES(${ACE_LIB_DEPS_INCLUDE_DIRS})
+INCLUDE_DIRECTORIES(${WRT_ACE_DIR}/include)
+INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/modules/core/include)
+INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/modules/db/include)
+INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/modules/log/include)
+INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/modules/event/include)
+
+SET(WITH_ACE_SETTINGS_SERVER_SOURCES
+ ${WITH_ACE_SETTINGS_SERVER_NONE_SOURCES}
+ )
+
+ADD_LIBRARY(${TARGET_ACE_LIB} SHARED
+ ${ACE_SOURCES}
+ ${WITH_ACE_SETTINGS_SERVER_SOURCES}
+)
+
+SET_TARGET_PROPERTIES(${TARGET_ACE_LIB} PROPERTIES
+ SOVERSION ${VERSION})
+
+SET_TARGET_PROPERTIES(${TARGET_ACE_LIB} PROPERTIES
+ COMPILE_FLAGS -fPIC)
+
+TARGET_LINK_LIBRARIES(${TARGET_ACE_LIB}
+# ${TARGET_WRT_DAO_RW_LIB} #For now WRT has to be RW - Global dao write is needed
+ ${TARGET_ACE_DAO_RW_LIB}
+ ${ACE_LIB_DEPS_LIBRARIES}
+ ${DPL_EFL_LIBRARY}
+)
+
+INSTALL(TARGETS ${TARGET_ACE_LIB}
+ DESTINATION lib
+ PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
+ GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
+)
+
+INSTALL(FILES
+ include/dpl/ace/AbstractPolicyEnforcementPoint.h
+ include/dpl/ace/AbstractTreeElement.h
+ include/dpl/ace/Attribute.h
+ include/dpl/ace/AsyncVerdictResultListener.h
+ include/dpl/ace/Combiner.h
+ include/dpl/ace/CombinerImpl.h
+ include/dpl/ace/ConfigurationManager.h
+ include/dpl/ace/Constants.h
+ include/dpl/ace/Effect.h
+ include/dpl/ace/PermissionTriple.h
+ include/dpl/ace/Policy.h
+ include/dpl/ace/PolicyEffect.h
+ include/dpl/ace/PolicyEnforcementPoint.h
+ include/dpl/ace/PolicyEvaluator.h
+ include/dpl/ace/PolicyEvaluatorFactory.h
+ include/dpl/ace/PolicyInformationPoint.h
+ include/dpl/ace/PolicyResult.h
+ include/dpl/ace/Preference.h
+ include/dpl/ace/PromptDecision.h
+ include/dpl/ace/Request.h
+ include/dpl/ace/SettingsLogic.h
+ include/dpl/ace/Subject.h
+ include/dpl/ace/TreeNode.h
+ include/dpl/ace/UserDecision.h
+ include/dpl/ace/WRT_INTERFACE.h
+ include/dpl/ace/Verdict.h
+ DESTINATION
+ include/dpl-efl/dpl/ace
+ )
+
--- /dev/null
+!!!options!!! stop
+ACE - Access Control Engine - security module for Device APIs
--- /dev/null
+<policy-set id="Policy-1" combine="first-matching-target">
+ <policy>
+ <rule effect="permit" />
+ </policy>
+</policy-set>
--- /dev/null
+<!DOCTYPE signed-policy SYSTEM "bondixml.dtd">
+
+<signed-policy>
+
+ <Signature Id="SignatureExample" xmlns="http://www.w3.org/2000/09/xmldsig#">
+ <SignedInfo>
+ <CanonicalizationMethod Algorithm="http://www.w2.org/2006/12/xml-c14n11"/>
+ <SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
+ <Reference URI="Policy-1">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ </SignedInfo>
+ <SignatureValue>asdfkjlhxvczxnbcvnjahfjhsdfklahfdas</SignatureValue>
+ <KeyInfo>
+ <KeyValue>
+ <DSAKeyValue>
+ <P> PValue </P><Q> QValue </Q><G> Gvalue </G><Y> laj?</Y>
+ </DSAKeyValue>
+ <RSAKeyValue>
+ <Modulus>
+ modulus
+ </Modulus>
+ <Exponent>
+ exponent
+ </Exponent>
+ </RSAKeyValue>
+ </KeyValue>
+ <X509Data>
+ <X509SubjectName> Subject name </X509SubjectName>
+ <X509SKI> SKI </X509SKI>
+ </X509Data>
+ </KeyInfo>
+ </Signature>
+
+ <policy-set id="Policy-1" combine="first-matching-target">
+
+<!--
+ <policy-set combine="deny-overrides" >
+ <target>
+ <subject>
+ <subject-match attr="JilSecurityDomain">
+ Unidentified
+ </subject-match>
+ </subject>
+ </target>
+ <policy combine="deny-overrides">
+ <rule effect="prompt-oneshot">
+ <condition combine="or" >
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/addressbookitem.AddressBookItem.update
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.Camera.captureImage
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/device.Device.launchApplication
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/devicestateinfo.DeviceStateInfo.requestPositionInfo
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/messaging.Messaging.sendMessage
+ </resource-match>
+ </condition>
+ </rule>
+ <rule effect="prompt-session">
+ <condition combine="or" >
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.1/pim.PIM.findAddressBookItems
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.1/pim.PIM.getAddressBookItem
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.1/pim.PIM.getAddressBookItemsCount
+ </resource-match>
+ </condition>
+ </rule>
+ <rule effect="prompt-blanket">
+ <condition combine="or" >
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/device.Device.getAvailableApplications
+ </resource-match>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="or" >
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/device.Device.PositionInfo
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/device.Device.DeviceStateInfo
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/addressbookitem.AddressBookItem.getAttributeValue
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/addressbookitem.AddressBookItem.getAvailableAttributes
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/addressbookitem.AddressBookItem.setAttributeValue
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.AudioPlayer.open
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.AudioPlayer.play
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.AudioPlayer.pause
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.AudioPlayer.resume
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.AudioPlayer.stop
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.AudioPlayer.onStateChange
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.Camera.onCameraCaptured
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.Camera.setWindow
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/devicestateinfo.DeviceStateInfo.onPositionRetrieved
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/messaging.Messaging.createMessage
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/messaging.Messaging.onMessageSendingFailure
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.Multimedia.getVolume
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.Multimedia.stopAll
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.Multimedia.isAudioPlaying
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.1/pim.PIM.createAddressBookItem
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.1/pim.PIM.onAddressBookItemFound
+ </resource-match>
+
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/accelerometerinfo
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/addressbookitem
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.5/applicationtypes
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.2/camera
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/device
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/devicestateinfo
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.5/exception
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.5/exceptiontypes
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/message
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/messagetypes
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/messaging
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.1/pim
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/positioninfo
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/widget
+ </resource-match>
+ </condition>
+ </rule>
+ <rule effect="permit" />
+ </policy>
+ </policy-set>
+-->
+ <policy-set combine="deny-overrides" >
+ <target>
+ <subject>
+ <subject-match attr="JilSecurityDomain">
+ Identified
+ </subject-match>
+ </subject>
+ </target>
+ <policy combine="deny-overrides">
+ <rule effect="prompt-session">
+ <condition combine="or" >
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/devicestateinfo.DeviceStateInfo.requestPositionInfo
+ </resource-match>
+ </condition>
+ </rule>
+ <rule effect="prompt-blanket">
+ <condition combine="or" >
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/widget.Widget.openURL
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/addressbookitem.AddressBookItem.update
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/device.Device.launchApplication
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.Camera.captureImage
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/messaging.Messaging.sendMessage
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.1/pim.PIM.findAddressBookItems
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.1/pim.PIM.getAddressBookItem
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.1/pim.PIM.getAddressBookItemsCount
+ </resource-match>
+ </condition>
+ </rule>
+ <!-- If the resource was not specified above then the access is unrestricted -->
+ <rule effect="permit">
+ <condition combine="or" >
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/device.Device.getAvailableApplications
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/addressbookitem.AddressBookItem.getAttributeValue
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/addressbookitem.AddressBookItem.getAvailableAttributes
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/addressbookitem.AddressBookItem.setAttributeValue
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.AudioPlayer.open
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.AudioPlayer.play
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.AudioPlayer.pause
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.AudioPlayer.resume
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.AudioPlayer.stop
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.AudioPlayer.onStateChange
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.Camera.onCameraCaptured
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.Camera.setWindow
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/device.Device.PositionInfo
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/device.Device.DeviceStateInfo
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/devicestateinfo.DeviceStateInfo.onPositionRetrieved
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/messaging.Messaging.createMessage
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/messaging.Messaging.onMessageSendingFailure
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.Multimedia.getVolume
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.Multimedia.stopAll
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.Multimedia.isAudioPlaying
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.1/pim.PIM.createAddressBookItem
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.1/pim.PIM.onAddressBookItemFound
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/accelerometerinfo
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/addressbookitem
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.5/applicationtypes
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.2/camera
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/device
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/devicestateinfo
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.5/exception
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.5/exceptiontypes
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/message
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/messagetypes
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/messaging
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.1/pim
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/positioninfo
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/widget
+ </resource-match>
+ </condition>
+ </rule>
+ <rule effect="permit" />
+ </policy>
+ </policy-set>
+
+ <policy-set combine="deny-overrides" >
+ <target>
+ <subject>
+ <subject-match attr="JilSecurityDomain">
+ Operator
+ </subject-match>
+ </subject>
+ </target>
+ <policy combine="deny-overrides">
+<!-- <rule effect="permit">
+ <condition combine="or" >
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/device.Device.launchApplication
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/devicestateinfo.DeviceStateInfo.requestPositionInfo
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/addressbookitem.AddressBookItem.update
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/device.Device.getAvailableApplications
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/addressbookitem.AddressBookItem.getAttributeValue
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/addressbookitem.AddressBookItem.getAvailableAttributes
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/addressbookitem.AddressBookItem.setAttributeValue
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.AudioPlayer.open
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.AudioPlayer.play
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.AudioPlayer.pause
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.AudioPlayer.resume
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.AudioPlayer.stop
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.AudioPlayer.onStateChange
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.Camera.onCameraCaptured
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.Camera.setWindow
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.Camera.captureImage
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/device.Device.DeviceStateInfo
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/device.Device.PositionInfo
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/devicestateinfo.DeviceStateInfo.onPositionRetrieved
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/messaging.Messaging.createMessage
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/messaging.Messaging.sendMessage
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/messaging.Messaging.onMessageSendingFailure
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.Multimedia.getVolume
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.Multimedia.stopAll
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.Multimedia.isAudioPlaying
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.1/pim.PIM.createAddressBookItem
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.1/pim.PIM.onAddressBookItemsFound
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.1/pim.PIM.findAddressBookItems
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.1/pim.PIM.getAddressBookItem
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.1/pim.PIM.getAddressBookItemsCount
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/accelerometerinfo
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/addressbookitem
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.5/applicationtypes
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.2/camera
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/device
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/devicestateinfo
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.5/exception
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.5/exceptiontypes
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/message
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/messagetypes
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/messaging
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.1/pim
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/positioninfo
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/widget
+ </resource-match>
+ </condition>
+ </rule> -->
+ <rule effect="permit" />
+ </policy>
+ </policy-set>
+</policy-set>
+</signed-policy>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
+ <xs:element name="policy-set">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element minOccurs="0" ref="target"/>
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element ref="policy-set"/>
+ <xs:element ref="policy"/>
+ </xs:choice>
+ </xs:sequence>
+ <xs:attributeGroup ref="policy-set.attlist"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:attributeGroup name="policy-set.attlist">
+ <xs:attribute name="combine" default="deny-overrides">
+ <xs:simpleType>
+ <xs:restriction base="xs:token">
+ <xs:enumeration value="deny-overrides"/>
+ <xs:enumeration value="permit-overrides"/>
+ <xs:enumeration value="first-matching-target"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ <xs:attribute name="id"/>
+ </xs:attributeGroup>
+ <xs:element name="policy">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element minOccurs="0" ref="target"/>
+ <xs:element minOccurs="0" maxOccurs="unbounded" ref="rule"/>
+ </xs:sequence>
+ <xs:attributeGroup ref="policy.attlist"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:attributeGroup name="policy.attlist">
+ <xs:attribute name="combine" default="deny-overrides">
+ <xs:simpleType>
+ <xs:restriction base="xs:token">
+ <xs:enumeration value="deny-overrides"/>
+ <xs:enumeration value="permit-overrides"/>
+ <xs:enumeration value="first-applicable"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ <xs:attribute name="description"/>
+ <xs:attribute name="id"/>
+ </xs:attributeGroup>
+ <xs:element name="rule">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element minOccurs="0" ref="condition"/>
+ </xs:sequence>
+ <xs:attributeGroup ref="rule.attlist"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:attributeGroup name="rule.attlist">
+ <xs:attribute name="effect" default="permit">
+ <xs:simpleType>
+ <xs:restriction base="xs:token">
+ <xs:enumeration value="permit"/>
+ <xs:enumeration value="prompt-blanket"/>
+ <xs:enumeration value="prompt-session"/>
+ <xs:enumeration value="prompt-oneshot"/>
+ <xs:enumeration value="deny"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ </xs:attributeGroup>
+ <xs:element name="target">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element maxOccurs="unbounded" ref="subject"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="subject">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element maxOccurs="unbounded" ref="subject-match"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="condition">
+ <xs:complexType>
+ <xs:choice maxOccurs="unbounded">
+ <xs:element ref="condition"/>
+ <xs:element ref="subject-match"/>
+ <xs:element ref="resource-match"/>
+ <xs:element ref="environment-match"/>
+ </xs:choice>
+ <xs:attributeGroup ref="condition.attlist"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:attributeGroup name="condition.attlist">
+ <xs:attribute name="combine" default="and">
+ <xs:simpleType>
+ <xs:restriction base="xs:token">
+ <xs:enumeration value="and"/>
+ <xs:enumeration value="or"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ </xs:attributeGroup>
+ <xs:attributeGroup name="match-attrs">
+ <xs:attribute name="attr" use="required"/>
+ <xs:attribute name="match"/>
+ <xs:attribute name="func" default="glob">
+ <xs:simpleType>
+ <xs:restriction base="xs:token">
+ <xs:enumeration value="equal"/>
+ <xs:enumeration value="glob"/>
+ <xs:enumeration value="regexp"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ </xs:attributeGroup>
+ <xs:element name="subject-match">
+ <xs:complexType mixed="true">
+ <xs:attributeGroup ref="subject-match.attlist"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:attributeGroup name="subject-match.attlist">
+ <xs:attributeGroup ref="match-attrs"/>
+ </xs:attributeGroup>
+ <xs:complexType name="match-model" mixed="true">
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element ref="subject-attr"/>
+ <xs:element ref="resource-attr"/>
+ <xs:element ref="environment-attr"/>
+ </xs:choice>
+ </xs:complexType>
+ <xs:element name="resource-match">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:extension base="match-model">
+ <xs:attributeGroup ref="resource-match.attlist"/>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:attributeGroup name="resource-match.attlist">
+ <xs:attributeGroup ref="match-attrs"/>
+ </xs:attributeGroup>
+ <xs:element name="environment-match">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:extension base="match-model">
+ <xs:attributeGroup ref="environment-match.attlist"/>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:attributeGroup name="environment-match.attlist">
+ <xs:attributeGroup ref="match-attrs"/>
+ </xs:attributeGroup>
+ <xs:attributeGroup name="attr-attrs">
+ <xs:attribute name="attr" use="required"/>
+ </xs:attributeGroup>
+ <xs:element name="subject-attr">
+ <xs:complexType>
+ <xs:attributeGroup ref="subject-attr.attlist"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:attributeGroup name="subject-attr.attlist">
+ <xs:attributeGroup ref="attr-attrs"/>
+ </xs:attributeGroup>
+ <xs:element name="resource-attr">
+ <xs:complexType>
+ <xs:attributeGroup ref="resource-attr.attlist"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:attributeGroup name="resource-attr.attlist">
+ <xs:attributeGroup ref="attr-attrs"/>
+ </xs:attributeGroup>
+ <xs:element name="environment-attr">
+ <xs:complexType>
+ <xs:attributeGroup ref="environment-attr.attlist"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:attributeGroup name="environment-attr.attlist">
+ <xs:attributeGroup ref="attr-attrs"/>
+ </xs:attributeGroup>
+</xs:schema>
--- /dev/null
+<!ELEMENT manager-settings ( storage-path, policy-files ) >
+
+<!ELEMENT storage-path (#PCDATA)>
+
+<!ELEMENT policy-files (file*)>
+
+<!ELEMENT file (#PCDATA)>
+<!ATTLIST file
+ active (true|false) "false"
+>
--- /dev/null
+<?xml version="1.0" ?>
+<!DOCTYPE manager-settings SYSTEM "config.dtd">
+<manager-settings>
+ <storage-path>/usr/etc/ace/</storage-path>
+ <policy-files>
+ <file active="true">demo.xml</file>
+ </policy-files>
+</manager-settings>
+
+
--- /dev/null
+<policy-set id="Policy-1" combine="first-matching-target">
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="name" match="demoMSG" />
+ </subject>
+ </target>
+ <rule effect="deny" />
+ </policy>
+
+ <policy>
+ <rule effect="permit" />
+ </policy>
+</policy-set>
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ *
+ *
+ * @file AceDAO.cpp
+ * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @version 0.1
+ * @brief
+ */
+
+#include <dpl/ace-dao-rw/AceDAO.h>
+
+#include <openssl/md5.h>
+#include <dpl/foreach.h>
+#include <dpl/string.h>
+#include <dpl/log/log.h>
+#include <dpl/db/orm.h>
+#include <dpl/ace-dao-ro/AceDAOUtilities.h>
+#include <dpl/ace-dao-ro/AceDAOConversions.h>
+#include <dpl/ace-dao-ro/AceDatabase.h>
+
+using namespace DPL::DB::ORM;
+using namespace DPL::DB::ORM::ace;
+using namespace AceDB::AceDaoUtilities;
+using namespace AceDB::AceDaoConversions;
+
+namespace {
+char const * const EMPTY_SESSION = "";
+} // namespace
+
+namespace AceDB{
+
+void AceDAO::setPromptDecision(
+ const DPL::String &hash,
+ const DPL::String &userParam,
+ const DPL::OptionalString &session,
+ PromptDecision decision)
+{
+ Try {
+ ScopedTransaction transaction(&AceDaoUtilities::m_databaseInterface);
+
+ ACE_DB_DELETE(del, AcePromptDecision, &AceDaoUtilities::m_databaseInterface);
+ del->Where(
+ And(
+ Equals<AcePromptDecision::user_param>(userParam),
+ Equals<AcePromptDecision::hash>(hash)));
+ del->Execute();
+
+ AcePromptDecision::Row row;
+ row.Set_hash(hash);
+ row.Set_decision(promptDecisionToInt(decision));
+ row.Set_user_param(userParam);
+ row.Set_session(session);
+ ACE_DB_INSERT(insert, AcePromptDecision, &AceDaoUtilities::m_databaseInterface);
+ insert->Values(row);
+ insert->Execute();
+
+ transaction.Commit();
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(Exception::DatabaseError, "Failed to setUserSetting");
+ }
+}
+
+void AceDAO::setPromptDecision(
+ const BaseAttributeSet &attributes,
+ const DPL::String &userParam,
+ const DPL::OptionalString &session,
+ PromptDecision decision)
+{
+ DPL::String DPLHash = convertToHash(attributes);
+
+ setPromptDecision(
+ DPLHash,
+ userParam,
+ session,
+ decision);
+}
+
+void AceDAO::removePolicyResult(
+ const BaseAttributeSet &attributes)
+{
+ Try {
+ ScopedTransaction transaction(&AceDaoUtilities::m_databaseInterface);
+
+ auto attrHash = convertToHash(attributes);
+
+ ACE_DB_DELETE(del,
+ AcePolicyResult,
+ &AceDaoUtilities::m_databaseInterface);
+ del->Where(Equals<AcePolicyResult::hash>(attrHash));
+ del->Execute();
+ transaction.Commit();
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(Exception::DatabaseError, "Failed to removeVerdict");
+ }
+}
+
+void AceDAO::clearAllSettings(void)
+{
+ clearWidgetDevCapSettings();
+ clearDevCapSettings();
+}
+
+void AceDAO::setDevCapSetting(const std::string &resource,
+ PreferenceTypes preference)
+{
+ Try {
+ ACE_DB_UPDATE(update, AceDevCap, &AceDaoUtilities::m_databaseInterface);
+ AceDevCap::Row row;
+ row.Set_general_setting(preferenceToInt(preference));
+ update->Values(row);
+ update->Where(
+ Equals<AceDevCap::id_uri>(DPL::FromUTF8String(resource)));
+ update->Execute();
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(Exception::DatabaseError, "Failed to SetResourceSetting");
+ }
+}
+
+void AceDAO::removeDevCapSetting(const std::string &resource)
+{
+ Try {
+ ACE_DB_UPDATE(update, AceDevCap, &AceDaoUtilities::m_databaseInterface);
+ AceDevCap::Row row;
+ row.Set_general_setting(preferenceToInt(PreferenceTypes::PREFERENCE_DEFAULT));
+ update->Values(row);
+ update->Where(
+ Equals<AceDevCap::id_uri>(DPL::FromUTF8String(resource)));
+ update->Execute();
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(Exception::DatabaseError, "Failed to removeResourceSetting");
+ }
+}
+
+
+void AceDAO::setWidgetDevCapSetting(const std::string &resource,
+ WidgetHandle handler,
+ PreferenceTypes preference)
+{
+ Try {
+ ScopedTransaction transaction(&AceDaoUtilities::m_databaseInterface);
+ // TODO JOIN
+ AceDevCap::Row rrow;
+ if (!getResourceByUri(resource, rrow)) {
+ ThrowMsg(Exception::DatabaseError, "Resource not found");
+ }
+
+ ACE_DB_INSERT(insert,
+ AceWidgetDevCapSetting,
+ &AceDaoUtilities::m_databaseInterface);
+
+ AceWidgetDevCapSetting::Row row;
+ row.Set_app_id(handler);
+ int rid = rrow.Get_resource_id();
+ row.Set_resource_id(rid);
+ row.Set_access_value(preferenceToInt(preference));
+ insert->Values(row);
+ insert->Execute();
+
+ transaction.Commit();
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(Exception::DatabaseError, "Failed to setUserSetting");
+ }
+}
+
+void AceDAO::removeWidgetDevCapSetting(const std::string &resource,
+ WidgetHandle handler)
+{
+ Try {
+ ScopedTransaction transaction(&AceDaoUtilities::m_databaseInterface);
+ AceDevCap::Row rrow;
+ if (!getResourceByUri(resource, rrow)) {
+ ThrowMsg(Exception::DatabaseError, "resource not found");
+ }
+
+ ACE_DB_DELETE(del,
+ AceWidgetDevCapSetting,
+ &AceDaoUtilities::m_databaseInterface);
+
+ Equals<AceWidgetDevCapSetting::app_id> e1(handler);
+ Equals<AceWidgetDevCapSetting::resource_id> e2(rrow.Get_resource_id());
+ del->Where(And(e1, e2));
+ del->Execute();
+ transaction.Commit();
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(Exception::DatabaseError, "Failed to clearUserSettings");
+ }
+}
+
+
+void AceDAO::setPolicyResult(const BaseAttributeSet &attributes,
+ const PolicyResult &policyResult)
+{
+ Try {
+ ScopedTransaction transaction(&AceDaoUtilities::m_databaseInterface);
+
+ // TODO: this call is connected with logic.
+ // It should be moved to PolicyEvaluator
+ addAttributes(attributes);
+
+ auto attrHash = convertToHash(attributes);
+
+ ACE_DB_DELETE(del, AcePolicyResult, &AceDaoUtilities::m_databaseInterface)
+ del->Where(Equals<AcePolicyResult::hash>(attrHash));
+ del->Execute();
+
+ ACE_DB_INSERT(insert, AcePolicyResult, &AceDaoUtilities::m_databaseInterface);
+ AcePolicyResult::Row row;
+ row.Set_decision(PolicyResult::serialize(policyResult));
+ row.Set_hash(attrHash);
+ insert->Values(row);
+ insert->Execute();
+
+ transaction.Commit();
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(Exception::DatabaseError, "Failed to addVerdict");
+ }
+}
+
+void AceDAO::resetDatabase(void)
+{
+ Try {
+ ScopedTransaction transaction(&AceDaoUtilities::m_databaseInterface);
+ ACE_DB_DELETE(del1, AcePolicyResult, &AceDaoUtilities::m_databaseInterface);
+ del1->Execute();
+ ACE_DB_DELETE(del2, AceWidgetDevCapSetting, &AceDaoUtilities::m_databaseInterface);
+ del2->Execute();
+ ACE_DB_DELETE(del3, AceDevCap, &AceDaoUtilities::m_databaseInterface);
+ del3->Execute();
+ ACE_DB_DELETE(del4, AceSubject, &AceDaoUtilities::m_databaseInterface);
+ del4->Execute();
+ ACE_DB_DELETE(del5, AceAttribute, &AceDaoUtilities::m_databaseInterface);
+ del5->Execute();
+ ACE_DB_DELETE(del6, AcePromptDecision, &AceDaoUtilities::m_databaseInterface);
+ del6->Execute();
+
+ transaction.Commit();
+
+ // TODO there is no such query yet in ORM.
+ // GlobalConnection::DataCommandAutoPtr command =
+ // GlobalConnectionSingleton::Instance().PrepareDataCommand(
+ // "VACUUM");
+ // command->Step();
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(Exception::DatabaseError, "Failed to resetDatabase");
+ }
+}
+
+void AceDAO::clearDevCapSettings()
+{
+ Try {
+ ACE_DB_UPDATE(update, AceDevCap, &AceDaoUtilities::m_databaseInterface);
+ AceDevCap::Row row;
+ row.Set_general_setting(-1);
+ update->Values(row);
+ update->Execute();
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(Exception::DatabaseError, "Failed to clearResourceSettings");
+ }
+}
+
+void AceDAO::clearWidgetDevCapSettings()
+{
+ Try {
+ ACE_DB_DELETE(del, AceWidgetDevCapSetting, &AceDaoUtilities::m_databaseInterface);
+ del->Execute();
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(Exception::DatabaseError, "Failed to clearUserSettings");
+ }
+}
+
+int AceDAO::addResource(const std::string &request)
+{
+ LogDebug("addResource: " << request);
+ Try {
+ ScopedTransaction transaction(&AceDaoUtilities::m_databaseInterface);
+ AceDevCap::Row rrow;
+ if (getResourceByUri(request, rrow)) {
+ transaction.Commit();
+ return rrow.Get_resource_id();
+ }
+
+ ACE_DB_INSERT(insert, AceDevCap, &AceDaoUtilities::m_databaseInterface);
+ AceDevCap::Row row;
+ row.Set_id_uri(DPL::FromUTF8String(request));
+ row.Set_general_setting(-1);
+ insert->Values(row);
+ int id = insert->Execute();
+ transaction.Commit();
+ return id;
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(Exception::DatabaseError, "Failed in addResource");
+ }
+}
+
+void AceDAO::addAttributes(const BaseAttributeSet &attributes)
+{
+ Try {
+ BaseAttributeSet::const_iterator iter;
+
+ for (iter = attributes.begin(); iter != attributes.end(); ++iter) {
+ ACE_DB_SELECT(select, AceAttribute, &AceDaoUtilities::m_databaseInterface);
+ select->Where(Equals<AceAttribute::name>(DPL::FromUTF8String(
+ *(*iter)->getName())));
+ std::list<AceAttribute::Row> rows = select->GetRowList();
+ if (!rows.empty()) {
+ continue;
+ }
+
+ ACE_DB_INSERT(insert, AceAttribute, &AceDaoUtilities::m_databaseInterface);
+ AceAttribute::Row row;
+ row.Set_name(DPL::FromUTF8String(*(*iter)->getName()));
+ row.Set_type(attributeTypeToInt((*iter)->getType()));
+ insert->Values(row);
+ insert->Execute();
+ }
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(Exception::DatabaseError, "Failed in addAttributes");
+ }
+}
+
+void AceDAO::setStaticDevCapPermissions(
+ int widgetHandle,
+ const std::set<DPL::String> &permissions)
+{
+ Try {
+ FOREACH(it, permissions) {
+ ACE_DB_INSERT(insert, AceStaticDevCapPermission,
+ &AceDaoUtilities::m_databaseInterface);
+ AceStaticDevCapPermission::Row row;
+ row.Set_app_id(widgetHandle);
+ row.Set_dev_cap(*it);
+ insert->Values(row);
+ insert->Execute();
+ }
+ } Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(Exception::DatabaseError, "Failed in setStaticDevCapPermissions");
+ }
+}
+
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ *
+ *
+ * @file AceDaoConversions.h
+ * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @author Grzegorz Krawczyk (g.krawczyk@samsung.com)
+ * @version 0.1
+ * @brief
+ */
+
+#include <openssl/md5.h>
+#include <dpl/foreach.h>
+
+#include <dpl/ace-dao-ro/AceDAOConversions.h>
+
+namespace AceDB {
+
+DPL::String AceDaoConversions::convertToHash(const BaseAttributeSet &attributes)
+{
+ unsigned char attrHash[MD5_DIGEST_LENGTH];
+ std::string attrString;
+ FOREACH(it, attributes) {
+ // [CR] implementation of it->toString() is not secure, 24.03.2010
+ attrString.append((*it)->toString());
+ }
+
+ MD5((unsigned char *) attrString.c_str(), attrString.length(), attrHash);
+
+ char attrHashCoded[MD5_DIGEST_LENGTH*2 + 1];
+ for (int i = 0; i < MD5_DIGEST_LENGTH; ++i) {
+ sprintf(&attrHashCoded[i << 1],
+ "%02X",
+ static_cast<int>(attrHash[i]));
+ }
+ return DPL::FromASCIIString(attrHashCoded);
+}
+
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ *
+ *
+ * @file AceDAOReadOnlyReadOnly.cpp
+ * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @author Grzegorz Krawczyk (g.krawczyk@samsung.com)
+ * @version 0.1
+ * @brief
+ */
+
+#include <dpl/ace-dao-ro/AceDAOReadOnly.h>
+#include <dpl/ace-dao-ro/AceDAOUtilities.h>
+#include <dpl/ace-dao-ro/AceDAOConversions.h>
+#include <dpl/ace-dao-ro/AceDatabase.h>
+
+#include <dpl/foreach.h>
+
+using namespace DPL::DB::ORM;
+using namespace DPL::DB::ORM::ace;
+using namespace AceDB::AceDaoUtilities;
+using namespace AceDB::AceDaoConversions;
+
+namespace AceDB {
+
+static const int DB_ALLOW_ALWAYS = 0;
+static const int DB_ALLOW_FOR_SESSION = 1;
+static const int DB_ALLOW_THIS_TIME = 2;
+static const int DB_DENY_ALWAYS = 3;
+static const int DB_DENY_FOR_SESSION = 4;
+static const int DB_DENY_THIS_TIME = 5;
+
+int AceDAOReadOnly::promptDecisionToInt(PromptDecision decision)
+{
+ if (PromptDecision::ALLOW_ALWAYS == decision) {
+ return DB_ALLOW_ALWAYS;
+ } else if (PromptDecision::DENY_ALWAYS == decision) {
+ return DB_DENY_ALWAYS;
+ } else if (PromptDecision::ALLOW_THIS_TIME == decision) {
+ return DB_ALLOW_THIS_TIME;
+ } else if (PromptDecision::DENY_THIS_TIME == decision) {
+ return DB_DENY_THIS_TIME;
+ } else if (PromptDecision::ALLOW_FOR_SESSION == decision) {
+ return DB_ALLOW_FOR_SESSION;
+ }
+ // DENY_FOR_SESSION
+ return DB_DENY_FOR_SESSION;
+}
+
+PromptDecision AceDAOReadOnly::intToPromptDecision(int dec) {
+ if (dec == DB_ALLOW_ALWAYS) {
+ return PromptDecision::ALLOW_ALWAYS;
+ } else if (dec == DB_DENY_ALWAYS) {
+ return PromptDecision::DENY_ALWAYS;
+ } else if (dec == DB_ALLOW_THIS_TIME) {
+ return PromptDecision::ALLOW_THIS_TIME;
+ } else if (dec == DB_DENY_THIS_TIME) {
+ return PromptDecision::DENY_THIS_TIME;
+ } else if (dec == DB_ALLOW_FOR_SESSION) {
+ return PromptDecision::ALLOW_FOR_SESSION;
+ }
+ // DB_DENY_FOR_SESSION
+ return PromptDecision::DENY_FOR_SESSION;
+}
+
+void AceDAOReadOnly::attachToThread()
+{
+ AceDaoUtilities::m_databaseInterface.AttachToThread();
+}
+
+void AceDAOReadOnly::detachFromThread()
+{
+ AceDaoUtilities::m_databaseInterface.DetachFromThread();
+}
+
+OptionalCachedPromptDecision AceDAOReadOnly::getPromptDecision(
+ const DPL::String &hash,
+ const std::string &userParam)
+{
+ Try {
+ ScopedTransaction transaction(&AceDaoUtilities::m_databaseInterface);
+
+ // get matching subject verdict
+ ACE_DB_SELECT(select, AcePromptDecision, &AceDaoUtilities::m_databaseInterface);
+ DPL::String DPLParam = DPL::FromUTF8String(userParam);
+
+ select->Where(
+ And(
+ Equals<AcePromptDecision::hash>(hash),
+ Equals<AcePromptDecision::user_param>(DPLParam)));
+
+ std::list<AcePromptDecision::Row> rows = select->GetRowList();
+ if (rows.empty()) {
+ transaction.Commit();
+ return OptionalCachedPromptDecision();
+ }
+
+ AcePromptDecision::Row row = rows.front();
+ CachedPromptDecision decision;
+ decision.decision = intToPromptDecision(row.Get_decision());
+ decision.session = row.Get_session();
+
+ return OptionalCachedPromptDecision(decision);
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(Exception::DatabaseError, "Failed to getPromptDecision");
+ }
+}
+
+OptionalCachedPromptDecision AceDAOReadOnly::getPromptDecision(
+ const BaseAttributeSet &attributes,
+ const std::string &userParam)
+{
+ return getPromptDecision(convertToHash(attributes), userParam);
+}
+
+void AceDAOReadOnly::getAttributes(BaseAttributeSet *attributes)
+{
+ if (NULL == attributes) {
+ LogError("NULL pointer");
+ return;
+ }
+ attributes->clear();
+ std::string aname;
+ int type;
+ Try {
+ ScopedTransaction transaction(&AceDaoUtilities::m_databaseInterface);
+
+ ACE_DB_SELECT(select, AceAttribute, &AceDaoUtilities::m_databaseInterface);
+ typedef std::list<AceAttribute::Row> RowList;
+ RowList list = select->GetRowList();
+
+ FOREACH(i, list) {
+ BaseAttributePtr attribute(new BaseAttribute());
+ DPL::String name = i->Get_name();
+ aname = DPL::ToUTF8String(name);
+ type = i->Get_type();
+
+ attribute->setName(&aname);
+ attribute->setType(intToAttributeType(type));
+ attributes->insert(attribute);
+ }
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(Exception::DatabaseError, "Failed to getAttributes");
+ }
+}
+
+OptionalPolicyResult AceDAOReadOnly::getPolicyResult(
+ const BaseAttributeSet &attributes)
+{
+
+ auto attrHash = convertToHash(attributes);
+ return getPolicyResult(attrHash);
+}
+
+OptionalPolicyResult AceDAOReadOnly::getPolicyResult(
+ const DPL::String &attrHash)
+{
+ Try {
+ ScopedTransaction transaction(&AceDaoUtilities::m_databaseInterface);
+
+ // get matching subject verdict
+ ACE_DB_SELECT(select, AcePolicyResult, &AceDaoUtilities::m_databaseInterface);
+ Equals<AcePolicyResult::hash> e1(attrHash);
+ select->Where(e1);
+
+ std::list<AcePolicyResult::Row> rows = select->GetRowList();
+ if (rows.empty()) {
+ transaction.Commit();
+ return OptionalPolicyResult();
+ }
+
+ AcePolicyResult::Row row = rows.front();
+ int decision = row.Get_decision();
+ PolicyResult res = PolicyResult::deserialize(decision);
+ transaction.Commit();
+ return OptionalPolicyResult(res);
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(Exception::DatabaseError, "Failed to getVerdict");
+ }
+}
+
+PreferenceTypes AceDAOReadOnly::getDevCapSetting(const std::string &resource)
+{
+ Try {
+ AceDevCap::Row row;
+ if (!getResourceByUri(resource, row)) {
+ return PreferenceTypes::PREFERENCE_DEFAULT;
+ }
+ return intToPreference(row.Get_general_setting());
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(Exception::DatabaseError, "Failed to getResourceSetting");
+ }
+}
+
+void AceDAOReadOnly::getDevCapSettings(PreferenceTypesMap *globalSettingsMap)
+{
+ if (NULL == globalSettingsMap) {
+ LogError("Null pointer");
+ return;
+ }
+ globalSettingsMap->clear();
+ Try {
+ ACE_DB_SELECT(select, AceDevCap, &AceDaoUtilities::m_databaseInterface);
+ typedef std::list<AceDevCap::Row> RowList;
+ RowList list = select->GetRowList();
+
+ FOREACH(i, list) {
+ PreferenceTypes p = intToPreference(i->Get_general_setting());
+ globalSettingsMap->insert(make_pair(DPL::ToUTF8String(
+ i->Get_id_uri()), p));
+ }
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(Exception::DatabaseError, "Failed to getResourceSettings");
+ }
+}
+
+
+
+void AceDAOReadOnly::getWidgetDevCapSettings(BasePermissionList *outputList)
+{
+ if (NULL == outputList) {
+ LogError("NULL pointer");
+ return;
+ }
+ outputList->clear();
+ Try {
+ ScopedTransaction transaction(&AceDaoUtilities::m_databaseInterface);
+
+ std::string resourceName;
+ PreferenceTypes allowAccess;
+
+ ACE_DB_SELECT(select,
+ AceWidgetDevCapSetting,
+ &AceDaoUtilities::m_databaseInterface);
+
+ typedef std::list<AceWidgetDevCapSetting::Row> RowList;
+ RowList list = select->GetRowList();
+
+ // TODO JOIN
+ FOREACH(i, list) {
+ int app_id = i->Get_app_id();
+ int res_id = i->Get_resource_id();
+
+ ACE_DB_SELECT(resourceSelect, AceDevCap, &AceDaoUtilities::m_databaseInterface);
+ resourceSelect->Where(Equals<AceDevCap::resource_id>(res_id));
+ AceDevCap::Row rrow = resourceSelect->GetSingleRow();
+
+ resourceName = DPL::ToUTF8String(rrow.Get_id_uri());
+
+ if (!resourceName.empty()) {
+ allowAccess = intToPreference(i->Get_access_value());
+ outputList->push_back(
+ BasePermission(app_id,
+ resourceName,
+ allowAccess));
+ }
+ }
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(Exception::DatabaseError, "Failed to findUserSettings");
+ }
+}
+
+PreferenceTypes AceDAOReadOnly::getWidgetDevCapSetting(
+ const std::string &resource,
+ WidgetHandle handler)
+{
+ Try {
+ ScopedTransaction transaction(&AceDaoUtilities::m_databaseInterface);
+
+ AceDevCap::Row rrow;
+ if (!getResourceByUri(resource, rrow)) {
+ return PreferenceTypes::PREFERENCE_DEFAULT;
+ }
+ int resourceId = rrow.Get_resource_id();
+
+ // get matching user setting
+ ACE_DB_SELECT(select, AceWidgetDevCapSetting, &AceDaoUtilities::m_databaseInterface);
+
+ select->Where(And(Equals<AceWidgetDevCapSetting::resource_id>(resourceId),
+ Equals<AceWidgetDevCapSetting::app_id>(handler)));
+
+ std::list<int> values =
+ select->GetValueList<AceWidgetDevCapSetting::access_value>();
+ if (values.empty()) {
+ return PreferenceTypes::PREFERENCE_DEFAULT;
+ }
+ return intToPreference(values.front());
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(Exception::DatabaseError, "Failed in getUserSetting");
+ }
+}
+
+void AceDAOReadOnly::getStaticDevCapPermissions(
+ int widgetHandle,
+ std::set<DPL::String> *permissions)
+{
+ if (NULL == permissions) {
+ LogError("NULL pointer");
+ return;
+ }
+ permissions->clear();
+ Try {
+ ScopedTransaction transaction(&AceDaoUtilities::m_databaseInterface);
+
+ ACE_DB_SELECT(select, AceStaticDevCapPermission,
+ &AceDaoUtilities::m_databaseInterface);
+ select->Where(
+ Equals<AceStaticDevCapPermission::app_id>(widgetHandle));
+ std::list<DPL::String> devCapNames =
+ select->GetValueList<AceStaticDevCapPermission::dev_cap>();
+ permissions->insert(devCapNames.begin(), devCapNames.end());
+ transaction.Commit();
+ } Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(Exception::DatabaseError, "Failed to getStaticDevCapPermissions");
+ }
+}
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ *
+ *
+ * @file AceDaoReadOnly.h
+ * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @author Grzegorz Krawczyk (g.krawczyk@samsung.com)
+ * @version 0.1
+ * @brief
+ */
+
+#include <openssl/md5.h>
+#include <dpl/assert.h>
+#include <dpl/foreach.h>
+
+#include <dpl/ace-dao-ro/AceDatabase.h>
+#include <dpl/ace-dao-ro/AceDAOUtilities.h>
+#include <dpl/ace-dao-ro/AceDAOReadOnly.h>
+
+namespace AceDB {
+
+namespace {
+const char* ACE_DB_DATABASE = "/opt/dbspace/.ace.db";
+DPL::DB::SqlConnection::Flag::Type ACE_DB_FLAGS =
+ DPL::DB::SqlConnection::Flag::UseLucene;
+}
+
+DPL::DB::ThreadDatabaseSupport AceDaoUtilities::m_databaseInterface(
+ ACE_DB_DATABASE, ACE_DB_FLAGS);
+
+BaseAttribute::Type AceDaoUtilities::intToAttributeType(int val)
+{
+ switch (val) {
+ case 0:
+ return BaseAttribute::Type::Subject;
+ case 1:
+ return BaseAttribute::Type::Environment;
+ case 2:
+ return BaseAttribute::Type::Resource;
+ case 3:
+ return BaseAttribute::Type::FunctionParam;
+
+ default:
+ Assert(0 && "Unknown Attribute type value");
+ return BaseAttribute::Type::Subject; //remove compilation warrning
+ }
+}
+
+int AceDaoUtilities::attributeTypeToInt(BaseAttribute::Type type)
+{
+ // we cannot cast enum -> int because this cast will be removed from next c++ standard
+ switch (type) {
+ case BaseAttribute::Type::Subject:
+ return 0;
+ case BaseAttribute::Type::Environment:
+ return 1;
+ case BaseAttribute::Type::Resource:
+ return 2;
+ case BaseAttribute::Type::FunctionParam:
+ return 3;
+
+ default:
+ Assert(0 && "Unknown Attribute type!");
+ return 0; //remove compilation warrning
+ }
+}
+
+int AceDaoUtilities::preferenceToInt(PreferenceTypes p)
+{
+ switch (p) {
+ case PreferenceTypes::PREFERENCE_PERMIT:
+ return 1;
+ case PreferenceTypes::PREFERENCE_DENY:
+ return 0;
+ case PreferenceTypes::PREFERENCE_BLANKET_PROMPT:
+ return 2;
+ case PreferenceTypes::PREFERENCE_SESSION_PROMPT:
+ return 3;
+ case PreferenceTypes::PREFERENCE_ONE_SHOT_PROMPT:
+ return 4;
+
+ default:
+ return -1;
+ }
+}
+
+PreferenceTypes AceDaoUtilities::intToPreference(int p)
+{
+ switch (p) {
+ case 1:
+ return PreferenceTypes::PREFERENCE_PERMIT;
+ case 0:
+ return PreferenceTypes::PREFERENCE_DENY;
+ case 2:
+ return PreferenceTypes::PREFERENCE_BLANKET_PROMPT;
+ case 3:
+ return PreferenceTypes::PREFERENCE_SESSION_PROMPT;
+ case 4:
+ return PreferenceTypes::PREFERENCE_ONE_SHOT_PROMPT;
+
+ default:
+ return PreferenceTypes::PREFERENCE_DEFAULT;
+ }
+}
+
+VerdictTypes AceDaoUtilities::intToVerdict(int v)
+{
+ switch (v) {
+ case -1:
+ return VerdictTypes::VERDICT_UNKNOWN;
+ case 0:
+ return VerdictTypes::VERDICT_DENY;
+ case 1:
+ return VerdictTypes::VERDICT_PERMIT;
+ case 2:
+ return VerdictTypes::VERDICT_INAPPLICABLE;
+
+ default:
+ Assert(0 && "Cannot convert int to verdict");
+ return VerdictTypes::VERDICT_UNKNOWN; // remove compile warrning
+ }
+}
+
+int AceDaoUtilities::verdictToInt(VerdictTypes v)
+{
+ switch (v) {
+ case VerdictTypes::VERDICT_UNKNOWN:
+ return -1;
+ case VerdictTypes::VERDICT_DENY:
+ return 0;
+ case VerdictTypes::VERDICT_PERMIT:
+ return 1;
+ case VerdictTypes::VERDICT_INAPPLICABLE:
+ return 2;
+
+ default:
+ Assert(0 && "Unknown Verdict value");
+ return -1; // remove compile warrning
+ }
+}
+
+bool AceDaoUtilities::getSubjectByUri(const std::string &uri,
+ DPL::DB::ORM::ace::AceSubject::Row &row)
+{
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::ace;
+ ACE_DB_SELECT(select, AceSubject, &m_databaseInterface);
+ select->Where(Equals<AceSubject::id_uri>(DPL::FromUTF8String(uri)));
+ std::list<AceSubject::Row> rows = select->GetRowList();
+ if (rows.empty()) {
+ return false;
+ }
+
+ row = rows.front();
+ return true;
+}
+
+bool AceDaoUtilities::getResourceByUri(const std::string &uri,
+ DPL::DB::ORM::ace::AceDevCap::Row &row)
+{
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::ace;
+ ACE_DB_SELECT(select, AceDevCap, &m_databaseInterface);
+ select->Where(Equals<AceDevCap::id_uri>(DPL::FromUTF8String(uri)));
+ std::list<AceDevCap::Row> rows = select->GetRowList();
+ if (rows.empty()) {
+ return false;
+ }
+
+ row = rows.front();
+ return true;
+}
+
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file AceDatabase.cpp
+ * @author Lukasz Marek (l.marek@samsung.com)
+ * @version 1.0
+ * @brief This file contains the declaration of ace database
+ */
+
+#include <dpl/ace-dao-ro/AceDatabase.h>
+
+DPL::Mutex g_aceDbQueriesMutex;
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ *
+ *
+ * @file BaseAttribute.cpp
+ * @author Lukasz Marek (l.marek@samsung.com)
+ * @version 0.1
+ * @brief
+ */
+
+#include <sstream>
+#include <string>
+
+#include <dpl/ace-dao-ro/BaseAttribute.h>
+
+namespace AceDB {
+
+const char* BaseAttribute::typeToString(Type type)
+{
+ const char * ret = NULL;
+ switch (type) {
+ case Type::Resource:
+ ret = "resource";
+ break;
+ case Type::Subject:
+ ret = "subject";
+ break;
+ case Type::Environment:
+ ret = "environment";
+ break;
+ default:
+ ret = "unknown type";
+ break;
+ }
+
+ return ret;
+}
+
+std::string BaseAttribute::toString() const
+{
+ std::string ret;
+ const char * SEPARATOR = ";";
+
+ ret.append(m_name);
+ ret.append(SEPARATOR);
+ ret.append(typeToString(m_typeId));
+ ret.append(SEPARATOR);
+ if (m_undetermindState) {
+ ret.append("true");
+ } else {
+ ret.append("false");
+ }
+ ret.append(SEPARATOR);
+ for (std::list<std::string>::const_iterator it = value.begin();
+ it != value.end();
+ ++it) {
+ std::stringstream num;
+ num << it->size();
+ ret.append(num.str());
+ ret.append(SEPARATOR);
+ ret.append(*it);
+ ret.append(SEPARATOR);
+ }
+
+ return ret;
+}
+
+}
--- /dev/null
+
+SET(ACE_DAO_DEPS_LIST
+ ecore
+ appcore-efl
+ openssl
+ vconf
+ db-util
+ libpcrecpp
+ icu-uc
+ libxml-2.0
+ )
+
+PKG_CHECK_MODULES(ACE_DAO_DEPS ${ACE_DAO_DEPS_LIST} REQUIRED)
+
+set(ACE_SRC_DIR ${PROJECT_SOURCE_DIR}/modules/ace/dao)
+
+set(ACE_DAO_RO_SOURCES
+ ${ACE_SRC_DIR}/AceDAOReadOnly.cpp
+ ${ACE_SRC_DIR}/AceDAOUtilities.cpp
+ ${ACE_SRC_DIR}/AceDAOConversions.cpp
+ ${ACE_SRC_DIR}/BaseAttribute.cpp
+ ${ACE_SRC_DIR}/AceDatabase.cpp
+ ${ACE_SRC_DIR}/PromptModel.cpp
+)
+
+set(ACE_DAO_RW_SOURCES
+ ${ACE_SRC_DIR}/AceDAO.cpp
+)
+
+INCLUDE_DIRECTORIES(${ACE_SRC_DIR})
+INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/modules/log/include)
+INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/modules/db/include)
+INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/modules/core/include)
+INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/modules/ace/include)
+INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/modules/ace/orm)
+INCLUDE_DIRECTORIES(${ACE_DAO_DEPS_INCLUDE_DIRS})
+INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/modules/ace/orm)
+
+ADD_LIBRARY(${TARGET_ACE_DAO_RO_LIB} SHARED
+ ${ACE_DAO_RO_SOURCES}
+)
+
+SET_TARGET_PROPERTIES(${TARGET_ACE_DAO_RO_LIB} PROPERTIES
+ SOVERSION ${VERSION})
+
+SET_TARGET_PROPERTIES(${TARGET_ACE_DAO_RO_LIB} PROPERTIES
+ COMPILE_FLAGS -fPIC)
+
+SET_TARGET_PROPERTIES(${TARGET_ACE_DAO_RO_LIB} PROPERTIES
+ COMPILE_FLAGS "-include ${CMAKE_BINARY_DIR}/modules/ace/database_checksum_ace.h")
+
+target_link_libraries(${TARGET_ACE_DAO_RO_LIB}
+ ${TARGET_DPL_EFL}
+ ${TARGET_DPL_DB_EFL}
+ ${ACE_DAO_DEPS_LIBRARY}
+ ${ACE_DAO_DEPS_LDFLAGS}
+)
+
+ADD_LIBRARY(${TARGET_ACE_DAO_RW_LIB} SHARED
+ ${ACE_DAO_RW_SOURCES}
+)
+
+SET_TARGET_PROPERTIES(${TARGET_ACE_DAO_RW_LIB} PROPERTIES
+ SOVERSION ${VERSION})
+
+SET_TARGET_PROPERTIES(${TARGET_ACE_DAO_RW_LIB} PROPERTIES
+ COMPILE_FLAGS -fPIC)
+
+SET_TARGET_PROPERTIES(${TARGET_ACE_DAO_RW_LIB} PROPERTIES
+ COMPILE_FLAGS "-include ${CMAKE_BINARY_DIR}/modules/ace/database_checksum_ace.h")
+
+target_link_libraries(${TARGET_ACE_DAO_RW_LIB}
+ ${TARGET_DPL_EFL}
+ ${TARGET_DPL_DB_EFL}
+ ${TARGET_ACE_DAO_RO_LIB}
+)
+
+INSTALL(TARGETS ${TARGET_ACE_DAO_RO_LIB}
+ DESTINATION lib
+ PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
+ GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
+)
+
+INSTALL(TARGETS ${TARGET_ACE_DAO_RW_LIB}
+ DESTINATION lib
+ PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
+ GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
+)
+
+INSTALL(FILES
+ ${PROJECT_SOURCE_DIR}/modules/ace/include/dpl/ace-dao-ro/PromptModel.h
+ ${PROJECT_SOURCE_DIR}/modules/ace/include/dpl/ace-dao-ro/PreferenceTypes.h
+ ${PROJECT_SOURCE_DIR}/modules/ace/include/dpl/ace-dao-ro/BaseAttribute.h
+ ${PROJECT_SOURCE_DIR}/modules/ace/include/dpl/ace-dao-ro/BasePermission.h
+ ${PROJECT_SOURCE_DIR}/modules/ace/include/dpl/ace-dao-ro/VerdictTypes.h
+ ${PROJECT_SOURCE_DIR}/modules/ace/include/dpl/ace-dao-ro/TimedVerdict.h
+ ${PROJECT_SOURCE_DIR}/modules/ace/include/dpl/ace-dao-ro/IRequest.h
+ ${PROJECT_SOURCE_DIR}/modules/ace/include/dpl/ace-dao-ro/ValidityTypes.h
+ ${PROJECT_SOURCE_DIR}/modules/ace/include/dpl/ace-dao-ro/AceDAOReadOnly.h
+ ${PROJECT_SOURCE_DIR}/modules/ace/include/dpl/ace-dao-ro/AceDatabase.h
+ ${PROJECT_SOURCE_DIR}/modules/ace/include/dpl/ace-dao-ro/wrt_db_types.h
+ ${PROJECT_SOURCE_DIR}/modules/ace/include/dpl/ace-dao-ro/common_dao_types.h
+ ${PROJECT_SOURCE_DIR}/modules/ace/include/dpl/ace-dao-ro/AceDAOConversions.h
+ DESTINATION include/dpl-efl/dpl/ace-dao-ro
+)
+
+INSTALL(FILES
+ ${PROJECT_SOURCE_DIR}/modules/ace/include/dpl/ace-dao-rw/AceDAO.h
+ DESTINATION include/dpl-efl/dpl/ace-dao-rw
+)
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/* @file PromptModel.cpp
+ * @author Justyna Mejzner (j.kwiatkowsk@samsung.com)
+ * @author Jaroslaw Osmanski (j.osmanski@samsung.com)
+ * @version 1.0
+ *
+ */
+
+#include <dpl/ace-dao-ro/PromptModel.h>
+
+#include <algorithm>
+#include <dpl/log/log.h>
+#include <dpl/assert.h>
+
+namespace {
+
+const char INFO[] = "Widget requires access to:";
+const char DENY[] = "Deny";
+const char ALLOW[] = "Permit";
+
+const char BLANKET_CHECKBOX_LABEL[] = "Keep setting as permanent";
+const char SESSION_CHECKBOX_LABEL[] = "Remember for one run";
+
+Prompt::ButtonLabels aceQuestionLabel = {DENY, ALLOW};
+
+static Prompt::PromptLabels* getModel(
+ Prompt::PromptModel::PromptType promptType,
+ const std::string& resourceId)
+{
+ std::string strLabel;
+ strLabel = INFO;
+ strLabel += "<br>";
+ strLabel += resourceId;
+
+ return new Prompt::PromptLabels(promptType, aceQuestionLabel, strLabel);
+}
+
+Prompt::Validity fromPromptTypeToValidity(int aPromptType, bool checkClicked)
+{
+ using namespace Prompt;
+ PromptModel::PromptType promptTypeEnum =
+ static_cast<PromptModel::PromptType>(aPromptType);
+ switch (promptTypeEnum) {
+ case PromptModel::PROMPT_ONESHOT:
+ return Validity::ONCE;
+ case PromptModel::PROMPT_SESSION:
+ if (checkClicked)
+ {
+ return Validity::SESSION;
+ }
+ else
+ {
+ return Validity::ONCE;
+ }
+ case PromptModel::PROMPT_BLANKET:
+ if (checkClicked)
+ {
+ return Validity::ALWAYS;
+ }
+ else
+ {
+ return Validity::ONCE;
+ }
+ default:
+ Assert(0);
+ return Validity::ONCE;
+ }
+}
+} // namespace anonymous
+
+namespace Prompt {
+
+
+PromptLabels::PromptLabels(int promptType,
+ const Prompt::ButtonLabels& questionLabel,
+ const std::string& mainLabel) :
+ m_promptType(promptType),
+ m_buttonLabels(questionLabel),
+ m_mainLabel(mainLabel)
+{
+
+}
+
+int PromptLabels::getPromptType() const
+{
+ return m_promptType;
+}
+const ButtonLabels& PromptLabels::getButtonLabels() const
+{
+ return m_buttonLabels;
+}
+const std::string& PromptLabels::getMainLabel() const
+{
+ return m_mainLabel;
+}
+
+DPL::OptionalString PromptLabels::getCheckLabel() const
+{
+ if (PromptModel::PROMPT_BLANKET == m_promptType)
+ {
+ return DPL::OptionalString(
+ DPL::FromUTF8String(BLANKET_CHECKBOX_LABEL));
+ }
+ else if (PromptModel::PROMPT_SESSION == m_promptType)
+ {
+ return DPL::OptionalString(
+ DPL::FromUTF8String(SESSION_CHECKBOX_LABEL));
+ }
+
+ return DPL::OptionalString::Null;
+}
+
+bool PromptLabels::isAllowed(const size_t buttonClicked) const
+{
+ Assert(buttonClicked < aceQuestionLabel.size() &&
+ "Button Clicked number is not in range of questionLabel");
+
+ return aceQuestionLabel[buttonClicked] == ALLOW;
+}
+
+PromptAnswer::PromptAnswer(bool isAccessAllowed, Validity validity) :
+ m_isAccessAllowed(isAccessAllowed),
+ m_validity(validity)
+{
+
+}
+
+PromptAnswer::PromptAnswer(
+ int aPromptType, unsigned int buttonAns, bool checkAns)
+{
+ Assert(buttonAns < aceQuestionLabel.size() &&
+ "Button Clicked number is not in range of questionLabel");
+
+ m_isAccessAllowed = aceQuestionLabel[buttonAns] == ALLOW;
+ m_validity = fromPromptTypeToValidity(aPromptType, checkAns);
+}
+
+bool PromptAnswer::isAccessAllowed() const
+{
+ return m_isAccessAllowed;
+}
+
+Validity PromptAnswer::getValidity() const
+{
+ return m_validity;
+}
+
+PromptLabels* PromptModel::getOneShotModel(const std::string& resourceId)
+{
+ return getModel(PROMPT_ONESHOT, resourceId);
+}
+
+PromptLabels* PromptModel::getSessionModel(const std::string& resourceId)
+{
+ return getModel(PROMPT_SESSION, resourceId);
+}
+
+PromptLabels* PromptModel::getBlanketModel(const std::string& resourceId)
+{
+ return getModel(PROMPT_BLANKET, resourceId);
+}
+
+
+} // Prompt
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <dpl/wrt-dao-ro/common_dao_types.h>
+
+#include <dpl/log/log.h>
+
+namespace WrtDB {
+namespace Powder {
+
+Description::LevelEntry::LevelEntry(LevelEnum level) :
+ level(level)
+{
+}
+
+bool Description::LevelEntry::isContextValid(LevelEnum level,
+ const DPL::OptionalString& aContext) const
+{
+ if (!aContext) {
+ return level < level;
+ } else {
+ Context::const_iterator iter = context.find(*aContext);
+ if (iter != context.end()) {
+ return level < level;
+ } else {
+ return true;
+ }
+ }
+}
+
+bool Description::CategoryEntry::isCategoryValid(LevelEntry& aReason,
+ LevelEnum aLevel,
+ const DPL::OptionalString& aContext) const
+{
+ for (LevelsContainer::const_iterator iter = levels.begin();
+ iter != levels.end(); ++iter) {
+ if (!iter->isContextValid(aLevel, aContext)) {
+ aReason = *iter;
+ return false;
+ }
+ }
+ return true;
+}
+}
+
+namespace ChildProtection
+{
+
+PowderRules::CategoryRule::CategoryRule(const DPL::String& aCategory,
+ Powder::Description::LevelEnum aLevel,
+ const DPL::OptionalString& aContext) :
+ category(aCategory),
+ level(aLevel),
+ context(aContext)
+{
+}
+
+PowderRules::PowderResult::PowderResult(InvalidReason aReason,
+ const Powder::Description::LevelEntry& anInvalidDescription,
+ const CategoryRule& anInvalidRule) :
+ invalidDescription(anInvalidDescription),
+ invalidRule(anInvalidRule),
+ reason(aReason)
+{
+}
+
+//! Function checks if rule is fulfilled by description
+//! \param[in] rule checked rule
+//! \param[in] description
+//! \retval true rule is valid
+//! \retval false rule is invalid
+PowderRules::ResultPair PowderRules::isRuleValidForDescription(
+ const CategoryRule& aRule,
+ const Powder::Description& aDescription) const
+{
+ Powder::Description::CategoryEntries::const_iterator
+ iter = aDescription.categories.find(aRule.category);
+ if (iter != aDescription.categories.end()) {
+ Powder::Description::LevelEntry invalidDescription;
+ if (!iter->second.isCategoryValid(invalidDescription, aRule.level,
+ aRule.context)) {
+ LogWarning("Widget forbidden for children detected");
+ return std::make_pair(false,
+ PowderResult(PowderResult::InvalidRule,
+ invalidDescription,
+ aRule));
+ } else {
+ return std::make_pair(true, PowderResult());
+ }
+ } else {
+ return std::make_pair(true, PowderResult());
+ }
+}
+
+//! Function checks if age limit is fulfilled by description
+//! \param[in] description
+//! \retval true age is valid
+//! \retval false age is invalid
+PowderRules::ResultPair PowderRules::isAgeValidForDescription(
+ const Powder::Description& aDescription) const
+{
+ if (!ageLimit) {
+ return std::make_pair(true, PowderResult());
+ } else {
+ if (!!aDescription.ageRating) {
+ if (*aDescription.ageRating <= *ageLimit) {
+ return std::make_pair(true, PowderResult());
+ } else {
+ return std::make_pair(false,
+ PowderResult(PowderResult::InvalidAge));
+ }
+ } else {
+ if (!isAgeRatingRequired) {
+ return std::make_pair(true, PowderResult());
+ } else {
+ return std::make_pair(
+ false,
+ PowderResult(PowderResult::AgeRatingNotSet));
+ }
+ }
+ }
+}
+
+//! Function check if Widget description is valid for ChildProtection
+//! configuration
+//! \param description widget description
+//! \retval true widget is valid
+//! \retval false widget is invalid
+PowderRules::ResultPair PowderRules::isDescriptionValid(
+ const Powder::Description& aDescription) const
+{
+ ResultPair powderResult;
+ for (RulesContainer::const_iterator iter = rules.begin();
+ iter != rules.end(); ++iter) {
+ powderResult = isRuleValidForDescription(*iter, aDescription);
+ if (!powderResult.first) {
+ return powderResult;
+ }
+ }
+ return isAgeValidForDescription(aDescription);
+}
+
+}
+} // namespace WrtDB
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <fnmatch.h>
+#include <pcrecpp.h>
+#include <sstream>
+#include <dpl/foreach.h>
+#include <dpl/log/log.h>
+#include <dpl/ace/Attribute.h>
+#include <dpl/ace/Serializer.h>
+
+const bool Attribute::alpha[256] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0
+};
+const bool Attribute::digit[256] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0
+};
+
+const bool Attribute::mark[256] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0
+};
+
+bool Attribute::searchAndCut(const char *str)
+{
+ //TODO
+ size_t pos = m_name.rfind(str);
+ if (pos == std::string::npos) {
+ return false;
+ }
+ if ((strlen(str) + pos) == m_name.size()) {
+ m_name.erase(pos, std::string::npos);
+ return true;
+ }
+ return false;
+}
+
+Attribute::Attribute(const std::string *name,
+ const Match matchFunc,
+ const Type type_) :
+ matchFunction(matchFunc)
+{
+ m_name = *name;
+ m_typeId = type_;
+ m_undetermindState = false;
+ if (matchFunction != Match::Equal
+ && matchFunction != Match::Glob
+ && matchFunction != Match::Regexp)
+ {
+ //LogDebug("MID: " << matchFunction);
+ Assert(0 && "Match function problem");
+ }
+
+ if (searchAndCut(".scheme")) {
+ modifierFunction = Modifier::Scheme;
+ } else if (searchAndCut(".authority")) {
+ modifierFunction = Modifier::Authority;
+ } else if (searchAndCut(".scheme-authority")) {
+ modifierFunction = Modifier::SchemeAuthority;
+ } else if (searchAndCut(".host")) {
+ modifierFunction = Modifier::Host;
+ } else if (searchAndCut(".path")) {
+ modifierFunction = Modifier::Path;
+ } else {
+ modifierFunction = Modifier::Non;
+ }
+}
+
+static Attribute::MatchResult equal_comparator(const std::string *first,
+ const std::string *second)
+{
+ if((*first) == (*second)) {
+ return Attribute::MatchResult::MRTrue;
+ }
+ return Attribute::MatchResult::MRFalse;
+}
+
+static Attribute::MatchResult glob_comparator(const std::string *first,
+ const std::string *second)
+{
+ // order is important
+ if (!fnmatch(first->c_str(), second->c_str(), 0)) {
+ return Attribute::MatchResult::MRTrue;
+ }
+ return Attribute::MatchResult::MRFalse;
+}
+
+static Attribute::MatchResult regexp_comparator(const std::string *first,
+ const std::string *second)
+{
+ // order is important
+ pcrecpp::RE re(first->c_str());
+ if (re.FullMatch(second->c_str())) {
+ return Attribute::MatchResult::MRTrue;
+ }
+ return Attribute::MatchResult::MRFalse;
+}
+
+Attribute::MatchResult Attribute::lists_comparator(
+ const std::list<std::string> *first,
+ const std::list<std::string> *second,
+ Attribute::MatchResult (*comparator)(const std::string *,
+ const std::string *)) const
+{
+ //NOTE: BONDI defines all availabe matching function as: if some string from first input bag
+ //matches some input string from second input bag, so it's required to find only one matching string
+ MatchResult result = MatchResult::MRFalse;
+
+ for (std::list<std::string>::const_iterator second_iter = second->begin();
+ (second_iter != second->end()) && (result != MatchResult::MRTrue);
+ ++second_iter)
+ {
+ std::string *modified_value = applyModifierFunction(&(*second_iter));
+ //Value was not an URI, it will be removed from the string bag (ignored)
+ if (modified_value == NULL) {
+ continue;
+ }
+
+ for (std::list<std::string>::const_iterator first_iter = first->begin();
+ first_iter != first->end();
+ ++first_iter) {
+ //Compare attributes
+ if ((*comparator)(&(*first_iter), modified_value) == MatchResult::MRTrue) {
+ result = MatchResult::MRTrue;
+ break; //Only one match is enough
+ }
+ }
+ if (modified_value) {
+ delete modified_value;
+ modified_value = NULL;
+ }
+ }
+
+ if (result == MatchResult::MRTrue) {
+ LogDebug("Returning TRUE");
+ } else if (result == MatchResult::MRFalse) {
+ LogDebug("Returning FALSE");
+ } else if (result == MatchResult::MRUndetermined) {
+ LogDebug("Returning UNDETERMINED");
+ }
+ return result;
+}
+
+std::string * Attribute::applyModifierFunction(const std::string * val) const
+{
+ std::string * result = NULL;
+ switch (modifierFunction) {
+ case Modifier::Scheme:
+ result = uriScheme(val);
+ break;
+ case Modifier::Authority:
+ result = uriAuthority(val);
+ break;
+ case Modifier::SchemeAuthority:
+ result = uriSchemeAuthority(val);
+ break;
+ case Modifier::Host:
+ result = uriHost(val);
+ break;
+ case Modifier::Path:
+ result = uriPath(val);
+ break;
+ default:
+ result = new std::string(*val);
+ }
+
+ return result;
+}
+
+/**
+ * this - attribute obtained from xmlPolicy tree
+ * attribute - attribute obtained from PIP
+ */
+Attribute::MatchResult Attribute::matchAttributes(
+ const BaseAttribute *attribute) const
+{
+ std::string tempNam = *(attribute->getName());
+ std::string tempVal;
+ std::string myVal;
+
+ if (!(attribute->getValue()->empty())) {
+ tempVal = attribute->getValue()->front();
+ }
+
+ if (!(this->value.empty())) {
+ myVal = this->value.front();
+ }
+
+ LogDebug("Comparing attribute: " << this->m_name << "(" <<
+ myVal << ") with: " << tempNam <<
+ "(" << tempVal << ")");
+
+ Assert(
+ (this->m_name == *(attribute->getName())) &&
+ "Two completely different attributes are being compared!");
+ Assert(
+ (this->m_typeId == attribute->getType()) &&
+ "Two completely different attributes are being compared!");
+
+ if (attribute->isUndetermind()) {
+ LogDebug("Attribute match undetermined");
+ return MatchResult::MRUndetermined;
+ }
+
+ //Regardles the algorithm used, if we have empty
+ //bag the result is always false
+ if (this->isValueEmpty() || attribute->isValueEmpty()) {
+ if (this->isValueEmpty()) {
+ LogDebug("empty bag in condition comparing");
+ }
+ if (attribute->isValueEmpty()) {
+ LogDebug("empty bag in attribute comparing");
+ }
+ return MatchResult::MRFalse;
+ }
+
+ if (this->matchFunction == Match::Equal) {
+ return lists_comparator(&(this->value),
+ attribute->getValue(),
+ equal_comparator);
+ } else if (this->matchFunction == Match::Glob) {
+ return lists_comparator(&(this->value),
+ attribute->getValue(),
+ glob_comparator);
+ } else if (this->matchFunction == Match::Regexp) {
+ return lists_comparator(&(this->value),
+ attribute->getValue(),
+ regexp_comparator);
+ } //[CR] Change to Assert
+ Assert(false && " ** Critical :: no match function selected!");
+ return MatchResult::MRFalse; // to remove compilator warning
+}
+
+void Attribute::addValue(const std::string *val)
+{
+ this->getValue()->push_back(*val);
+}
+
+std::ostream & operator<<(std::ostream & out,
+ const Attribute & attr)
+{
+ out << "attr: m_name: " << *(attr.getName())
+ << " type: " << Attribute::typeToString(attr.getType())
+ << " value: ";
+ if (attr.m_undetermindState) {
+ out << "Undetermined";
+ } else if (attr.getValue()->empty()) {
+ out << "Empty string bag";
+ } else {
+ FOREACH (it, *attr.getValue()) {
+ out << *it;
+ }
+ }
+ return out;
+}
+
+bool
+Attribute::parse(const std::string *input,
+ std::string *val) const
+{
+ static const char *pattern =
+ "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?";
+ pcrecpp::RE re(pattern);
+ re.FullMatch(input->c_str(), &val[0], &val[1],
+ &val[2], &val[3], &val[4],
+ &val[5], &val[6], &val[7], &val[8]);
+
+#ifdef ALL_LOGS
+ for (int i = 0; i < 9; i++) {
+ LogDebug("val " << i << " :" << val[i]);
+ }
+#endif
+
+ if (find_error(val)) {
+ LogDebug("Input is not an URI " << *input);
+ for (int i = 0; i < 9; ++i) {
+ val[i].clear();
+ }
+ return false;
+ }
+
+ return true;
+}
+
+Attribute::Attribute(std::istream& is)
+{
+ Serializer* serializer = Serializer::getInstance();
+
+ m_name = serializer->deserializeString(is);
+ m_typeId = serializer->deserializeType(is);
+
+ setValue(serializer->deserializeListStrings(is));
+
+ matchFunction = serializer->deserializeMatch(is);
+ modifierFunction = serializer->deserializeModifier(is);
+}
+
+Attribute::~Attribute()
+{
+}
+
+bool Attribute::serialize(std::ostream& os) const
+{
+ Serializer* serializer = Serializer::getInstance();
+
+ serializer->serializeString(os, m_name);
+ serializer->serializeType(os, m_typeId);
+ serializer->serializeListStrings(os, value);
+
+ serializer->serializeMatch(os, matchFunction);
+ serializer->serializeModifier(os, modifierFunction);
+ return 0;
+}
+
+std::string * Attribute::uriScheme(const std::string *input) const
+{
+ std::string part[9];
+ if (!parse(input, part)) {
+ return NULL;
+ }
+ return new string(part[1]);
+}
+
+std::string *
+Attribute::uriAuthority(const std::string *input) const
+{
+ std::string part[9];
+ if (!parse(input, part)) {
+ return NULL;
+ }
+ return new string(part[3]);
+}
+
+std::string *
+Attribute::uriSchemeAuthority(const std::string *input) const
+{
+ std::string part[9];
+ if (!parse(input, part)) {
+ return NULL;
+ }
+
+ if (part[0].size() == 0 || part[2].size() == 0) {
+ return new std::string();
+ }
+ return new string(part[0] + part[2]);
+}
+
+std::string *
+Attribute::uriHost(const std::string *input) const
+{
+ std::string part[9];
+ if (!parse(input, part)) {
+ return NULL;
+ }
+ return getHost(&(part[3]));
+}
+
+std::string *
+Attribute::uriPath(const std::string *input) const
+{
+ //TODO right now uriPath leaves leading '/' in uri, this slash is removed from the string
+ //it's not clear if leading '/' is a part of path component or only the separator
+ std::string part[9];
+ if (!parse(input, part)) {
+ return NULL;
+ }
+
+ std::string * temp = NULL;
+
+ if (part[4].at(0) == '/') {
+ temp = new string(part[4].substr(1, part[4].length() - 1));
+ } else {
+ temp = new string(part[4]);
+ }
+
+ return temp;
+}
+
+bool Attribute::find_error(const std::string *tab) const
+{
+ //We are checking tab[1] which contains scheme without ':' at the end
+ if (!checkScheme(&(tab[1]))) {
+ LogDebug("Check scheme failed, URI is invalid");
+ return true; //error found
+ }
+ if (!checkAuthority(&(tab[3]))) {
+ LogDebug("Check authority failed, URI is invalid");
+ return true; //error found
+ }
+
+ if (!checkPath(&(tab[4]))) {
+ LogDebug("Check path failed, URI is invalid");
+ return true; //error found
+ }
+
+ return false;
+}
+
+bool Attribute::checkScheme(const std::string *part) const
+{
+ Assert(part != NULL && "Checking NULLable string. This should never happen");
+
+ bool result = true;
+
+ //TODO change part->at to data=part->c_str()
+ //TODO can scheme be empty? In absolute URI no, in relative URI yes
+ if (part->empty()) {
+ //Empty string is a correct schema
+ result = true;
+ } else if (alpha[(int) (part->at(0))] == 0) {
+ result = false; // First scheme character must be alpha
+ } else {
+ // rest must be alpha or digit or '+' or '-' or '.'
+ for (unsigned int i = 1; i < part->size(); ++i) {
+ int c = static_cast<int>(part->at(i));
+ if (!isSchemeAllowedCharacter(c)) {
+ result = false;
+ break;
+ }
+ }
+ }
+ return result;
+}
+
+bool Attribute::checkAuthority(const std::string *part) const
+{
+ Assert(part != NULL && "Checking NULLable string. This should never happen");
+
+ //Server is a subset of reg_m_names so here we only check if authority matches reg_m_name
+ //Additional check if authority is a valid 'server' component is done in getHost
+ if (part->empty()) {
+ return true; //empty authority is valid uri
+ }
+ bool result = true;
+
+ const char * data = part->c_str();
+ for (size_t i = 0; i < part->length(); ++i) {
+ int c = (int) data[i];
+ if (isUnreserved(c)) {
+ continue;
+ }
+ if (c == '$') {
+ continue;
+ }
+ if (c == ',') {
+ continue;
+ }
+ if (c == ';') {
+ continue;
+ }
+ if (c == ':') {
+ continue;
+ }
+ if (c == '@') {
+ continue;
+ }
+ if (c == '&') {
+ continue;
+ }
+ if (c == '=') {
+ continue;
+ }
+ if (c == '+') {
+ continue;
+ }
+ if (c == '%') {
+ if (isEscaped(data + i)) {
+ i += 2; //rewind the two escaped characters
+ continue;
+ }
+ }
+ result = false;
+ break;
+ }
+
+ return result;
+}
+
+std::string * Attribute::getHost(const std::string *part) const
+{
+ if (part->empty()) {
+ return new std::string("");
+ }
+
+ //Check userinfo
+ size_t userInfoPos = part->find("@");
+ if (userInfoPos != std::string::npos) {
+ std::string data = part->substr(0, userInfoPos);
+ if (!isUserInfoAllowedString(&data)) {
+ return new string(""); //the authority is not composed of 'server' part
+ }
+ }
+
+ std::string host;
+ //If we use host modifier then authority is composed of 'server' part so
+ //the port must contain only digits
+ size_t portPos = part->find(":");
+ if (portPos != std::string::npos) {
+ for (unsigned int i = portPos + 1; i < part->size(); ++i) {
+ if (!digit[(int) part->at(i)]) {
+ return new string(""); //the authority is not composed of 'server' part
+ }
+ }
+ host = part->substr(userInfoPos + 1, portPos - (userInfoPos + 1));
+ } else {
+ host = part->substr(userInfoPos + 1, part->length() - (userInfoPos + 1));
+ }
+
+ if (!isHostAllowedString(&host)) {
+ //Even if the string is not allowed for host this can still be a valid uri
+ return new string("");
+ }
+
+ return new std::string(host);
+}
+
+bool Attribute::checkPath(const std::string *part) const
+{
+ bool result = true;
+
+ const char * data = part->c_str();
+
+ for (unsigned int i = 0; i < part->size(); ++i) {
+ int c = data[i];
+ if (c == '/') {
+ //If we found slash then the next character must be a part of segment
+ //It cannot be '/' so we have to check it immediately
+ i++;
+ c = data[i];
+ if (!isSegmentAllowedCharacter(c)) {
+ result = false;
+ break;
+ }
+ } else if (c == ';') {
+ //Start param part of segment
+ i++; //Param can be empty so we don't have to check what's right after semicolon
+ continue;
+ } else if (c == '%') {
+ //We have to handle escaped characters differently than other segment allowed characters
+ //because we need an array
+ if (isEscaped(data + i)) {
+ i += 2;
+ } else {
+ result = false;
+ break;
+ }
+ } else {
+ if (!isSegmentAllowedCharacter(c)) {
+ result = false;
+ break;
+ }
+ }
+ }
+
+ return result;
+}
+
+bool Attribute::isSchemeAllowedCharacter(int c) const
+{
+ bool result = false;
+ if (isAlphanum(c)) {
+ result = true;
+ } else if (c == '+') {
+ result = true;
+ } else if (c == '-') {
+ result = true;
+ } else if (c == '.') {
+ result = true;
+ }
+
+ return result;
+}
+
+bool Attribute::isSegmentAllowedCharacter(int c) const
+{
+ bool result = true;
+
+ // LogDebug("Checking is segment allowed for char "<<(char)c);
+
+ if (isUnreserved(c)) { //do nothing, result = true
+ } else if (c == ':') { //do nothing, result = true
+ } else if (c == '@') { //do nothing, result = true
+ } else if (c == '&') { //do nothing, result = true
+ } else if (c == '=') { //do nothing, result = true
+ } else if (c == '+') { //do nothing, result = true
+ } else if (c == '$') { //do nothing, result = true
+ } else if (c == ',') { //do nothing, result = true
+ } else {
+ result = false;
+ }
+
+ return result;
+}
+
+bool Attribute::isUserInfoAllowedString(const std::string * str) const
+{
+ bool result = false;
+
+ const char * data = str->c_str();
+
+ for (unsigned int i = 0; i < str->length(); ++i) {
+ int c = data[i];
+ if (isUnreserved(c)) {
+ result = true;
+ } else if (c == '%') {
+ //isEsacped method checks if we don't cross array bounds, so we can
+ //safely give data[i] here
+ result = isEscaped((data + i));
+ if (result == false) {
+ break;
+ }
+ i += 2; //rewind the next two characters sEsacped method checks if we don't cross array bounds, so we can safely rewind
+ } else if (c == ',') {
+ result = true;
+ } else if (c == '$') {
+ result = true;
+ } else if (c == '+') {
+ result = true;
+ } else if (c == '=') {
+ result = true;
+ } else if (c == '&') {
+ result = true;
+ } else if (c == '@') {
+ result = true;
+ } else if (c == ':') {
+ result = true;
+ }
+ }
+ return result;
+}
+
+bool Attribute::isUnreserved(int c) const
+{
+ return isAlphanum(c) || mark[c];
+}
+
+bool Attribute::isAlphanum(int c) const
+{
+ return alpha[c] || digit[c];
+}
+
+bool Attribute::isHex(int c) const
+{
+ bool result = false;
+
+ if (digit[c]) {
+ result = true;
+ } else if (c == 'A') {
+ result = true;
+ } else if (c == 'B') {
+ result = true;
+ } else if (c == 'C') {
+ result = true;
+ } else if (c == 'D') {
+ result = true;
+ } else if (c == 'E') {
+ result = true;
+ } else if (c == 'F') {
+ result = true;
+ } else if (c == 'a') {
+ result = true;
+ } else if (c == 'b') {
+ result = true;
+ } else if (c == 'c') {
+ result = true;
+ } else if (c == 'd') {
+ result = true;
+ } else if (c == 'e') {
+ result = true;
+ } else if (c == 'f') {
+ result = true;
+ }
+
+ return result;
+}
+
+bool Attribute::isEscaped(const char esc[3]) const
+{
+ if (esc == NULL) {
+ return false;
+ }
+
+ if ((esc[0] == 0) || (esc[1] == 0) || (esc[2] == 0)) {
+ //We get an array that seems to be out of bounds.
+ //To be on the safe side return here
+ LogDebug("HEX NULLS");
+ return false;
+ }
+
+ if (esc[0] != '%') {
+ LogDebug(
+ "Error: first character of escaped value must be a precent but is "
+ <<
+ esc[0]);
+ return false;
+ }
+
+#ifdef ALL_LOGS
+ for (int i = 0; i < 3; i++) {
+ LogDebug("HEX " << esc[i]);
+ }
+#endif
+ return isHex((int) esc[1]) && isHex((int) esc[2]);
+}
+
+bool Attribute::isHostAllowedString(const std::string * str) const
+{
+ bool result = true;
+
+ if (digit[(int) str->at(0)]) {
+ //IPv4 address
+ result = isIPv4AllowedString(str);
+ } else {
+ //Hostname
+ result = isHostNameAllowedString(str);
+ }
+
+ return result;
+}
+
+bool Attribute::isIPv4AllowedString(const std::string * str) const
+{
+ LogDebug("Is hostIPv4 allowed String for " << *str);
+
+ const char * data = str->c_str();
+ bool result = true;
+ int digitCounter = 0;
+ int dotCounter = 0;
+
+ for (unsigned int i = 0; i < str->length(); ++i) {
+ if (data[i] == '.') {
+ dotCounter++;
+ digitCounter = 0;
+ } else if (digit[(int) data[i]]) {
+ digitCounter++;
+ if ((digitCounter > 3) || !digitCounter) {
+ result = false;
+ break;
+ }
+ } else {
+ result = false;
+ break;
+ }
+ }
+ if (dotCounter != 3) {
+ result = false;
+ }
+ return result;
+}
+
+bool Attribute::isHostNameAllowedString(const std::string * str) const
+{
+ LogDebug("Is hostname allowed String for " << *str);
+
+ int lastPosition = 0; //the position of last dot + 1
+ const char * data = str->c_str();
+ bool finalDot = false;
+ size_t end = str->length();
+ bool result = false;
+
+ for (size_t i = 0; i < end; ++i) {
+ if (data[i] == '.') {
+ if (i == str->length() - 1) { //ending dot
+ //There can be a leading '.' int the hostm_name
+ finalDot = true;
+ break;
+ } else {
+ //we found domain label
+ if (!isDomainLabelAllowedString(data + lastPosition, i -
+ lastPosition)) {
+ result = false;
+ goto end;
+ }
+ lastPosition = i + 1; //Set position to position of last dot + 1
+ }
+ }
+ }
+
+ if (finalDot) {
+ //we have to rewind one position to check the rightmost string
+ //but only in case we find final dot
+ end--;
+ }
+ //Compare only the rightmost string aaa.bbbb.rightmostString.
+ result = isTopLabelAllowedString(data + lastPosition, end - lastPosition);
+
+end:
+
+ if (result) {
+ LogInfo("Hostname is allowed");
+ } else {
+ LogInfo("Hostname is NOT allowed");
+ }
+
+ return result;
+}
+
+bool Attribute::isDomainLabelAllowedString(const char * data,
+ int length) const
+{
+ LogDebug(
+ "Is domain allowed String for " << data << " taking first " <<
+ length <<
+ " chars");
+
+ if (!isAlphanum((int) data[0]) || !isAlphanum((int) data[length - 1])) {
+ return false;
+ }
+
+ for (int i = 0; i < length; i++) {
+ if ((!isAlphanum(data[i])) && !(data[i] == '-')) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool Attribute::isTopLabelAllowedString(const char * data,
+ int length) const
+{
+ if ((!alpha[(int) data[0]]) || (!isAlphanum((int) data[length - 1]))) {
+ return false;
+ }
+
+ for (int i = 1; i < length - 1; i++) {
+ if ((!isAlphanum(data[i])) && !(data[i] == '-')) {
+ return false;
+ }
+ }
+ return true;
+}
+
+void printAttributes(const AttributeSet& attrs)
+{
+ if (attrs.empty()) {
+ LogWarning("Empty attribute set");
+ } else {
+ LogDebug("PRINT ATTRIBUTES:");
+ for (AttributeSet::const_iterator it = attrs.begin();
+ it != attrs.end();
+ ++it)
+ {
+ LogDebug("name: " << *(*it)->getName());
+ }
+ }
+}
+
+void printAttributes(const std::list<Attribute> & attrs)
+{
+ if (attrs.empty()) {
+ LogWarning("Empty attribute set");
+ } else {
+ LogDebug("PRINT ATTRIBUTES:");
+ for (std::list<Attribute>::const_iterator it = attrs.begin();
+ it != attrs.end();
+ ++it
+ ) {
+ LogDebug(*it);
+ }
+ }
+}
+
+//KW const char * matchResultToString(Attribute::MatchResult result){
+//KW
+//KW const char * ret = NULL;
+//KW
+//KW switch(result){
+//KW
+//KW case Attribute::MRTrue:
+//KW ret = "true";
+//KW break;
+//KW case Attribute::MRFalse:
+//KW ret = "false";
+//KW break;
+//KW case Attribute::MRUndetermined:
+//KW ret = "undetermined";
+//KW break;
+//KW default:
+//KW ret = "Wrong match result";
+//KW }
+//KW
+//KW return ret;
+//KW
+//KW }
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//
+//
+//
+// @ Project : Access Control Engine
+// @ File Name : CombinerImpl.cpp
+// @ Date : 2009-05-06
+// @ Author : Samsung
+//
+//
+
+#include <dpl/log/log.h>
+#include <dpl/assert.h>
+
+#include <dpl/ace/CombinerImpl.h>
+#include <dpl/ace/Rule.h>
+#include <dpl/ace/Policy.h>
+
+const int CombinerImpl::DenyInt = 0, //mb jk changed the numbers !!!!!!!!!!!!!!!!!
+CombinerImpl::UndeterminedInt = 1, //this one is added
+CombinerImpl::PromptOneShotInt = 2,
+CombinerImpl::PromptSessionInt = 3,
+CombinerImpl::PromptBlanketInt = 4,
+CombinerImpl::PermitInt = 5,
+CombinerImpl::InapplicableInt = 6,
+CombinerImpl::NotMatchingTargetInt = 7,
+CombinerImpl::ErrorInt = 8;
+
+std::list<int> * CombinerImpl::convertEffectsToInts(
+ const std::list<Effect> * effects)
+{
+ std::list<int> * intList = new std::list<int>();
+ for (
+ std::list<Effect>::const_iterator it = effects->begin();
+ it != effects->end();
+ ++it
+ ) {
+ switch (*it) {
+ case Deny:
+ intList->push_back(CombinerImpl::DenyInt);
+ break;
+ case Undetermined: //jk mb added
+ intList->push_back(CombinerImpl::UndeterminedInt);
+ break;
+ case Permit:
+ intList->push_back(CombinerImpl::PermitInt);
+ break;
+ case PromptBlanket:
+ intList->push_back(CombinerImpl::PromptBlanketInt);
+ break;
+ case PromptOneShot:
+ intList->push_back(CombinerImpl::PromptOneShotInt);
+ break;
+ case PromptSession:
+ intList->push_back(CombinerImpl::PromptSessionInt);
+ break;
+ case Inapplicable:
+ intList->push_back(CombinerImpl::InapplicableInt);
+ break;
+ case NotMatchingTarget:
+ intList->push_back(CombinerImpl::NotMatchingTargetInt);
+ break;
+ case Error:
+ intList->push_back(CombinerImpl::ErrorInt);
+ break;
+ default:
+ Assert(false && "Wrong effect");
+ }
+ }
+ return intList;
+}
+
+Effect CombinerImpl::convertIntToEffect(int intEffect)
+{
+ switch (intEffect) {
+ case DenyInt:
+ return Deny;
+
+ case UndeterminedInt: //jk mb added
+ return Undetermined;
+
+ case PermitInt:
+ return Permit;
+
+ case PromptBlanketInt:
+ return PromptBlanket;
+
+ case PromptOneShotInt:
+ return PromptOneShot;
+
+ case PromptSessionInt:
+ return PromptSession;
+
+ case InapplicableInt:
+ return Inapplicable;
+
+ case NotMatchingTargetInt:
+ return NotMatchingTarget;
+
+ case ErrorInt:
+ return Error;
+
+ default:
+ Assert(false && "Wrong integer in int to Effect conversion");
+ return Error;
+ }
+}
+
+Effect CombinerImpl::denyOverrides(const std::list<Effect> & effects)
+{
+ if (isError(effects)) {
+ return Error;
+ }
+
+ std::list<int> * intList = convertEffectsToInts(&effects);
+
+ int result = InapplicableInt; //Deny has value 0, Undetermined value 1, Inapplicable value 6
+
+ std::list<int>::const_iterator it = intList->begin();
+
+ while (it != intList->end()) {
+ int effect = *it;
+ //Use most restrictive policy always
+ result = effect < result ? effect : result;
+ ++it;
+ }
+ delete intList;
+ return convertIntToEffect(result);
+}
+
+Effect CombinerImpl::permitOverrides(const std::list<Effect> & effects) //mb jk modified
+{ if (isError(effects)) {
+ return Error;
+ }
+
+ int result = DenyInt; //Deny has value 0, Inapplicable value 5
+ std::list<int> * intList = convertEffectsToInts(&effects);
+ std::list<int>::const_iterator it = intList->begin();
+
+ //Flag used to indicate that any of Deny,prompt-*,permit options appear
+ //Consequently if flag is true then result should be return, otherwise inapplicable should be returned
+ bool flag = false;
+ bool flagUndetermined = false;
+
+ while (it != intList->end()) {
+ int effect = *it;
+
+ if (effect == PermitInt) {
+ result = effect;
+ delete intList;
+ return convertIntToEffect(result);
+ } // no need for further check if "permit" found
+ if (effect == UndeterminedInt) { flagUndetermined = true; } //check for undetermined
+
+ //Set the flag and the result even if effect is equal to result
+ //It is done to mark if any "Deny" effect occured
+ if (effect >= result && effect != InapplicableInt && effect !=
+ UndeterminedInt) { //check for other results
+ result = effect;
+ flag = true;
+ }
+
+ ++it;
+ }
+ delete intList;
+
+ if (flagUndetermined) {
+ return Undetermined;
+ }
+
+ if (!flag) {
+ return Inapplicable;
+ }
+ return convertIntToEffect(result);
+}
+
+Effect CombinerImpl::firstApplicable(const std::list<Effect> & effects) //jk mb modified to comply with BONDI 1.0 ("undetermined" handling)
+{ std::list<Effect>::const_iterator it = effects.begin();
+
+ if (isError(effects)) {
+ return Error;
+ }
+
+ for (; it != effects.end(); ++it) {
+ if (*it != InapplicableInt) {
+ return *it;
+ }
+ }
+ return Inapplicable;
+}
+
+Effect CombinerImpl::firstMatchingTarget(const std::list<Effect> & effects)
+{
+ if (isError(effects)) {
+ return Error;
+ }
+ // effect list constains result of policies which target has been matched.
+ //
+ // If target does not match policy result is NotMatchingTarget
+ // NotMatchingTarget values are not stored on the effects list
+ // (you can check it in combinePolicies function).
+ //
+ // So we are intrested in first value on the list.
+ return effects.empty() ? Inapplicable : effects.front();
+}
+
+bool CombinerImpl::isError(const std::list<Effect> & effects)
+{
+ FOREACH(it, effects)
+ {
+ if (Error == *it) {
+ return true;
+ }
+ }
+ return false;
+}
+
+Effect CombinerImpl::combineRules(const TreeNode * policy)
+{
+ const Policy * policyObj = dynamic_cast<const Policy *>(policy->getElement());
+ if (!policyObj) {
+ LogError("dynamic_cast failed. PolicyObj is null.");
+ return Error;
+ }
+
+ Policy::CombineAlgorithm algorithm = policyObj->getCombineAlgorithm();
+
+ Assert(
+ algorithm != Policy::FirstTargetMatching &&
+ "Policy cannot have algorithm first target matching");
+
+ bool isUndetermined = false;
+
+ if (!checkIfTargetMatches(policyObj->getSubjects(), isUndetermined)) {
+ if (isUndetermined) {
+ //TODO Target is undetermined what should we do now ??
+ //Right now simply return NotMatchingTarget
+ }
+ //Target doesn't match
+ return NotMatchingTarget;
+ }
+ //Get all rules
+ const ChildrenSet & children = policy->getChildrenSet();
+ ChildrenConstIterator it = children.begin();
+ std::list<Effect> effects;
+
+ while (it != children.end()) {
+ const Rule * rule = dynamic_cast<const Rule *>((*it)->getElement());
+
+ if (!rule) {
+ LogError("Error in dynamic_cast. rule is null");
+ return Error;
+ }
+
+ Effect effect = rule->evaluateRule(this->getAttributeSet());
+ effects.push_back(effect);
+ if (algorithm == Policy::FirstApplicable && effect != Inapplicable) {
+ //For first applicable algorithm we may stop after evaluating first policy
+ //which has effect other than inapplicable
+ break;
+ }
+ ++it;
+ } //end policy children iteration
+
+ //Use combining algorithm
+ Effect ef = combine(policyObj->getCombineAlgorithm(), effects);
+ return ef;
+}
+
+//WARNING this method makes an assumption that Policy target is a policy child
+Effect CombinerImpl::combinePolicies(const TreeNode * policy)
+{
+ const Policy * policySet = dynamic_cast<const Policy *>(policy->getElement());
+
+ if (!policySet) {
+ LogError("dynamic_cast failed. Policy set is null.");
+ return Error;
+ }
+
+ bool isUndetermined = false;
+ Policy::CombineAlgorithm algorithm = policySet->getCombineAlgorithm();
+
+ if (!checkIfTargetMatches(policySet->getSubjects(), isUndetermined)) {
+ /* I can't explain this...
+ if (isUndetermined) {
+ if (algorithm == Policy::FirstTargetMatching) {
+ return Undetermined;
+ }
+ }
+ */
+ //Target doesn't match
+ return NotMatchingTarget;
+ }
+
+ const ChildrenSet & children = policy->getChildrenSet();
+
+ ChildrenConstIterator it = children.begin();
+
+ std::list<Effect> effects;
+
+ while (it != children.end()) {
+ Effect effect;
+
+ if ((*it)->getTypeID() == TreeNode::PolicySet) {
+ effect = combinePolicies(*it);
+ if (effect != NotMatchingTarget) {
+ effects.push_back(effect);
+ }
+ } else if ((*it)->getTypeID() == TreeNode::Policy) {
+ effect = combineRules(*it);
+ if (effect != NotMatchingTarget) {
+ effects.push_back(effect);
+ }
+ } else {
+ // [CR] fix it
+ LogError("effect value is not initialized!");
+ return Error;
+ }
+
+ if (algorithm == Policy::FirstTargetMatching && effect !=
+ NotMatchingTarget) {
+ //In First matching target algorithm we may return when first result is found
+ break;
+ }
+ ++it;
+ }
+
+ //Use combining algorithm
+ Effect ef = combine(policySet->getCombineAlgorithm(), effects);
+ return ef;
+}
+
+Effect CombinerImpl::combine(Policy::CombineAlgorithm algorithm,
+ std::list<Effect> & effects)
+{
+ LogDebug("Effects to be combined with algorithm: " << toString(algorithm));
+ showEffectList(effects);
+
+ switch (algorithm) {
+ case Policy::DenyOverride:
+ return denyOverrides(effects);
+ break;
+ case Policy::PermitOverride:
+ return permitOverrides(effects);
+ break;
+ case Policy::FirstApplicable:
+ return firstApplicable(effects);
+ break;
+ case Policy::FirstTargetMatching:
+ return firstMatchingTarget(effects);
+ break;
+ default:
+ Assert(false && "Wrong combining algorithm used");
+ return Error;
+ }
+}
+
+/**
+ *
+ * @param attrSet set of Subject attributes in policy that identifies target
+ * @return true if target is determined and matches, false and isUndertmined is set to true if the target is undetermined
+ * false and isUndetermined set to false if target is determined but doesn't match
+ */
+bool CombinerImpl::checkIfTargetMatches(
+ const std::list<const Subject *> * subjectsList,
+ bool &isUndetermined)
+{
+ if (subjectsList->empty()) {
+ return true;
+ }
+
+ std::list<const Subject *>::const_iterator it = subjectsList->begin();
+ bool match = false;
+ //According to BONDI 1.0 at least one target must match
+ while (it != subjectsList->end()) {
+ match = (*it)->matchSubject(this->getAttributeSet(), isUndetermined);
+ if (match) { //at least one match
+ break;
+ }
+ ++it;
+ }
+
+ #ifdef _DEBUG
+ if (match == Attribute::MRTrue) {
+ LogDebug("Target matches ");
+ } else if (match == Attribute::MRUndetermined) {
+ LogDebug("Target match undetermined ");
+ } else {
+ LogDebug("Target doesn't match");
+ }
+ #endif
+ return match;
+}
+
+const char * toString(Effect effect)
+{
+ const char * temp = "";
+
+ switch (effect) {
+ case Deny:
+ temp = "Deny";
+ break;
+ case Undetermined:
+ temp = "Undetermined";
+ break;
+ case PromptOneShot:
+ temp = "PromptOneShot";
+ break;
+ case PromptSession:
+ temp = "PromptSession";
+ break;
+ case PromptBlanket:
+ temp = "PromptBlanket";
+ break;
+ case Permit:
+ temp = "Permit";
+ break;
+ case Inapplicable:
+ temp = "Inapplicable";
+ break;
+ case NotMatchingTarget:
+ temp = "NotMatchingTarget";
+ break;
+ case Error:
+ temp = "Error";
+ break;
+ default:
+ Assert(false && "Wrong effect");
+ }
+ return temp;
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//
+// File: Condition.cpp
+// Author: notroot
+//
+// Created on June 3, 2009, 9:00 AM
+//
+
+#include <iostream>
+#include <dpl/log/log.h>
+#include <dpl/foreach.h>
+#include <dpl/ace/Serializer.h>
+#include <dpl/ace/Condition.h>
+
+/**
+ * Check if attribute in condition matches the values obtained from PIP
+ * attrSet - attributes from PIP
+ */
+
+Attribute::MatchResult Condition::evaluateCondition(
+ const AttributeSet * attrSet) const
+{
+ //Condition may include either matches of attributes or other conditions
+ //in this method all attributes are matched at first and if possible the
+ //condition is evaluated. If evaluation is not possible based solely on
+ //attributes then we start recursion into child conditions.
+
+ Attribute::MatchResult match;
+ bool undeterminedMatchFound = false;
+ bool isFinalMatch = false;
+
+ LogDebug("Attributes to be matched");
+ printAttributes(*attrSet);
+ LogDebug("Condition attributes values");
+ printAttributes(attributes);
+
+ if (this->isEmpty()) {
+ LogDebug("Condition is empty, returning true");
+ //Condition is empty, it means it evaluates to TRUE
+ return Attribute::MatchResult::MRTrue;
+ }
+
+ match = evaluateAttributes(attrSet, isFinalMatch, undeterminedMatchFound);
+ if (isFinalMatch) {
+ LogDebug("Evaluate attributes returning verdict" ) ; //<< match);
+ return match;
+ }
+
+ match = evaluateChildConditions(attrSet,
+ isFinalMatch,
+ undeterminedMatchFound);
+ if (isFinalMatch) {
+ LogDebug("Evaluate child conditions returning verdict" ); // << match);
+ return match;
+ }
+
+ if (undeterminedMatchFound) {
+ //If any child condition/attribute-match was undetermined and
+ //so far we couldn't make a decision then we must return undetermined
+ LogDebug("Evaluate condition returning MRUndetermined");
+ return Attribute::MatchResult::MRUndetermined;
+ }
+
+ if (this->isAndCondition()) {
+ match = Attribute::MatchResult::MRTrue;
+ } else if (this->isOrCondition()) {
+ match = Attribute::MatchResult::MRFalse;
+ } else {
+ Assert(false && "Condition has to be either AND or OR");
+ }
+ return match;
+}
+
+// KW Attribute::MatchResult Condition::performORalgorithm(const std::set<Attribute>* attrSet) const{
+// KW
+// KW Attribute::MatchResult match;
+// KW bool undeterminedMatchFound = false;
+// KW bool isFinalMatch = false;
+// KW
+// KW LogDebug("Performing OR algorithm");
+// KW
+// KW match = evaluateAttributes(attrSet, isFinalMatch, undeterminedMatchFound);
+// KW if(isFinalMatch){
+// KW LogDebug("OR algorithm evaluate attributes returning verdict" << match);
+// KW return match;
+// KW }
+// KW
+// KW match = evaluateChildConditions(attrSet, isFinalMatch, undeterminedMatchFound);
+// KW if(isFinalMatch){
+// KW return match;
+// KW }
+// KW
+// KW if(undeterminedMatchFound){
+// KW //If any child condition/attribute-match was undetermined and
+// KW //so far we couldn't make a decision then we must return undetermined
+// KW LogDebug("OR algorithm returning MRUndetermined");
+// KW return Attribute::MRUndetermined;
+// KW }
+// KW
+// KW LogDebug("OR algorithm returning MRFalse");
+// KW return Attribute::MRFalse;
+// KW }
+
+// KW Attribute::MatchResult Condition::performANDalgorithm(const std::set<Attribute>* attrSet) const{
+// KW
+// KW
+// KW Attribute::MatchResult match;
+// KW bool undeterminedMatchFound = false;
+// KW bool isFinalMatch = false;
+// KW
+// KW LogDebug("Performing AND algorithm");
+// KW match = evaluateAttributes(attrSet, isFinalMatch, undeterminedMatchFound);
+// KW if(isFinalMatch){
+// KW LogDebug("AND algorithm evaluate attributes returning verdict" << match);
+// KW return match;
+// KW }
+// KW match = evaluateChildConditions(attrSet, isFinalMatch, undeterminedMatchFound);
+// KW if(isFinalMatch){
+// KW LogDebug("AND algorithm evaluate child returning verdict " << match);
+// KW return match;
+// KW }
+// KW if(undeterminedMatchFound){
+// KW //If any child condition/attribute-match was undetermined and
+// KW //so far we couldn't make a decision then we must return undetermined
+// KW LogDebug("AND algorithm returning Undetermined");
+// KW return Attribute::MRUndetermined;
+// KW }
+// KW
+// KW LogDebug("AND algorithm returning MRTrue");
+// KW return Attribute::MRTrue;
+// KW
+// KW }
+
+Attribute::MatchResult Condition::evaluateAttributes(
+ const AttributeSet * attrSet,
+ bool& isFinalMatch,
+ bool & undeterminedMatchFound) const
+{
+ Attribute::MatchResult match = Attribute::MatchResult::MRUndetermined;
+
+ std::list<Attribute>::const_iterator condIt = this->attributes.begin();
+ while (condIt != this->attributes.end()) {
+ //Find the value of needed attribute, based on attribute name
+ AttributeSet::const_iterator attr =
+ std::find_if(attrSet->begin(),
+ attrSet->end(),
+ AceDB::BaseAttribute::UnaryPredicate(&(*condIt)));
+ if (attr == attrSet->end()) {
+ LogError("Couldn't find required attribute. This should not happen");
+ Assert(
+ false &&
+ "Couldn't find attribute required in condition. This should not happen"
+ "This means that some attributes has not been obtained from PIP");
+ //Return undetermined here because it seems one of the attributes is unknown/undetermined
+ isFinalMatch = true;
+ match = Attribute::MatchResult::MRUndetermined;
+ break;
+ }
+
+ match = condIt->matchAttributes(&(*(*attr)));
+ if ((match == Attribute::MatchResult::MRFalse) && isAndCondition()) {
+ //FALSE match found in AND condition
+ isFinalMatch = true;
+ break;
+ } else if ((match == Attribute::MatchResult::MRTrue) && isOrCondition()) {
+ //TRUE match found in OR condition
+ isFinalMatch = true;
+ break;
+ } else if (match == Attribute::MatchResult::MRUndetermined) {
+ //Just mark that there was undetermined value found
+ undeterminedMatchFound = true;
+ }
+ ++condIt;
+ }
+
+ return match;
+}
+
+Attribute::MatchResult Condition::evaluateChildConditions(
+ const AttributeSet * attrSet,
+ bool& isFinalMatch,
+ bool & undefinedMatchFound) const
+{
+ Attribute::MatchResult match = Attribute::MatchResult::MRUndetermined;
+
+ std::list<Condition>::const_iterator it = conditions.begin();
+ while (it != conditions.end()) {
+ match = it->evaluateCondition(attrSet);
+
+ if ((match == Attribute::MatchResult::MRFalse) && isAndCondition()) {
+ //FALSE match found in AND condition
+ LogDebug("Child conditions results MRFalse)");
+ isFinalMatch = true;
+ break;
+ } else if ((match == Attribute::MatchResult::MRTrue) && isOrCondition()) {
+ //TRUE match found in OR condition
+ LogDebug("Child conditions result MRTrue");
+ isFinalMatch = true;
+ break;
+ } else if (match == Attribute::MatchResult::MRUndetermined) {
+ undefinedMatchFound = true;
+ }
+ ++it;
+ }
+
+ return match;
+}
+
+void Condition::getAttributes(AttributeSet * attrSet)
+{
+ //Get attributes from current condition
+ FOREACH (it, attributes)
+ {
+ AceDB::BaseAttributePtr attr(new Attribute(it->getName(), it->getMatchFunction(), it->getType()));
+ attrSet->insert(attr);
+ }
+ //Get attributes from any child conditions
+ FOREACH (it, conditions)
+ {
+ it->getAttributes(attrSet);
+ }
+}
+
+Condition::Condition(std::istream& is,
+ Condition* parent)
+{
+ Serializer* serializer = Serializer::getInstance();
+
+ //Condition is a object in class
+ if (parent != NULL) {
+ this->parent = parent;
+ } else {
+ this->parent = NULL;
+ }
+
+ conditions = serializer->deserializeListConditions(is, this);
+ combineType = serializer->deserializeCombineType(is);
+ attributes = serializer->deserializeListAttributes(is);
+}
+
+bool Condition::serialize(std::ostream& os)
+{
+ Serializer* serializer = Serializer::getInstance();
+
+ serializer->serializeListConditions(os, conditions);
+ serializer->serializeCombineType(os, combineType);
+ serializer->serializeListAttributes(os, attributes);
+
+ return 0;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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/assert.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <error.h>
+#include <malloc.h>
+#include <sys/stat.h>
+#include <dpl/ace/ConfigurationManager.h>
+
+using namespace std;
+
+namespace {
+const string currentXMLSchema("bondixml.xsd");
+}
+
+ConfigurationManager * ConfigurationManager::instance = NULL;
+
+string ConfigurationManager::getCurrentPolicyFile(void) const
+{
+ return currentPolicyFile;
+}
+
+string ConfigurationManager::getFullPathToCurrentPolicyFile(void) const
+{
+ if (*(storagePath.rbegin()) == '/') {
+ return storagePath + currentPolicyFile;
+ }
+ return storagePath + "/" + currentPolicyFile;
+}
+
+string ConfigurationManager::getStoragePath(void) const
+{
+ return storagePath;
+}
+
+string ConfigurationManager::getFullPathToCurrentPolicyXMLSchema() const
+{
+ if (*(storagePath.rbegin()) == '/')
+ {
+ return storagePath + currentXMLSchema;
+ }
+ return storagePath + "/" + currentXMLSchema;
+}
+
+int ConfigurationManager::parse(const string &configFileName)
+{
+ configFile = configFileName;
+ int error = PARSER_SUCCESS;
+ policyFiles.clear();
+
+ reader = xmlNewTextReaderFilename(configFile.c_str());
+
+ if (reader == NULL) {
+ LogError("Parser does not exist");
+ error = PARSER_ERROR;
+ goto cleanUp;
+ }
+
+ if (xmlTextReaderSetParserProp(reader, XML_PARSER_VALIDATE, 1)) {
+ LogError("Error while setting parser validating.");
+ error = PARSER_ERROR;
+ Assert(false && "Cannot make XML parser validating");
+ goto cleanUp;
+ }
+
+ if (xmlTextReaderSetParserProp(reader, XML_PARSER_DEFAULTATTRS, 1)) {
+ LogError("Error while attribute defaulting.");
+ error = PARSER_ERROR;
+ Assert(false && "XML Parser cannot default xml attributes");
+ goto cleanUp;
+ }
+
+ int ret;
+ while (1 == (ret = xmlTextReaderRead(reader))) {
+ processNode();
+ if (xmlTextReaderIsValid(reader) == 0) {
+ LogError(
+ "Parser error while reading file " << configFile <<
+ ". File is not valid.");
+ error = PARSER_ERROR;
+ Assert(false && "Configuration Manager error");
+ goto cleanUp;
+ }
+ }
+ if (ret != 0) {
+ LogError("There were some errors while parsing XML file.");
+ }
+
+cleanUp:
+ if (reader != NULL) {
+ xmlFreeTextReader(reader);
+ }
+ return error;
+}
+
+void ConfigurationManager::extractFileAttributes()
+{
+ xmlChar *active = xmlTextReaderGetAttribute(reader, ATTR_ACTIVE_POLICY);
+ xmlActive = false;
+
+ if (active && active[0] == 't') {
+ xmlActive = true;
+ }
+
+ xmlFree(active);
+}
+
+void ConfigurationManager::startNodeHandler(void)
+{
+ xmlChar *name = xmlTextReaderName(reader);
+ switch (*name) {
+ case 'f': // file
+ extractFileAttributes();
+ break;
+ default:
+ break;
+ }
+ xmlFree(name);
+}
+
+void ConfigurationManager::endNodeHandler(void)
+{
+ xmlChar *name = xmlTextReaderName(reader);
+ switch (*name) {
+ case 'f':
+ policyFiles.push_back(currentText);
+ if (xmlActive) {
+ currentPolicyFile = currentText;
+ xmlActive = false;
+ }
+ currentText.clear();
+ break;
+ case 's':
+ storagePath = currentText;
+ currentText.clear();
+ break;
+ default:
+ break;
+ }
+ xmlFree(name);
+}
+
+void ConfigurationManager::textNodeHandler(void)
+{
+ xmlChar *text = xmlTextReaderValue(reader);
+ currentText = reinterpret_cast<const char*>(text);
+ xmlFree(text);
+}
+
+void ConfigurationManager::processNode(void)
+{
+ xmlReaderTypes type =
+ static_cast<xmlReaderTypes>(xmlTextReaderNodeType(reader));
+ switch (type) {
+ case XML_READER_TYPE_ELEMENT: startNodeHandler();
+ break;
+ case XML_READER_TYPE_END_ELEMENT: endNodeHandler();
+ break;
+ case XML_READER_TYPE_TEXT: textNodeHandler();
+ break;
+ default:
+ break;
+ }
+}
+
+int ConfigurationManager::addPolicyFile(const string & sourcePath)
+{
+ FILE * sourceFd = NULL, *destFd = NULL;
+ int flag = CM_OPERATION_SUCCESS;
+ int sourceLength;
+ string fileName;
+
+ string newFilePath(getStoragePath());
+ newFilePath.append("/");
+
+ if (sourcePath.empty()) {
+ LogError("Filename empty");
+ flag = CM_GENERAL_ERROR;
+ goto cleanup;
+ }
+
+ fileName = extractFilename(sourcePath);
+ newFilePath.append(fileName);
+
+ LogDebug("Adding new file " << newFilePath);
+ if (checkIfFileExistst(newFilePath)) {
+ LogError("Destination file already exists");
+ flag = CM_FILE_EXISTS;
+ goto cleanup;
+ }
+
+ sourceFd = fopen(sourcePath.c_str(), "r");
+ if (sourceFd == NULL) {
+ LogError("Source file opening failed");
+ flag = CM_GENERAL_ERROR;
+ goto cleanup;
+ }
+
+ destFd = fopen(newFilePath.c_str(), "w");
+ if (destFd == NULL) {
+ LogError("Destination file creation failed");
+ flag = CM_GENERAL_ERROR;
+ goto cleanup;
+ }
+
+ if (0 > (sourceLength = getFileSize(sourcePath))) {
+ LogError("getFileSize error");
+ flag = CM_GENERAL_ERROR;
+ goto cleanup;
+ }
+
+ if (!copyFile(sourceFd, destFd, sourceLength)) {
+ //Copying failed, we have to remove corrupted file
+ flag = CM_GENERAL_ERROR;
+ if (removePolicyFile(newFilePath) != CM_OPERATION_SUCCESS) {
+ flag = CM_REMOVE_ERROR;
+ }
+ goto cleanup;
+ }
+ policyFiles.push_back(fileName);
+
+ if (saveConfig() != CM_OPERATION_SUCCESS) {
+ LogError("Error while saving policy file");
+ //TODO HOW TO ROLLBACK save config?
+ }
+
+cleanup:
+
+ if (sourceFd) {
+ fclose(sourceFd);
+ }
+ if (destFd) {
+ fclose(destFd);
+ }
+
+ return flag;
+}
+
+int ConfigurationManager::removePolicyFile(const string& file)
+{
+ LogDebug("Trying to remove policy " << file);
+ int errorFlag = CM_OPERATION_SUCCESS;
+ string fileName = extractFilename(file);
+ string filePath(CONFIGURATION_MGR_TEST_POLICY_STORAGE);
+
+ if (fileName == currentPolicyFile) {
+ errorFlag = CM_REMOVE_CURRENT;
+ LogError("Cannot remove current policy");
+ goto end;
+ }
+
+ filePath.append("/").append(fileName);
+
+ if (remove(filePath.c_str()) != 0) {
+ if (checkIfFileExistst(filePath)) {
+ errorFlag = CM_REMOVE_ERROR;
+ LogError("Cannot delete file" << filePath);
+ goto end;
+ }
+ LogError("Cannot delete file" << filePath << " the file doesn't exist");
+ errorFlag = CM_REMOVE_NOT_EXISTING;
+ } else {
+ errorFlag = CM_OPERATION_SUCCESS;
+ }
+ //If remove was successful or unsuccessful but file doesn't exists then it
+ //should be removed from the list of available policies
+ policyFiles.remove(fileName);
+
+end:
+ return errorFlag;
+}
+
+string ConfigurationManager::extractFilename(const string & sourcePath) const
+{
+ //begining of filename without path
+ size_t filenamePos = sourcePath.rfind('/');
+
+ string tmp;
+ if (filenamePos == string::npos) {
+ tmp = sourcePath;
+ } else {
+ tmp = sourcePath.substr(filenamePos + 1);
+ }
+ LogDebug("Extracted filename " << tmp);
+ return tmp;
+}
+
+int ConfigurationManager::getFileSize(const string & path) const
+{
+ //get source file size
+ struct stat sourceStat;
+ int sourceLength;
+ if (stat(path.c_str(), &sourceStat) == -1) {
+ LogError("Reading file properties failed");
+ sourceLength = -1;
+ } else {
+ sourceLength = sourceStat.st_size;
+ }
+ return sourceLength;
+}
+
+bool ConfigurationManager::copyFile(FILE * sourceDesc,
+ FILE * destinationDesc,
+ int lenght) const
+{
+ int rv;
+ char *buffer = static_cast<char *>(malloc(lenght));
+ bool result = true;
+
+ if (!buffer) {
+ return false;
+ }
+
+ while ((rv = fread(buffer, sizeof (char), lenght, sourceDesc)) > 0) {
+ if (rv != lenght) {
+ if (!feof(sourceDesc)) {
+ LogError("Error while reading file ");
+ result = false;
+ break;
+ }
+ }
+
+ rv = fwrite(buffer, sizeof (char), lenght, destinationDesc);
+ if (rv != lenght) {
+ LogError("Write file failed ");
+ result = false;
+ break;
+ }
+ }
+ free(buffer);
+ return result;
+}
+
+bool ConfigurationManager::checkIfFileExistst(const string & newFilePath) const
+{
+ bool exists = false;
+ struct stat stats;
+ if (stat(newFilePath.c_str(), &stats) == 0) {
+ exists = true;
+ }
+ return exists;
+}
+
+int ConfigurationManager::changeCurrentPolicyFile(const std::string & fileName)
+{
+ int result = CM_OPERATION_SUCCESS;
+ string oldPolicyFile = currentPolicyFile;
+
+ string filePath(getStoragePath() + "/");
+ filePath += fileName;
+
+ if (!checkIfFileExistst(filePath)) {
+ //Policy file doesn't exist
+ result = CM_GENERAL_ERROR;
+ LogError("Error: policy file " << filePath << " doesn't exist");
+ goto end;
+ }
+ if (result == CM_OPERATION_SUCCESS) {
+ //Adding file to storage succeeded
+ currentPolicyFile = extractFilename(filePath);
+ //Try to save the configuration file
+ result = saveConfig();
+ }
+ if (result != CM_OPERATION_SUCCESS) {
+ //rollback changes
+ currentPolicyFile = oldPolicyFile;
+ LogError("Error while saving policy file");
+ //TODO HOW TO ROLLBACK save config?
+ }
+
+end:
+ return result;
+}
+
+int ConfigurationManager::saveConfig()
+{
+ std::ofstream output(configFile.c_str());
+ int errorFlag = CM_OPERATION_SUCCESS;
+
+ output << "<?xml version=\"1.0\" ?>" << std::endl;
+ output <<
+ "<!DOCTYPE manager-settings SYSTEM \"" ACE_CONFIGURATION_DTD "\">" <<
+ std::endl;
+ output << "<manager-settings>" << std::endl;
+ output << " <storage-path>" << storagePath << "</storage-path>" <<
+ std::endl;
+ output << " <policy-files>" << std::endl;
+ for (list<string>::const_iterator it = policyFiles.begin();
+ it != policyFiles.end();
+ ++it) {
+ output << "\t<file ";
+ if (*it == currentPolicyFile) {
+ output << "active=\"true\"";
+ }
+ output << ">" << *it << "</file>" << std::endl;
+ }
+ output << " </policy-files>\n";
+ output << " </manager-settings>";
+ output.close();
+
+ //TODO should we add 'eof' here?
+ if (output.bad() || output.fail()) {
+ //There were some errors while writing to file
+ errorFlag = CM_GENERAL_ERROR;
+ }
+
+ return errorFlag;
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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/ace/NodeFactory.h>
+
+NodeFactory* NodeFactory::pInstance = NULL;
+
+AbstractTreeElement* NodeFactory::create(std::istream& is,
+ TreeNode::TypeID id)
+{
+ AbstractTreeElement* node;
+
+ switch (id) {
+ case TreeNode::Policy:
+ node = new Policy(is);
+ break;
+ case TreeNode::PolicySet:
+ node = new PolicySet(is);
+ break;
+ case TreeNode::Rule:
+ node = new Rule(is);
+ break;
+ default:
+ node = NULL;
+ break;
+ }
+
+ return node;
+}
+
+NodeFactory* NodeFactory::getInstance()
+{
+ if (pInstance == NULL) {
+ pInstance = new NodeFactory;
+ }
+ return pInstance;
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//
+//
+//
+// @ Project : Access Control Engine
+// @ File Name : Policy.cpp
+// @ Date : 2009-05-06
+// @ Author : Samsung
+//
+//
+
+#include <dpl/ace/Policy.h>
+#include <dpl/ace/Serializer.h>
+
+Policy::Policy(std::istream& is)
+{
+ Serializer* serializer = Serializer::getInstance();
+
+ std::list<const Subject*>* pList;
+ pList = serializer->deserializeListSubjects(is);
+ subjects = pList;
+
+ combineAlgorithm = serializer->deserializeCombineAlgorithm(is);
+}
+
+void Policy::serialize(std::ostream& os)
+{
+ Serializer* serializer = Serializer::getInstance();
+
+ serializer->serializeListSubjects(os, *subjects);
+ serializer->serializeCombineAlgorithm(os, combineAlgorithm);
+}
+
+Policy::~Policy()
+{
+ for (std::list<const Subject *>::iterator it = subjects->begin();
+ it != subjects->end();
+ ++it) {
+ delete *it;
+ }
+ delete subjects;
+}
+
+void Policy::printData()
+{
+ std::string subject;
+ if (subjects != NULL && subjects->size()) {
+ subject = (subjects->front())->getSubjectId();
+ }
+ std::string algorithm = printCombineAlgorithm(this->combineAlgorithm);
+
+ std::cout << "subject: " << subject << " algorithm: " << algorithm <<
+ std::endl;
+}
+
+std::string Policy::printCombineAlgorithm(CombineAlgorithm algorithm)
+{
+ switch (algorithm) {
+ case DenyOverride:
+ return "DenyOverride";
+ case PermitOverride:
+ return "PermitOverride";
+ case FirstApplicable:
+ return "FirstApplicable";
+ case FirstTargetMatching:
+ return "FirstTargetMatching";
+ default:
+ return "ERROR: Wrong Algorithm";
+ }
+}
+
+const char * toString(Policy::CombineAlgorithm algorithm)
+{
+ switch (algorithm) {
+ case Policy::DenyOverride:
+ return "DenyOverride";
+ case Policy::PermitOverride:
+ return "PermitOverride";
+ case Policy::FirstApplicable:
+ return "FirstApplicable";
+ case Policy::FirstTargetMatching:
+ return "FirstTargetMatching";
+ default:
+ return "ERROR: Wrong Algorithm";
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_logic.cpp
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @author Ming Jin(ming79.jin@samsung.com)
+ * @version 1.0
+ * @brief Implementation file for security logic
+ */
+#include <dpl/ace/PolicyEnforcementPoint.h>
+
+#include <sstream>
+#include <algorithm>
+#include <list>
+#include <string>
+#include <sstream>
+#include <stdexcept>
+#include <cstdlib>
+#include <map>
+
+#include <dpl/assert.h>
+#include <dpl/exception.h>
+#include <dpl/log/log.h>
+
+#include <dpl/ace/PolicyEvaluatorFactory.h>
+#include <dpl/ace/PolicyResult.h>
+#include <dpl/ace/Request.h>
+
+using namespace WrtDB;
+
+PolicyEnforcementPoint::PolicyEnforcementPoint() :
+ m_wrt(0),
+ m_res(0),
+ m_sys(0),
+ m_pdp(0),
+ m_pip(0)
+{}
+
+void PolicyEnforcementPoint::terminate()
+{
+ LogInfo("PolicyEnforcementPoint is being deinitialized.");
+
+ delete m_sys;
+ delete m_res;
+ delete m_wrt;
+ delete m_pdp;
+ delete m_pip;
+ m_sys = 0;
+ m_res = 0;
+ m_wrt = 0;
+ m_pdp = 0;
+ m_pip = 0;
+}
+
+PolicyEnforcementPoint::~PolicyEnforcementPoint()
+{
+ Assert((m_sys == 0) && "You must run "
+ "PolicyEnforcementPoint::Deinitialize before exit program!");
+}
+
+void PolicyEnforcementPoint::initialize(
+ IWebRuntime *wrt,
+ IResourceInformation *resource,
+ IOperationSystem *operation)
+{
+ if (m_wrt) {
+ ThrowMsg(PEPException::AlreadyInitialized,
+ "Policy Enforcement Point is already initialzed");
+ }
+
+ m_wrt = wrt;
+ m_res = resource;
+ m_sys = operation;
+
+ if (this->m_pip != NULL) {
+ this->m_pip->update(m_wrt, m_res, m_sys);
+ return;
+ }
+
+ this->m_pip = new PolicyInformationPoint(wrt, m_res, m_sys);
+ this->m_pdp = new PolicyEvaluator(m_pip);
+
+ if (!this->m_pdp->initPDP()) {
+ Assert(0);
+ }
+}
+
+PolicyResult PolicyEnforcementPoint::check(Request &request)
+{
+ return m_pdp->getPolicyForRequest(request);
+}
+
+void PolicyEnforcementPoint::updatePolicy(const std::string &policy)
+{
+ LogDebug("ACE updatePolicy: " << policy);
+ int errorCode = 0;
+
+ if (m_pdp == NULL) {
+ LogError("Evaluator not set. Ignoring message.");
+ Assert(false && "UpdateClient error on receiving event");
+ } else {
+ LogDebug("Emitting update signal.");
+ errorCode = m_pdp->updatePolicy(policy.c_str());
+ }
+
+ LogDebug("Sending reponse: " << errorCode);
+}
+
+OptionalPolicyResult PolicyEnforcementPoint::checkFromCache(Request &request)
+{
+ return m_pdp->getPolicyForRequestFromCache(request);
+ // return OptionalPolicyResult();
+}
+
+OptionalPolicyResult PolicyEnforcementPoint::check(Request &request,
+ bool fromCacheOnly)
+{
+ return m_pdp->getPolicyForRequest(request, fromCacheOnly);
+ // return OptionalPolicyResult();
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//
+//
+//
+// @ Project : Access Control Engine
+// @ File Name : PolicyEvaluator.cpp
+// @ Date : 2009-05-06
+// @ Author : Samsung
+//
+//
+
+#include <dpl/assert.h>
+#include <dpl/foreach.h>
+
+#include <dpl/ace/PolicyEvaluator.h>
+#include <dpl/ace/TreeNode.h>
+#include <dpl/ace/Policy.h>
+#include <dpl/ace/Rule.h>
+#include <dpl/ace/Attribute.h>
+//#include <dpl/ace/"UserDecisionTestStub.h>
+#include <dpl/ace/SettingsLogic.h>
+#include <dpl/ace-dao-rw/AceDAO.h>
+#include <dpl/ace-dao-ro/PreferenceTypes.h>
+#include <dpl/ace/parser.h>
+
+using namespace AceDB;
+
+PolicyEvaluator::~PolicyEvaluator()
+{
+ delete m_combiner;
+}
+
+bool PolicyEvaluator::initPDP()
+{
+ ConfigurationManager * configMgr = ConfigurationManager::getInstance();
+ if (configMgr == NULL) {
+ LogError("ACE fatal error: failed to create configuration manager");
+ return false;
+ }
+
+ Parser parser;
+ m_root = parser.parse(
+ configMgr->getFullPathToCurrentPolicyFile(),
+ configMgr->getFullPathToCurrentPolicyXMLSchema());
+
+ if (NULL == m_root) {
+ LogError("ACE fatal error: cannot parse XML file");
+ }
+
+ return true;
+}
+
+bool PolicyEvaluator::fillAttributeWithPolicy()
+{
+ if (m_attributeSet.empty()) {
+ if (!extractAttributes()) {
+ LogInfo(
+ "Warning attribute set cannot be extracted. Returning Deny");
+ return false;
+ }
+ } else {
+ LogDebug("Required attribute set found in database");
+ }
+ return true;
+}
+
+PolicyResult PolicyEvaluator::effectToPolicyResult(Effect effect){
+ if (Effect::Deny == effect) {
+ return PolicyEffect::DENY;
+ }
+ if (Effect::Undetermined == effect) {
+ return PolicyResult::Value::UNDETERMINED;
+ }
+ if (Effect::PromptOneShot == effect) {
+ return PolicyEffect::PROMPT_ONESHOT;
+ }
+ if (Effect::PromptSession == effect) {
+ return PolicyEffect::PROMPT_SESSION;
+ }
+ if (Effect::PromptBlanket == effect) {
+ return PolicyEffect::PROMPT_BLANKET;
+ }
+ if (Effect::Permit == effect) {
+ return PolicyEffect::PERMIT;
+ }
+ if (Effect::Inapplicable == effect) {
+ return PolicyDecision::Value::NOT_APPLICABLE;
+ }
+ return PolicyEffect::DENY;
+}
+
+OptionalPolicyResult PolicyEvaluator::getPolicyForRequestInternal(bool fromCacheOnly)
+{
+ //ADD_PROFILING_POINT("Search cached verdict in database", "start");
+
+ OptionalPolicyResult result = AceDAO::getPolicyResult(
+ m_attributeSet);
+
+ //ADD_PROFILING_POINT("Search cached verdict in database", "stop");
+
+ if (fromCacheOnly || !result.IsNull()) {
+ return result;
+ }
+
+ //ADD_PROFILING_POINT("EvaluatePolicy", "start");
+
+ Effect policyEffect = evaluatePolicies(m_root);
+
+ //ADD_PROFILING_POINT("EvaluatePolicy", "stop");
+
+ LogDebug("Policy effect is: " << toString(policyEffect));
+
+ result = effectToPolicyResult(policyEffect);
+
+ AceDAO::setPolicyResult(this->m_attributeSet, *result);
+ return result;
+}
+
+// +----------------+---------+---------+------+--------+
+// |\User setting | PERMIT | PROMPT* | DENY | DEF |
+// | \ | | | | |
+// |Policy result\ | | | | |
+// |----------------+---------+---------+------+--------+
+// |PERMIT | PERMIT | PROMPT* | DENY | PERMIT |
+// |----------------+---------+---------+------+--------+
+// |PROMPT* | PROMPT* | PR MIN | DENY | PROMPT*|
+// |----------------+---------+---------+------+--------+
+// |DENY | DENY | DENY | DENY | DENY |
+// |----------------+---------+---------+------+--------+
+// |UNDETERMIND | UNDET | UNDET | DENY | UNDET |
+// |----------------+---------+---------+------+--------+
+// |NOT_AP | PEMIT | PROMPT* | DENY | NOT_AP |
+// +----------------+---------+---------+------+--------+
+
+static PolicyResult getMostRestrict(PreferenceTypes globalPreference,
+ const PolicyResult &policyResult)
+{
+ if (globalPreference == PreferenceTypes::PREFERENCE_PERMIT &&
+ policyResult == PolicyEffect::PERMIT)
+ {
+ return PolicyEffect::PERMIT;
+ }
+
+ if (globalPreference == PreferenceTypes::PREFERENCE_DENY ||
+ policyResult == PolicyEffect::DENY)
+ {
+ return PolicyEffect::DENY;
+ }
+
+ if (policyResult == PolicyResult::UNDETERMINED) {
+ return PolicyResult::UNDETERMINED;
+ }
+
+ if (globalPreference == PreferenceTypes::PREFERENCE_DEFAULT)
+ {
+ return policyResult;
+ }
+
+ if (globalPreference == PreferenceTypes::PREFERENCE_ONE_SHOT_PROMPT ||
+ policyResult == PolicyEffect::PROMPT_ONESHOT)
+ {
+ return PolicyEffect::PROMPT_ONESHOT;
+ }
+
+ if (globalPreference == PreferenceTypes::PREFERENCE_SESSION_PROMPT ||
+ policyResult == PolicyEffect::PROMPT_SESSION)
+ {
+ return PolicyEffect::PROMPT_SESSION;
+ }
+
+ if (globalPreference == PreferenceTypes::PREFERENCE_BLANKET_PROMPT ||
+ policyResult == PolicyEffect::PROMPT_BLANKET)
+ {
+ return PolicyEffect::PROMPT_BLANKET;
+ }
+
+ return PolicyEffect::PERMIT;
+}
+
+OptionalPolicyResult PolicyEvaluator::getPolicyForRequestFromCache(
+ const Request &request)
+{
+ return getPolicyForRequest(request, true);
+}
+
+PolicyResult PolicyEvaluator::getPolicyForRequest(const Request &request)
+{
+ auto result = this->getPolicyForRequest(request, false);
+ Assert(!result.IsNull() &&
+ "Policy always has to be evaluated to valid state");
+ return *result;
+}
+
+OptionalPolicyResult PolicyEvaluator::getPolicyForRequest(
+ const Request &request,
+ bool fromCacheOnly)
+{
+ //ADD_PROFILING_POINT("getPolicyForRequest", "start");
+ m_attributeSet.clear();
+
+ try {
+ // Check which attributes should be used
+ // memory alocated, free in destructor
+ //ADD_PROFILING_POINT("getAttributes", "start");
+ AceDB::AceDAO::getAttributes(&m_attributeSet);
+ //ADD_PROFILING_POINT("getAttributes", "stop");
+
+ // If attributes can't be resolved then check the policy
+ if (!fillAttributeWithPolicy()) {
+ //ADD_PROFILING_POINT("getPolicyForRequest", "stop");
+ return OptionalPolicyResult(PolicyEffect::DENY);
+ }
+
+ //ADD_PROFILING_POINT("getAttributesValues", "start");
+ m_pip->getAttributesValues(&request, &m_attributeSet);
+ //ADD_PROFILING_POINT("getAttributesValues", "stop");
+ LogDebug("==== Attributes set by PIP ====");
+ printAttributes(m_attributeSet);
+ LogDebug("==== End of attributes set by PIP ====");
+
+ OptionalPolicyResult policyResult =
+ getPolicyForRequestInternal(fromCacheOnly);
+
+ LogDebug("==== getPolicyForRequestInternal result (PolicyResult): "
+ << policyResult << "=====");
+
+ if (policyResult.IsNull()) {
+ if (fromCacheOnly) {
+ return OptionalPolicyResult::Null;
+ } else {
+ LogError("Policy evaluated to NULL value");
+ Assert(false && "Policy evaluated to NULL value");
+ return OptionalPolicyResult::Null;
+ }
+ }
+
+ PreferenceTypes globalPreference =
+ SettingsLogic::findGlobalUserSettings(request);
+
+ auto ret = getMostRestrict(globalPreference, *policyResult);
+ //ADD_PROFILING_POINT("getPolicyForRequest", "stop");
+ return OptionalPolicyResult(ret);
+
+ } catch (AceDB::AceDAO::Exception::DatabaseError &e) {
+ LogError("Database error");
+ DPL::Exception::DisplayKnownException(e);
+ //ADD_PROFILING_POINT("getPolicyForRequest", "stop");
+ return OptionalPolicyResult(PolicyEffect::DENY);
+ }
+}
+
+
+bool PolicyEvaluator::extractAttributes()
+{
+ if (m_root == NULL) {
+ return false;
+ }
+
+ //We check if root target matches. In general the root's target should be empty
+ //Otherwise it would have to have all the subjects available specified
+ //But just to be on the safe side ( and for tests) add this checking
+ const Policy * policy = dynamic_cast<const Policy *>(m_root->getElement());
+ Assert(
+ policy != NULL &&
+ "Policy element has been null while attribute extracting");
+
+ extractTargetAttributes(policy);
+ extractAttributesFromSubtree(m_root); //Enter recursion
+
+ return true;
+}
+
+void PolicyEvaluator::extractTargetAttributes(const Policy *policy)
+{
+ std::list<const Subject *>::const_iterator it =
+ policy->getSubjects()->begin();
+ for (; it != policy->getSubjects()->end(); ++it)
+ {
+ const std::list<Attribute> & attrList = (*it)->getTargetAttributes();
+ FOREACH(it2, attrList)
+ {
+ BaseAttributePtr attr(new Attribute((*it2).getName(),
+ (*it2).getMatchFunction(), (*it2).getType()));
+ m_attributeSet.insert(attr);
+ }
+ }
+}
+
+/**
+ *
+ * @param *root - the root of the original (full) subtree of politics
+ * @param *newRoot - the pointer to the root of the copy (reduced) subtree of politics
+ */
+void PolicyEvaluator::extractAttributesFromSubtree(const TreeNode *root)
+{
+ const ChildrenSet & children = root->getChildrenSet();
+
+ for (
+ std::list<TreeNode *>::const_iterator it = children.begin();
+ it != children.end();
+ ++it
+ ) {
+ TreeNode * node = *it;
+ if (node->getTypeID() != TreeNode::Policy && node->getTypeID() !=
+ TreeNode::PolicySet) {
+ //It is not a policy so we may be sure that we have already checked that SubjectId matches
+ //Add new node to new tree and extract attributes
+
+ extractAttributesFromRules(node);
+ } else { //TreeNode is a Policy or PolicySet
+ const Policy * policy =
+ dynamic_cast<const Policy *>(node->getElement());
+ //We will be needing also the attributes from target
+ if (policy) {
+ extractTargetAttributes(policy);
+ } else {
+ LogError(" extractAttributesFromSubtree policy=NULL");
+ }
+ //Enter recursion
+ extractAttributesFromSubtree(node);
+ }
+ }
+}
+
+bool PolicyEvaluator::extractAttributesFromRules(const TreeNode *root)
+{
+ Assert(
+ root->getTypeID() == TreeNode::Rule
+ &&
+ "Tree structure, extracting attributes from node that is not a rule");
+ Rule * rule = dynamic_cast<Rule *>(root->getElement());
+ Assert(rule != NULL);
+ //Get attributes from rule
+ rule->getAttributes(&m_attributeSet);
+
+ //[CR] consider returned value, because its added only to eliminate errors
+ return true;
+}
+
+Effect PolicyEvaluator::evaluatePolicies(const TreeNode * root)
+{
+ if (root == NULL) {
+ LogInfo("Error: policy tree doesn't exist. "
+ "Probably xml file is missing");
+ return Deny;
+ }
+
+ if (m_attributeSet.empty()) {
+ LogInfo("Warning: evaluatePolicies: attribute set was empty");
+ }
+ m_combiner->setAttributeSet(&m_attributeSet);
+ return m_combiner->combinePolicies(root);
+}
+
+int PolicyEvaluator::updatePolicy(const char* newPolicy)
+{
+ ConfigurationManager* configMgr = ConfigurationManager::getInstance();
+
+ if (NULL == configMgr) {
+ LogError("ACE fatal error: failed to create configuration manager");
+ return POLICY_PARSING_ERROR;
+ }
+
+ int result = POLICY_PARSING_SUCCESS;
+ if (newPolicy == NULL) {
+ LogError("Policy Update: incorrect policy name");
+ return POLICY_FILE_ERROR;
+ }
+ LogDebug("Starting update policy: " << newPolicy);
+
+ Parser parser;
+ TreeNode *backup = m_root;
+
+ m_root = parser.parse(
+ newPolicy,
+ configMgr->getFullPathToCurrentPolicyXMLSchema());
+
+ if (NULL == m_root) {
+ m_root = backup;
+ LogError("Policy Update: corrupted policy file");
+ result = POLICY_PARSING_ERROR;
+ } else {
+ m_currentPolicyFile = newPolicy;
+ backup->releaseResources();
+ LogInfo("Policy Update: successful.");
+ try {
+ AceDAO::resetDatabase();
+ } catch (AceDAO::Exception::DatabaseError &e) {
+ }
+ }
+ return result;
+}
+
+std::string PolicyEvaluator::getCurrentPolicy(){
+ return m_currentPolicyFile;
+}
+
+const char * toString(Validity validity)
+{
+ switch (validity) {
+ case Validity::ONCE:
+ return "Once";
+ break;
+ case Validity::SESSION:
+ return "Session";
+ case Validity::ALWAYS:
+ return "Always";
+ default:
+ return "WRONG VALIDITY";
+ }
+}
+
+const char * toString(Verdict verdict)
+{
+ switch (verdict) {
+ case Verdict::VERDICT_PERMIT:
+ return "Permit";
+ case Verdict::VERDICT_DENY:
+ return "Deny";
+ case Verdict::VERDICT_INAPPLICABLE:
+ return "Inapplicable";
+ case Verdict::VERDICT_UNKNOWN:
+ return "Unknown";
+ case Verdict::VERDICT_UNDETERMINED:
+ return "Undetermined";
+ case Verdict::VERDICT_ERROR:
+ return "Error";
+ case Verdict::VERDICT_ASYNC:
+ return "Async";
+ default:
+ return "Wrong verdict value";
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//
+//
+//
+//
+// @ Project : Access Control Engine
+// @ File Name : PolicyInformationPoint.cpp
+// @ Date : 2009-05-06
+// @ Author : Samsung
+//
+//
+#include <dpl/ace/PolicyInformationPoint.h>
+
+#include <map>
+#include <dpl/log/log.h>
+
+#include <dpl/assert.h>
+#include <dpl/foreach.h>
+
+#include <dpl/ace/Attribute.h>
+#include <dpl/ace-dao-ro/BaseAttribute.h>
+
+using namespace AceDB;
+
+PolicyInformationPoint::~PolicyInformationPoint()
+{
+}
+
+/* gather attributes values from adequate interfaces */
+PipResponse PolicyInformationPoint::getAttributesValues(const Request* request,
+ AttributeSet* attributes)
+{
+ int subjectReturn = 0;
+ int resourceReturn = 0;
+ int operationReturn = 0;
+ int functionReturn = 0;
+ /* create query lists */
+ createQueries(attributes);
+
+ /* check if subject attributes query has any elements*/
+ if (!subjectAttributesQuery.empty()) {
+ /* get Subject Attributes */
+ subjectReturn = wrtInterface->getAttributesValues(
+ *request,
+ &subjectAttributesQuery);
+ }
+
+ AttributeSet::const_iterator iter2;
+ FOREACH(iter, subjectAttributesQuery)
+ {
+ if (iter->second == NULL) {
+ Attribute attr(*(iter->first));
+ attr.setType(Attribute::Type::Subject);
+ iter2 = std::find_if(attributes->begin(),
+ attributes->end(),
+ BaseAttribute::UnaryPredicate(&attr));
+ Assert(iter2 != attributes->end() && "This should not happen, "
+ "the attribute MUST be in attribute set");
+ (*iter2)->setUndetermind(true);
+ }
+ }
+
+ /* check if resource attributes query has any elements*/
+ if (!resourceAttributesQuery.empty()) {
+ /* get Resource Attributes */
+ resourceReturn = resourceInformation->getAttributesValues(
+ *request,
+ &resourceAttributesQuery);
+ /* error analyzys*/
+ resourceReturn <<= ERROR_SHIFT_RESOURCE;
+ }
+
+ FOREACH(iter, resourceAttributesQuery)
+ {
+ if (iter->second == NULL) {
+ LogInfo("Found undetermined attribute");
+ Attribute attr(*(iter->first));
+ attr.setType(Attribute::Type::Resource);
+ iter2 = std::find_if(attributes->begin(),
+ attributes->end(),
+ BaseAttribute::UnaryPredicate(&attr));
+ Assert(iter2 != attributes->end() && "This should not happen, "
+ "the attribute MUST be in attribute set");
+ (*iter2)->setUndetermind(true);
+ }
+ }
+
+ /* check if resource attributes query has any elements*/
+ if (!environmentAttributesQuery.empty()) {
+ /* get enviroment attributes */
+ operationReturn = operationSystem->getAttributesValues(
+ *request,
+ &environmentAttributesQuery);
+ /* error analyzys*/
+ operationReturn <<= ERROR_SHIFT_OS;
+ }
+
+ FOREACH(iter, environmentAttributesQuery)
+ {
+ if (iter->second == NULL) {
+ //it doesnt change uniqueness of a set element so we can const_cast
+ Attribute attr(*(iter->first));
+ attr.setType(Attribute::Type::Environment);
+ iter2 = find_if(attributes->begin(),
+ attributes->end(),
+ BaseAttribute::UnaryPredicate(&attr));
+ Assert(iter2 != attributes->end() && "This should not happen, "
+ "the attribute MUST be in attribute set");
+ (*iter2)->setUndetermind(true);
+ }
+ }
+
+ /* check if functionParam attributes query has any elements*/
+ if (!functionParamAttributesQuery.empty() && request->getFunctionParam()) {
+ /* get params attributes */
+ functionReturn = request->getFunctionParam()->getAttributesValues(
+ *request,
+ &functionParamAttributesQuery);
+ /* error analyzys*/
+ functionReturn <<= ERROR_SHIFT_FP;
+ }
+
+ FOREACH(iter, functionParamAttributesQuery)
+ {
+ if (iter->second == NULL) {
+ //it doesnt change uniqueness of a set element so we can const_cast
+ Attribute attr(*(iter->first));
+ attr.setType(Attribute::Type::FunctionParam);
+ iter2 = find_if(attributes->begin(),
+ attributes->end(),
+ BaseAttribute::UnaryPredicate(&attr));
+ Assert(iter2 != attributes->end() && "This should not happen, "
+ "the attribute MUST be in attribute set");
+ (*iter2)->setUndetermind(true);
+ }
+ }
+
+ /** clear query lists*/
+ resourceAttributesQuery.clear();
+ environmentAttributesQuery.clear();
+ subjectAttributesQuery.clear();
+ functionParamAttributesQuery.clear();
+
+ return subjectReturn | resourceReturn | operationReturn | functionReturn;
+}
+
+/** create query lists */
+void PolicyInformationPoint::createQueries(AttributeSet* attributes)
+{
+ AttributeSet::const_iterator it;
+
+ enum Attribute::Type type;
+
+ /**iterate all attributes and split them into adequate query */
+ FOREACH (it, *attributes) {
+ type = (*it)->getType();
+
+ switch (type) {
+ case Attribute::Type::Subject:
+ subjectAttributesQuery.push_back(ATTRIBUTE((*it)->getName(),
+ (*it)->getValue()));
+ break;
+
+ case Attribute::Type::Environment:
+ environmentAttributesQuery.push_back(ATTRIBUTE((*it)->getName(),
+ (*it)->getValue()));
+ break;
+
+ case Attribute::Type::Resource:
+ resourceAttributesQuery.push_back(ATTRIBUTE((*it)->getName(),
+ (*it)->getValue()));
+ break;
+
+ case Attribute::Type::FunctionParam:
+ functionParamAttributesQuery.push_back(ATTRIBUTE((*it)->getName(),
+ (*it)->getValue()));
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//
+//
+//
+// @ Project : Access Control Engine
+// @ File Name : Rule.h
+// @ Date : 2009-05-06
+// @ Author : Samsung
+//
+//
+
+#include <iostream>
+#include <dpl/log/log.h>
+
+#include <dpl/ace/Rule.h>
+#include <dpl/ace/Serializer.h>
+
+void Rule::printData()
+{
+ std::cout << "Rule: effect: " << printEffect(this->effect) <<
+ " condition: " << this->condition;
+}
+
+std::string Rule::printEffect(const Effect effect) const
+{
+ switch (effect) {
+ case Deny:
+ return "Deny";
+ case PromptBlanket:
+ return "PromptBlanket";
+ case PromptOneShot:
+ return "PromptOneShot";
+ case PromptSession:
+ return "PromptSession";
+ case Permit:
+ return "Permit";
+ case Inapplicable:
+ return "Inapplicable";
+ case Error:
+ return "Error";
+ default:
+ return "ERROR";
+ }
+}
+
+Effect Rule::evaluateRule(const AttributeSet * attrSet) const
+{
+ Attribute::MatchResult result = condition.evaluateCondition(attrSet);
+
+ if (result == Attribute::MatchResult::MRUndetermined) {
+ // LogInfo("Rule is undetermined");
+ return Undetermined;
+ } else if (result == Attribute::MatchResult::MRTrue) {
+ // LogInfo("Rule effect "<<printEffect(effect));
+ return effect;
+ }
+ // LogInfo("Rule is inapplicable");
+ return Inapplicable;
+}
+
+Rule::Rule(std::istream& is)
+{
+ Serializer* serializer = Serializer::getInstance();
+
+ condition = serializer->deserializeCondition(is);
+ effect = serializer->deserializeEffect(is);
+}
+
+void Rule::serialize(std::ostream& os)
+{
+ Serializer* serializer = Serializer::getInstance();
+
+ serializer->serializeCondition(os, condition);
+ serializer->serializeEffect(os, effect);
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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/log/log.h>
+#include <dpl/foreach.h>
+#include <dpl/ace/Serializer.h>
+#include <dpl/ace/NodeFactory.h>
+
+Serializer* Serializer::pInstance = NULL;
+
+Serializer* Serializer::getInstance()
+{
+ if (pInstance == NULL) {
+ pInstance = new Serializer;
+ }
+ return pInstance;
+}
+
+void Serializer::serializeInt(std::ostream& os,
+ int value)
+{
+ os.write((char*)(&value), sizeof(value));
+ //LogInfo("SerializeInt: " <<value);
+
+ Assert(os.bad() == false && "Error Writing to file failure");
+}
+
+int Serializer::deserializeInt(std::istream& is)
+{
+ int value = 0;
+ is.read((char*)(&value), sizeof(value));
+
+ LogInfo("DEserializeInt: " << value);
+ return value;
+}
+
+void Serializer::serializeString(std::ostream& os,
+ const std::string& text) const
+{
+ int dataLength = text.size();
+ os.write((char*)(&dataLength), sizeof(dataLength));
+ os.write(text.c_str(), dataLength);
+
+ Assert(os.bad() == false && "Error Writing to file failure");
+
+ //LogInfo("SerializeString: " <<text);
+}
+
+std::string Serializer::deserializeString(std::istream& is)
+{
+ //length
+ int dataLength = 0;
+ is.read((char*)(&dataLength), sizeof(dataLength));
+
+ char *buf = new char[dataLength + 1];
+ is.read(buf, dataLength);
+ buf[dataLength] = '\0';
+
+ std::string result = buf;
+ delete[] buf;
+
+ //LogInfo("DEserializeString: " <<result);
+ return result;
+}
+
+void Serializer::serializeListAttributes(std::ostream& os,
+ const std::list<Attribute>& inputList)
+{
+ int dataLength = inputList.size();
+ os.write((char*)(&dataLength), sizeof(dataLength));
+
+ //LogInfo("SerializeListAttributes SIZE: " <<dataLength);
+ FOREACH(it,inputList)
+ {
+ it->serialize(os);
+ }
+
+ Assert(os.bad() == false && "Error Writing to file failure");
+}
+
+std::list<Attribute> Serializer::deserializeListAttributes(std::istream& is)
+{
+ std::list<Attribute> outputList;
+
+ int numElem = 0;
+ is.read((char*)(&numElem), sizeof(numElem));
+
+ //LogInfo("DESerializeListAttributes SIZE: " <<numElem);
+
+ Attribute* attr;
+
+ for (int i = 0; i < numElem; i++) {
+ attr = new Attribute(is);
+ outputList.push_back(*attr);
+ delete attr;
+ }
+
+ return outputList;
+}
+
+void Serializer::serializeType(std::ostream& os,
+ const Attribute::Type& typeId) const
+{
+ os.write((char*)(&typeId), sizeof(typeId));
+
+ Assert(os.bad() == false && "Error Writing to file failure");
+
+ //LogInfo("SerializeTypeId: " <<typeId);
+}
+
+Attribute::Type Serializer::deserializeType(std::istream& is)
+{
+ Attribute::Type typeId(AceDB::BaseAttribute::Type::Subject);
+
+ is.read((char*)(&typeId), sizeof(typeId));
+ //LogInfo("DEserializeTypeId: " <<typeId);
+ return typeId;
+}
+
+void Serializer::serializeListStrings(std::ostream& os,
+ const std::list<std::string>& inputList) const
+{
+ int dataLength = inputList.size();
+ os.write((char*)(&dataLength), sizeof(dataLength));
+
+ FOREACH(it, inputList)
+ {
+ serializeString(os, *it);
+ }
+
+ Assert(os.bad() == false && "Error Writing to file failure");
+}
+
+std::list<std::string> Serializer::deserializeListStrings(std::istream& is)
+{
+ std::list<std::string> outputList;
+
+ int numElem = 0;
+ is.read((char*)(&numElem), sizeof(numElem));
+
+ for (int i = 0; i < numElem; i++) {
+ outputList.push_back(this->deserializeString(is));
+ }
+
+ return outputList;
+}
+
+void Serializer::serializeMatch(std::ostream& os,
+ const Attribute::Match& match) const
+{
+ os.write((char*)(&match), sizeof(match));
+ // LogInfo("SerializeMatch: " << match);
+ Assert(os.bad() == false && "Error Writing to file failure");
+}
+
+Attribute::Match Serializer::deserializeMatch(std::istream& is)
+{
+ Attribute::Match match(Attribute::Match::Error);
+ is.read((char*)(&match), sizeof(match));
+ // LogInfo("DESerializeMatch: " << match);
+ return match;
+}
+
+bool Serializer::serializeModifier(std::ostream& os,
+ const Attribute::Modifier& modifier) const
+{
+ os.write((char*)(&modifier), sizeof(modifier));
+ // LogInfo("SerializeModifier: " << modifier);
+ return 0;
+}
+
+Attribute::Modifier Serializer::deserializeModifier(std::istream& is)
+{
+ Attribute::Modifier modifier(Attribute::Modifier::Non);
+ is.read((char*)(&modifier), sizeof(modifier));
+ // LogInfo("DESerializeModifer: " << modifier);
+ return modifier;
+}
+
+//TODO zrobic z tego szablon - z list jezeli sie da
+void Serializer::serializeListTreeNode(std::ostream& os,
+ std::list<TreeNode*>& inputList)
+{
+ int dataLength = inputList.size();
+ os.write((char*)(&dataLength), sizeof(dataLength));
+
+ // LogInfo("SerializeListTreeNode SIZE: " <<dataLength);
+ FOREACH(it, inputList)
+ {
+ (*it)->serialize(os);
+ }
+
+ Assert(os.bad() == false && "Error Writing to file failure");
+}
+
+std::list<TreeNode* > Serializer::deserializeListTreeNode(std::istream&is,
+ TreeNode* parent)
+{
+ std::list<TreeNode* > outputList;
+
+ int numElem = 0;
+ is.read((char*)(&numElem), sizeof(numElem));
+
+ // LogInfo("DESerializeListTreeNode SIZE: " <<numElem);
+
+ TreeNode* node;
+
+ for (int i = 0; i < numElem; i++) {
+ node = new TreeNode(is, parent);
+ outputList.push_back(node);
+ }
+
+ return outputList;
+}
+
+void Serializer::serializeTypeAbstract(std::ostream& os,
+ const TreeNode::TypeID& typeId)
+{
+ os.write((char*)(&typeId), sizeof(typeId));
+ // LogInfo(" Serialize TypeAbstract: " << typeId);
+
+ Assert(os.bad() == false && "Error Writing to file failure");
+}
+
+TreeNode::TypeID Serializer::deserializeTypeAbstract(std::istream& is)
+{
+ TreeNode::TypeID typeId(TreeNode::Policy);
+ is.read((char*)(&typeId), sizeof(typeId));
+ // LogInfo(" DESerialize TypeAbstract: " << typeId);
+ return typeId;
+}
+
+void Serializer::serializeAbstractElement(std::ostream& os,
+ AbstractTreeElement* element)
+{
+ element->serialize(os);
+
+ // LogInfo("Serialize AbstractElem: " << element);
+ Assert(os.bad() == false && "Error Writing to file failure");
+}
+
+AbstractTreeElement* Serializer::deserializeAbstractElement(std::istream& is,
+ TreeNode::TypeID& typeId)
+{
+ NodeFactory* factory = NodeFactory::getInstance();
+
+ AbstractTreeElement* element;
+
+ element = factory->create(is, typeId);
+
+ //LogInfo("DESerialize AbstractElem: " << typeId);
+ return element;
+}
+
+void Serializer::serializeListSubjects(std::ostream& os,
+ std::list<const Subject*>& inputList)
+{
+ int dataLength = inputList.size();
+ os.write((char*)(&dataLength), sizeof(dataLength));
+
+ //LogInfo("Serialize list Subjects SIZE: " << dataLength);
+
+ FOREACH (it, inputList)
+ {
+ //serialize method doesn't change anything in object
+ const_cast<Subject* >((*it))->serialize(os);
+ }
+
+ Assert(os.bad() == false && "Error Writing to file failure");
+}
+
+std::list<const Subject*>* Serializer::deserializeListSubjects(std::istream& is)
+{
+ std::list<const Subject*>* outputList = new std::list<const Subject*>;
+
+ int numElem = 0;
+ is.read((char*)(&numElem), sizeof(numElem));
+
+ //LogInfo("DESerialize list Subjects SIZE: " <<numElem);
+ Subject* subject;
+
+ for (int i = 0; i < numElem; i++) {
+ subject = new Subject(is);
+ outputList->push_back(subject);
+ }
+
+ return outputList;
+}
+
+void Serializer::serializeCombineAlgorithm(std::ostream& os,
+ const Policy::CombineAlgorithm& combAlg)
+{
+ os.write((char*)(&combAlg), sizeof(combAlg));
+ //LogInfo("Serialize Combine Alg:" << combAlg);
+
+ Assert(os.bad() == false && "Error Writing to file failure");
+}
+
+Policy::CombineAlgorithm Serializer::deserializeCombineAlgorithm(
+ std::istream& is)
+{
+ Policy::CombineAlgorithm combAlg(Policy::DenyOverride);
+ is.read((char*)(&combAlg), sizeof(combAlg));
+ //LogInfo("DESerialize Combine Alg:" << combAlg);
+ return combAlg;
+}
+
+void Serializer::serializeCombineType(std::ostream& os,
+ const Condition::CombineType& combType)
+{
+ os.write((char*)(&combType), sizeof(combType));
+ //LogInfo("Serialize CombineType: " <<combType);
+
+ Assert(os.bad() == false && "Error Writing to file failure");
+}
+
+Condition::CombineType Serializer::deserializeCombineType(std::istream& is)
+{
+ Condition::CombineType combType(Condition::AND);
+ is.read((char*)(&combType), sizeof(combType));
+ //LogInfo("Deserialize CombineType: " <<combType);
+ return combType;
+}
+
+void Serializer::serializeListConditions(std::ostream& os,
+ std::list<Condition>& inputList)
+{
+ int dataLength = inputList.size();
+ os.write((char*)(&dataLength), sizeof(dataLength));
+
+ //LogInfo("Serialize List Conditions SIZE:" <<dataLength);
+ FOREACH (it, inputList)
+ {
+ it->serialize(os);
+ }
+
+ Assert(os.bad() == false && "Error Writing to file failure");
+}
+
+std::list<Condition> Serializer::deserializeListConditions(std::istream& is,
+ Condition* parent)
+{
+ std::list<Condition> outputList;
+
+ int numElem = 0;
+ is.read((char*)(&numElem), sizeof(numElem));
+
+ //LogInfo("DESerialize list Condition SIZE: " <<numElem);
+ Condition* cond;
+
+ for (int i = 0; i < numElem; i++) {
+ cond = new Condition(is, parent);
+ outputList.push_back(*cond);
+ delete cond;
+ }
+
+ return outputList;
+}
+
+void Serializer::serializeEffect(std::ostream& os,
+ Effect effect)
+{
+ os.write((char*)(&effect), sizeof(effect));
+ //LogInfo("Serialize Effect: " << effect);
+
+ Assert(os.bad() == false && "Error Writing to file failure");
+}
+
+Effect Serializer::deserializeEffect(std::istream& is)
+{
+ Effect effect(Deny);
+ is.read((char*)(&effect), sizeof(effect));
+ //LogInfo("DESerialize Effect: " << effect);
+ return effect;
+}
+
+void Serializer::serializeCondition(std::ostream& os,
+ Condition& cond)
+{
+ cond.serialize(os);
+
+ Assert(os.bad() == false && "Error Writing to file failure");
+}
+
+Condition& Serializer::deserializeCondition(std::istream& is)
+{
+ //[CR] maybe we should use Factory here
+ Condition * cond = new Condition(is);
+ return *cond;
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ *
+ *
+ * @file SettingsLogic.cpp
+ * @author Tomasz Swierczek (t.swierczek@samsung.com)
+ * @version 0.1
+ * @brief SettingsLogic implementation
+ */
+
+#include <dpl/ace/SettingsLogic.h>
+
+#include <dpl/log/log.h>
+#include <dpl/foreach.h>
+
+#include <dpl/ace/Preference.h>
+
+using namespace AceDB;
+
+Preference SettingsLogic::findGlobalUserSettings(
+ const std::string &resource,
+ WidgetHandle handler)
+{
+ Preference p = AceDAO::getWidgetDevCapSetting(resource, handler);
+ if (PreferenceTypes::PREFERENCE_DEFAULT == p) {
+ return AceDAO::getDevCapSetting(resource);
+ } else {
+ return p;
+ }
+}
+
+Preference SettingsLogic::findGlobalUserSettings(
+ const Request &request)
+{
+ Request::DeviceCapabilitySet devset = request.getDeviceCapabilitySet();
+ Assert(!devset.empty() && "No device cap set in request");
+ return findGlobalUserSettings(
+ *(devset.begin()),
+ request.getWidgetHandle());
+}
+
+Preference SettingsLogic::getDevCapSetting(const std::string &resource)
+{
+ return AceDAO::getDevCapSetting(resource);
+}
+
+void SettingsLogic::getDevCapSettings(PreferenceMap *globalSettingsMap)
+{
+ AceDAO::getDevCapSettings(globalSettingsMap); // NULL check inside
+}
+
+
+void SettingsLogic::setDevCapSetting(const std::string &resource,
+ Preference preference)
+{
+ if (resource.empty()) {
+ LogInfo("WARNING: setting resource settings for empty resource name");
+ }
+
+ AceDAO::addResource(resource);
+
+ if (preference == PreferenceTypes::PREFERENCE_DEFAULT) {
+ return;
+ }
+
+ Assert((PreferenceTypes::PREFERENCE_PERMIT == preference ||
+ PreferenceTypes::PREFERENCE_DENY == preference ||
+ PreferenceTypes::PREFERENCE_BLANKET_PROMPT == preference ||
+ PreferenceTypes::PREFERENCE_ONE_SHOT_PROMPT == preference ||
+ PreferenceTypes::PREFERENCE_SESSION_PROMPT == preference));
+
+ AceDAO::setDevCapSetting(resource,preference);
+}
+
+void SettingsLogic::setAllDevCapSettings(
+ const std::list < std::pair < const std::string*,
+ Preference > > &resourcesList)
+{
+ std::list < std::pair < const std::string*,
+ Preference > >::const_iterator iter;
+ for (iter = resourcesList.begin(); iter != resourcesList.end(); ++iter) {
+ SettingsLogic::setDevCapSetting(*(iter->first), iter->second);
+ }
+}
+
+void SettingsLogic::removeDevCapSetting(const std::string &resource)
+{
+ AceDAO::removeDevCapSetting(resource);
+}
+
+void SettingsLogic::updateDevCapSetting(const std::string &resource,
+ Preference p)
+{
+ if (PreferenceTypes::PREFERENCE_DEFAULT == p) {
+ SettingsLogic::removeDevCapSetting(resource);
+ } else {
+ SettingsLogic::setDevCapSetting(resource, p);
+ }
+}
+
+Preference SettingsLogic::getWidgetDevCapSetting(
+ const std::string &resource,
+ WidgetHandle handler)
+{
+ return AceDAO::getWidgetDevCapSetting(resource, handler);
+}
+
+void SettingsLogic::getWidgetDevCapSettings(PermissionList *outputList)
+{
+ AceDAO::getWidgetDevCapSettings(outputList); // NULL check inside
+}
+
+
+void SettingsLogic::setWidgetDevCapSetting(
+ const std::string &resource,
+ WidgetHandle handler,
+ Preference preference)
+{
+ if (resource.empty()) {
+ LogError("Empty resource");
+ return;
+ }
+
+ LogDebug("userSetting, resource: " << resource <<
+ " app_id: " << handler);
+
+ AceDAO::addResource(resource);
+ SettingsLogic::removeWidgetDevCapSetting(resource, handler);
+
+ if (PreferenceTypes::PREFERENCE_DEFAULT == preference) {
+ return;
+ }
+
+ Assert((PreferenceTypes::PREFERENCE_PERMIT == preference ||
+ PreferenceTypes::PREFERENCE_DENY == preference ||
+ PreferenceTypes::PREFERENCE_BLANKET_PROMPT == preference ||
+ PreferenceTypes::PREFERENCE_ONE_SHOT_PROMPT == preference ||
+ PreferenceTypes::PREFERENCE_SESSION_PROMPT == preference));
+
+ AceDAO::setWidgetDevCapSetting(resource, handler, preference);
+}
+
+
+void SettingsLogic::setWidgetDevCapSettings(const PermissionList &permissionsList)
+{
+ FOREACH(i, permissionsList) {
+ SettingsLogic::setWidgetDevCapSetting(i->devCap,
+ i->appId,
+ i->access);
+ }
+}
+
+
+void SettingsLogic::removeWidgetDevCapSetting(const std::string &resource,
+ WidgetHandle handler)
+{
+ AceDAO::removeWidgetDevCapSetting(resource, handler);
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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/log/log.h>
+#include <dpl/foreach.h>
+
+#include <dpl/ace/Subject.h>
+#include <dpl/ace/Serializer.h>
+#include <dpl/ace/NodeFactory.h>
+
+bool Subject::matchSubject(const AttributeSet *attrSet,
+ bool &isUndetermined) const
+{
+ bool result = true;
+ Attribute::MatchResult match = Attribute::MatchResult::MRUndetermined;
+
+ FOREACH(it, targetAttributes)
+ {
+ AttributeSet::const_iterator attr =
+ std::find_if(attrSet->begin(),
+ attrSet->end(),
+ AceDB::BaseAttribute::UnaryPredicate(&(*it)));
+ if (attr == attrSet->end()) {
+ LogError("Cannot find attribute value for " << *(it->getName()));
+ Assert(false &&
+ "Attribute for subject hasn't been found."
+ "It shoud not happen. This attribute should be undetermined,"
+ "not missing");
+ result = false; //According to BONDI 1.0 for signle subject all attributes must match
+ isUndetermined = true;
+ break;
+ }
+
+ match = it->matchAttributes(&(*(*attr)));
+
+ if (match == Attribute::MatchResult::MRUndetermined) {
+ result = false;
+ isUndetermined = true;
+ /// LogError("Subject doesn match and UNDETERMINED");
+ break; //According to BONDI 1.0 for signle subject all attributes must match
+ } else if (match == Attribute::MatchResult::MRFalse) {
+ result = false;
+ // LogError("Subject doesn match and DETERMINED");
+ break; //According to BONDI 1.0 for signle subject all attributes must match
+ }
+ }
+
+ return result;
+}
+
+const std::list<Attribute>& Subject::getTargetAttributes() const
+{
+ return targetAttributes;
+}
+
+Subject::Subject(std::istream& is)
+{
+ Serializer* serializer = Serializer::getInstance();
+
+ subjectId = serializer->deserializeString(is);
+ targetAttributes = serializer->deserializeListAttributes(is);
+}
+
+bool Subject::serialize (std::ostream& os)
+{
+ Serializer* serializer = Serializer::getInstance();
+
+ serializer->serializeString(os, subjectId);
+ serializer->serializeListAttributes(os, targetAttributes);
+
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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/ace/TreeNode.h>
+#include <dpl/assert.h>
+#include <dpl/ace/Serializer.h>
+#include <dpl/log/log.h>
+
+//Tree node destructor is a tricky part, only the original tree should remove the elements
+//release resources should be called when we want to destroy the whole tree
+TreeNode::~TreeNode()
+{
+}
+
+bool TreeNode::serialize(std::ostream& os)
+{
+ Serializer* serializer = Serializer::getInstance();
+
+ //does node have any child - anty Inf recursion
+ if (!children.empty()) {
+ serializer->serializeInt(os, 1);
+ serializer->serializeListTreeNode(os, children);
+ } else {
+ serializer->serializeInt(os, 0);
+ }
+
+ serializer->serializeTypeAbstract(os, typeID);
+ serializer->serializeAbstractElement(os, element);
+
+ //LOG << "TreeNode Serialized" << std::endl;
+ return 0;
+}
+
+TreeNode::TreeNode(std::istream& is,
+ TreeNode* parent)
+{
+ Serializer* serializer = Serializer::getInstance();
+
+ this->parent = parent;
+
+ //check if this node has any child
+ int hasChild = 0;
+ hasChild = serializer->deserializeInt(is);
+
+ if (hasChild) { //[CR] - 0 remove copying list ....
+ children = serializer->deserializeListTreeNode(is, this);
+ }
+
+ typeID = serializer->deserializeTypeAbstract(is);
+ element = serializer->deserializeAbstractElement(is, typeID);
+ //LOG << "TreeNode DESERIALIZED" << std::endl;
+}
+
+//TODO release resources is releaseTheSubtree and delete the element
+void TreeNode::releaseResources()
+{
+ Assert(this != 0);
+ delete element;
+ std::list<TreeNode*>::iterator it = this->children.begin();
+ while (it != children.end()) {
+ (*it)->releaseResources();
+ ++it;
+ }
+ delete this;
+}
+
+// KW void TreeNode::releaseTheSubtree(){
+// KW
+// KW std::list<TreeNode *>::iterator it = children.begin();
+// KW
+// KW for(; it != children.end();it++){
+// KW (*it)->releaseTheSubtree();
+// KW }
+// KW delete this;
+// KW }
+
+int TreeNode::level = 0;
+
+// KW void TreeNode::printSubtree(){
+// KW
+// KW TreeNode::level++;
+// KW
+// KW for(int i=0;i<level;i++)
+// KW {
+// KW std::cout<<" ";
+// KW }
+// KW std::cout<<"l"<<level<<": ";
+// KW std::cout<<this;
+// KW
+// KW ChildrenIterator it = this->children.begin();
+// KW
+// KW for(;it != children.end();++it){
+// KW (*it)->printSubtree();
+// KW }
+// KW
+// KW TreeNode::level--;
+// KW }
+
+std::ostream & operator<<(std::ostream & out,
+ const TreeNode * node)
+{
+ std::string tmp;
+
+ switch (node->getTypeID()) {
+ case TreeNode::Policy:
+ tmp = "Policy";
+ break;
+ case TreeNode::PolicySet:
+ tmp = "PolicySet";
+ break;
+ case TreeNode::Rule:
+ tmp = "Rule";
+ break;
+ default:
+ break;
+ }
+
+ out << "" << tmp << "-> children count: " << node->children.size() <<
+ ": " << std::endl;
+ AbstractTreeElement * el = node->getElement();
+ if (el != NULL) {
+ el->printData();
+ } else {
+ std::cout << "Empty element!" << std::endl;
+ }
+
+ return out;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <memory>
+#include <functional>
+#include <string.h>
+#include <stdarg.h>
+#include <dpl/log/log.h>
+
+#include <dpl/ace/parser.h>
+#include <string.h>
+
+namespace {
+
+class ParserWarningLogger
+{
+ public:
+ void operator()(const std::string& logMsg)
+ {
+ LogWarning(logMsg);
+ }
+};
+
+class ParserErrorLogger
+{
+ public:
+ void operator()(const std::string& logMsg)
+ {
+ LogError(logMsg);
+ }
+};
+
+template <class Logger>
+void xmlLogFunction(void* /*ctx*/, const char *msg, ...)
+{
+ const int BUFFER_SIZE = 1024;
+ char buffer[BUFFER_SIZE];
+ buffer[BUFFER_SIZE - 1] = '\0';
+ Logger l;
+
+ va_list va;
+ va_start(va, msg);
+ vsnprintf(buffer, BUFFER_SIZE - 1, msg, va);
+ va_end(va);
+
+ std::string logmsg(buffer);
+ l(logmsg);
+}
+
+}
+
+const char *Parser::TOKEN_PARAM = "param:";
+
+Parser::Parser() :
+ reader(NULL),
+ root(NULL),
+ currentRoot(NULL),
+ currentSubject(NULL),
+ currentCondition(NULL),
+ currentAttribute(NULL),
+ currentText(NULL),
+ processingSignature(false),
+ canonicalizeOnce(false)
+{
+ processingSignature = true;
+ canonicalizeOnce = true;
+}
+
+Parser::~Parser()
+{
+ /* parse function destroys reader */
+ // free(this->xmlFilename);
+}
+
+TreeNode* Parser::parse(const std::string& filename, const std::string& schema)
+{
+ if(root != NULL) {
+ root->releaseResources();
+ root = NULL;
+ }
+
+ LogDebug("Parser: opening file " << filename);
+
+ xmlDocPtr xmlDocument = xmlParseFile(filename.c_str());
+ if (!xmlDocument) {
+ LogError("Couldn't parse file " << filename);
+ return root;
+ }
+
+ std::unique_ptr <xmlDoc, std::function<void(xmlDoc*)> >
+ doc(xmlDocument, xmlFreeDoc);
+
+ xmlSchemaParserCtxtPtr xmlSchemaParserContext =
+ xmlSchemaNewParserCtxt(schema.c_str());
+
+ if (!xmlSchemaParserContext) {
+ LogError("Couldn't load xml schema: " << schema);
+ return root;
+ }
+
+ std::unique_ptr <
+ xmlSchemaParserCtxt,
+ std::function<void(xmlSchemaParserCtxt*)> >
+ schemaContext(
+ xmlSchemaParserContext,
+ xmlSchemaFreeParserCtxt);
+
+ LogDebug("Setting callbacks");
+
+ xmlSchemaSetParserErrors(
+ schemaContext.get(),
+ static_cast<xmlValidityErrorFunc>
+ (&xmlLogFunction<ParserErrorLogger>),
+ static_cast<xmlValidityWarningFunc>
+ (&xmlLogFunction<ParserWarningLogger>),
+ NULL);
+
+ xmlSchemaPtr xmlSchema = xmlSchemaParse(schemaContext.get());
+
+ if (!xmlSchema) {
+ LogError("Couldn't parse xml schema: " << xmlSchema);
+ return root;
+ }
+
+ xmlSchemaValidCtxtPtr xmlValidContext = xmlSchemaNewValidCtxt(xmlSchema);
+
+ if (!xmlValidContext) {
+ LogError("Couldn't create validation context!");
+ return root;
+ }
+
+ std::unique_ptr <
+ xmlSchemaValidCtxt,
+ std::function<void(xmlSchemaValidCtxt*)> >
+ schemaValidContext(
+ xmlValidContext,
+ xmlSchemaFreeValidCtxt);
+
+ xmlSchemaSetValidErrors(
+ schemaValidContext.get(),
+ static_cast<xmlValidityErrorFunc>
+ (&xmlLogFunction<ParserErrorLogger>),
+ static_cast<xmlValidityWarningFunc>
+ (&xmlLogFunction<ParserWarningLogger>),
+ NULL);
+
+ xmlSchemaSetValidOptions(
+ schemaValidContext.get(),
+ XML_SCHEMA_VAL_VC_I_CREATE);
+
+ bool result =
+ (xmlSchemaValidateDoc(
+ schemaValidContext.get(),
+ xmlDocument) == 0 ? true : false);
+
+ if (!result) {
+ LogError("Couldn't validate policy file: " << filename <<
+ " against xml schema: " << schema);
+
+ return root;
+ }
+
+ LogInfo("Policy file: " << filename << " validated!");
+
+ xmlTextReaderPtr xmlReader = xmlReaderWalker(xmlDocument);
+
+ //[CR] consider using ASSERT/DASSERT
+ if (NULL == xmlReader) {
+ LogError("Error, xml reader cannot be created. Probably xml file is missing (opening file " << filename << ")");
+ return root;
+ }
+
+ std::unique_ptr <xmlTextReader, std::function<void(xmlTextReader*)> >
+ reader(xmlReader, xmlFreeTextReader);
+
+ int ret;
+ ret = xmlTextReaderRead(reader.get());
+ while (ret == 1) {
+ std::unique_ptr<xmlChar, std::function<void(xmlChar*)> >
+ name(xmlTextReaderName(reader.get()), xmlFree);
+
+ if (!strcmp("policy-set", (const char *)name.get())) {
+ processingSignature = false;
+ } else if (!strcmp("SignedInfo",
+ (const char *)name.get()) && canonicalizeOnce) {
+ #if 0 //TODO I think we don't need canonicalization in ACE only in PM,
+ //we have to verify it tough
+ extractNodeToFile(reader, "output.xml");
+ //TODO we should be able to handle more than one canonicalization algorithm
+ canonicalize("output.xml", "canon.xml", Canonicalization::C14N);
+ canonicalizeOnce = false;
+ #endif
+ }
+ //Do not process signature of xml file
+ if(!processingSignature) {
+ processNode(reader.get());
+ }
+ ret = xmlTextReaderRead(reader.get());
+ }
+
+ if (ret != 0) {
+ LogError("Error while parsing XML file");
+ if (root) {
+ root->releaseResources();
+ root = NULL;
+ }
+ }
+
+ return root;
+}
+
+void Parser::processNode(xmlTextReaderPtr reader)
+{
+ //TODO this is interesting, xmlTextReaderNodeType returns int but I am pretty sure
+ //those integers coresponds to xmlReaderTypes
+ xmlReaderTypes type =
+ static_cast<xmlReaderTypes>(xmlTextReaderNodeType(reader));
+
+ switch (type) {
+ //Start element
+ case XML_READER_TYPE_ELEMENT:
+ startNodeHandler(reader);
+ break;
+ //End element
+ case XML_READER_TYPE_END_ELEMENT:
+ endNodeHandler(reader);
+ break;
+ //Text element
+ case XML_READER_TYPE_TEXT:
+ textNodeHandler(reader);
+ break;
+ default:
+ //Do not handle other xml tags
+ break;
+ }
+}
+
+void Parser::startNodeHandler(xmlTextReaderPtr reader)
+{
+ xmlChar *name = xmlTextReaderName(reader);
+
+ switch (*name) {
+ case 'p': //policy and policy-set
+ if (*(name + 6) == 0) {
+ handlePolicy(reader, TreeNode::Policy);
+ } else {
+ handlePolicy(reader, TreeNode::PolicySet);
+ }
+ break;
+ case 'r': //rule and resource-match
+ if (*(name + 1) == 'u') {
+ handleRule(reader);
+ } else if (*(name + 9) == 'm') {
+ handleMatch(reader, Attribute::Type::Resource);
+ } else {
+ handleAttr(reader);
+ }
+ break;
+ case 's': //subject and subject-match
+ if (*(name + 7) == 0) {
+ handleSubject();
+ } else if (*(name + 8) == 'm') { //subject match
+ handleSubjectMatch(reader);
+ } else { //subject attr
+ handleAttr(reader);
+ }
+ break;
+ case 'c': //condition
+ handleCondition(reader);
+ break;
+ case 'e': //environment-match
+ if (*(name + 12) == 'm') {
+ handleMatch(reader, Attribute::Type::Environment);
+ } else { //env-attr
+ handleAttr(reader);
+ }
+ break;
+ }
+ xmlFree(name);
+}
+
+void Parser::endNodeHandler(xmlTextReaderPtr reader)
+{
+ xmlChar *name = xmlTextReaderName(reader);
+
+ switch (*name) {
+ case 'p': //policy and policy-set
+ //Restore old root
+ currentRoot = currentRoot->getParent();
+ break;
+ case 'r': //Rule and resource match
+ if (*(name + 1) == 'u') { //Rule
+ currentRoot = currentRoot->getParent();
+ } else { //Resource-match
+ consumeCurrentText(); //consume text if any available
+ consumeCurrentAttribute(); //consume attribute
+ }
+ break;
+ case 's': //subject and subject-match
+ if (*(name + 7) == 0) { //handle subject
+ consumeCurrentSubject();
+ } else if (*(name + 8) == 'm') { //handle subject match
+ consumeCurrentText();
+ consumeSubjectMatch();
+ }
+ //Subject-match end doesn't require handling
+ break;
+ case 'c': //condition
+ consumeCurrentCondition();
+ break;
+ case 'e': //environment-match
+ consumeCurrentText(); //consume text if any available
+ consumeCurrentAttribute(); //consume attribute
+ break;
+ }
+ xmlFree(name);
+}
+
+void Parser::textNodeHandler(xmlTextReaderPtr reader)
+{
+ delete currentText;
+ xmlChar * text = xmlTextReaderValue(reader);
+ Assert(text != NULL && "Parser couldn't parse PCDATA");
+
+ currentText = new std::string(reinterpret_cast<const char * >(text));
+ trim(currentText);
+ xmlFree(text);
+}
+
+void Parser::handlePolicy(xmlTextReaderPtr reader,
+ TreeNode::TypeID type)
+{
+ Policy::CombineAlgorithm algorithm;
+
+ //Get first attribute
+ xmlChar * combAlg = xmlTextReaderGetAttribute(reader, BAD_CAST("combine"));
+
+ Assert(combAlg != NULL && "Parser error while getting attributes");
+ algorithm = convertToCombineAlgorithm(combAlg);
+
+ //Create TreeNode element
+ Policy * policy = NULL;
+ if (type == TreeNode::Policy) {
+ policy = new Policy();
+ } else {
+ policy = new PolicySet();
+ }
+ policy->setCombineAlgorithm(algorithm);
+ TreeNode * node = new TreeNode(currentRoot, type, policy);
+ //Add new tree node to current's root children set
+ if (currentRoot != NULL) {
+ currentRoot->addChild(node);
+ }
+
+ //Switch the current root to the new node
+ if (!xmlTextReaderIsEmptyElement(reader)) {
+ //Current root switching is necessary only if tag is not empty
+ currentRoot = node;
+ }
+ if (root == NULL) {
+ root = currentRoot;
+ }
+
+ if (NULL == currentRoot) {
+ node->releaseResources();
+ }
+
+ xmlFree(combAlg);
+}
+
+void Parser::handleRule(xmlTextReaderPtr reader)
+{
+ Effect effect = Inapplicable;
+
+ //[CR] create macros for attribute names
+ xmlChar * eff = xmlTextReaderGetAttribute(reader, BAD_CAST("effect")); //get the rule attribute
+
+ Assert(eff != NULL && "Parser error while getting attributes");
+ effect = convertToEffect(eff);
+
+ Rule * rule = NULL;
+ rule = new Rule();
+ rule->setEffect(effect);
+
+ TreeNode * node = new TreeNode(currentRoot, TreeNode::Rule, rule);
+ //Add new tree node to current's root children set
+ if (currentRoot != NULL) { //
+ currentRoot->addChild(node);
+ }
+
+ if (!xmlTextReaderIsEmptyElement(reader)) {
+ currentRoot = node;
+ }
+
+ if (NULL == currentRoot) {
+ node->releaseResources();
+ }
+
+ xmlFree(eff);
+}
+
+void Parser::handleSubject()
+{
+ currentSubject = new Subject();
+ //TODO what about empty subject tag
+}
+
+void Parser::handleCondition(xmlTextReaderPtr reader)
+{
+ Condition::CombineType combineType = Condition::AND;
+
+ xmlChar * combine = xmlTextReaderGetAttribute(reader, BAD_CAST("combine")); //get the rule attribute
+
+ Assert(combine != NULL && "Parser error while getting attributes");
+
+ combineType = *combine == 'a' ? Condition::AND : Condition::OR;
+
+ Condition * condition = new Condition();
+ condition->setCombineType(combineType);
+ condition->setParent(currentCondition);
+
+ currentCondition = condition;
+ //TODO what about empty condition tag?
+}
+
+//Subject match is handled differently than resource or environment match
+//Because it cannot have any children tags and can only include PCDATA
+void Parser::handleSubjectMatch(xmlTextReaderPtr reader)
+{
+ //processing Subject
+ int attributes = xmlTextReaderAttributeCount(reader);
+
+ xmlChar * func = NULL;
+ xmlChar * value = NULL;
+ xmlChar * attrName = xmlTextReaderGetAttribute(reader, BAD_CAST("attr")); //get the first attribute
+
+ if (attributes == 2) {
+ //match attribute ommited, text value will be used
+ func = xmlTextReaderGetAttribute(reader, BAD_CAST("func"));
+ } else if (attributes == 3) {
+ value = xmlTextReaderGetAttribute(reader, BAD_CAST("match"));
+ func = xmlTextReaderGetAttribute(reader, BAD_CAST("func"));
+ } else {
+ Assert(false && "Wrong XML file format");
+ }
+
+ // creating temporiary object is not good idea
+ // but we have no choice untill Attribute have constructor taking std::string*
+ std::string temp(reinterpret_cast<const char *>(attrName));
+ Attribute * attr = new Attribute(&temp, convertToMatchFunction(
+ func), Attribute::Type::Subject);
+ if (value != NULL) { //add value of the attribute if possible
+ //[CR] consider create Attribute::addValue(char *) function
+ std::string temp(reinterpret_cast<const char *>(value));
+ attr->addValue(&temp);
+ }
+ currentAttribute = attr;
+
+ if (xmlTextReaderIsEmptyElement(reader)) {
+ Assert(value != NULL && "XML file format is wrong");
+ //Attribute value is required to obtain the match value easier
+ consumeSubjectMatch(value);
+ }
+
+ if (attributes == 2 || attributes == 3) {
+ xmlFree(func);
+ }
+ xmlFree(value);
+ xmlFree(attrName);
+}
+
+void Parser::handleMatch(xmlTextReaderPtr reader,
+ Attribute::Type type)
+{
+ int attributes = xmlTextReaderAttributeCount(reader);
+
+ xmlChar * func = NULL;
+ xmlChar * value = NULL;
+ xmlChar * attrName = xmlTextReaderGetAttribute(reader, BAD_CAST("attr")); //get the first attribute
+
+ if (attributes == 2) {
+ //match attribute ommited, text value will be used
+ func = xmlTextReaderGetAttribute(reader, BAD_CAST("func"));
+ //the content may be resource-attr or PCDATA
+ } else if (attributes == 3) {
+ value = xmlTextReaderGetAttribute(reader, BAD_CAST("match"));
+ func = xmlTextReaderGetAttribute(reader, BAD_CAST("func"));
+ } else {
+ Assert(false && "Wrong XML file format");
+ }
+
+ // FunctionParam type is sybtype of Resource.
+ // FunctionParam is used to storage attriburess of call functions.
+ if (0 ==
+ xmlStrncmp(attrName, BAD_CAST(TOKEN_PARAM),
+ xmlStrlen(BAD_CAST(TOKEN_PARAM))) && type ==
+ Attribute::Type::Resource) {
+ type = Attribute::Type::FunctionParam;
+ }
+
+ std::string temp(reinterpret_cast<const char*>(attrName));
+ Attribute * attr = new Attribute(&temp, convertToMatchFunction(func), type);
+ currentAttribute = attr;
+
+ if (xmlTextReaderIsEmptyElement(reader)) {
+ Assert(value != NULL && "XML is currupted");
+ std::string tempVal(reinterpret_cast<const char*>(value));
+ currentAttribute->addValue(&tempVal);
+ consumeCurrentAttribute();
+ }
+
+ if (attributes == 2 || attributes == 3) {
+ xmlFree(func);
+ }
+ xmlFree(value);
+ xmlFree(attrName);
+}
+
+Policy::CombineAlgorithm Parser::convertToCombineAlgorithm(xmlChar* algorithm)
+{
+ switch (*algorithm) {
+ case 'f':
+ if (*(algorithm + 6) == 'a') { //first applicable
+ return Policy::FirstApplicable;
+ }
+ return Policy::FirstTargetMatching;
+ case 'd':
+ return Policy::DenyOverride;
+ case 'p':
+ return Policy::PermitOverride;
+ default:
+ Assert(false && "Wrong combine algorithm name");
+ return Policy::DenyOverride;
+ }
+}
+
+Effect Parser::convertToEffect(xmlChar *effect)
+{
+ switch (*effect) {
+ case 'd': //deny
+ return Deny;
+ break;
+ case 'p':
+ //permit, prompt-blanket, prompt-session, prompt-oneshot
+ if (*(effect + 1) == 'e') {
+ return Permit;
+ }
+ switch (*(effect + 7)) {
+ case 'b':
+ return PromptBlanket;
+ case 's':
+ return PromptSession;
+ case 'o':
+ return PromptOneShot;
+ default:
+ Assert(false && "Effect is Error");
+ return Error;
+ }
+ break;
+ default:
+ Assert(false && "Effect is Error");
+ return Error;
+ }
+ return Inapplicable;
+}
+
+Attribute::Match Parser::convertToMatchFunction(xmlChar * func)
+{
+ if (func == NULL) {
+ LogError("[ERROR] match function value is NULL");
+ return Attribute::Match::Error;
+ }
+
+ if (*func == 'g') {
+ return Attribute::Match::Glob;
+ } else if (*func == 'e') {
+ return Attribute::Match::Equal;
+ } else if (*func == 'r') {
+ return Attribute::Match::Regexp;
+ } else {
+ LogError("[ERROR] match function value is NULL");
+ return Attribute::Match::Error;
+ }
+ Assert(false);
+}
+
+void Parser::handleAttr(xmlTextReaderPtr reader)
+{
+ xmlChar * attrValue = xmlTextReaderGetAttribute(reader, BAD_CAST("attr")); //get the first attribute
+ Assert(attrValue != NULL && "Error while obtaining attribute");
+
+ std::string temp(reinterpret_cast<const char*>(attrValue));
+ currentAttribute->addValue(&temp);
+
+ xmlFree(attrValue);
+}
+
+void Parser::consumeCurrentText()
+{
+ Assert(currentText != NULL);
+ currentAttribute->addValue(currentText);
+ delete currentText;
+
+ currentText = NULL;
+}
+
+void Parser::consumeCurrentAttribute()
+{
+ Assert(currentAttribute != NULL);
+
+ currentCondition->addAttribute(*currentAttribute);
+ delete currentAttribute;
+
+ currentAttribute = NULL;
+}
+
+void Parser::consumeCurrentSubject()
+{
+ Policy * policy = dynamic_cast<Policy *>(currentRoot->getElement());
+ Assert(policy != NULL);
+ policy->addSubject(currentSubject);
+ //TODO maybe keep subjects not subject pointers in Policies and consume subjects here
+ currentSubject = NULL;
+}
+
+void Parser::consumeCurrentCondition()
+{
+ Condition * temp = NULL;
+ if (currentCondition != NULL) {
+ if (currentCondition->getParent() != NULL) { //Condition is a child of another condition
+ currentCondition->getParent()->addCondition(*currentCondition);
+ } else { //Condition parent is a Rule
+ Rule * rule = dynamic_cast<Rule *>(currentRoot->getElement());
+ Assert(rule != NULL);
+ rule->setCondition(*currentCondition);
+ }
+ temp = currentCondition->getParent();
+ delete currentCondition;
+ }
+ currentCondition = temp; //switch current condition ( it may be switched to NULL if condition's parent was rule
+}
+
+void Parser::consumeSubjectMatch(xmlChar * value)
+{
+ Assert(
+ currentAttribute != NULL &&
+ "consuming subject match without attribute set");
+
+ if (currentSubject != NULL) {
+ currentSubject->addNewAttribute(*currentAttribute);
+ //[CR] matching/modyfing functions transform uri.host to uri ( etc. ) so strncmp is not needed, string equality will do
+ if (!strncmp(currentAttribute->getName()->c_str(), "uri",
+ 3) ||
+ !strncmp(currentAttribute->getName()->c_str(), "id", 2)) {
+ if (value != NULL) {
+ currentSubject->setSubjectId(reinterpret_cast<const char *>(
+ value));
+ } else if (currentAttribute->getValue()->size()) {
+ currentSubject->setSubjectId(
+ currentAttribute->getValue()->front());
+ } else {
+ Assert(false);
+ }
+ }
+ } else if (currentCondition != NULL) {
+ currentCondition->addAttribute(*currentAttribute);
+ }
+
+ delete currentAttribute;
+ currentAttribute = NULL;
+}
+
+void Parser::trim(std::string * str)
+{
+ std::string::size_type pos = str->find_last_not_of(whitespaces);
+ if (pos != std::string::npos) {
+ str->erase(pos + 1);
+ pos = str->find_first_not_of(whitespaces);
+ if (pos != std::string::npos) {
+ str->erase(0, pos);
+ }
+ } else {
+ str->erase(str->begin(), str->end());
+ LogInfo("Warning, empty string as attribute value");
+ }
+}
+
+// KW void Parser::canonicalize(const char * input, const char * output, CanonicalizationAlgorithm canonicalizationAlgorithm){
+// KW
+// KW xmlDocPtr doc = xmlParseFile(input);
+// KW //xmlDocDump(stdout, doc);
+// KW
+// KW if(doc == NULL)
+// KW {
+// KW LogError("Canonicalization error, cannot parser xml file");
+// KW }
+// KW
+// KW
+// KW int mode = -1;
+// KW if(canonicalizationAlgorithm == C14N)
+// KW {
+// KW mode = 0;
+// KW }
+// KW else if(canonicalizationAlgorithm == C14NEXCLUSIVE)
+// KW {
+// KW mode = 1;
+// KW }
+// KW
+// KW
+// KW xmlC14NDocSave(doc, NULL, mode, NULL, 0, output, 0);
+// KW
+// KW xmlFreeDoc(doc);
+// KW
+// KW }
+
+// KW int Parser::extractNodeToFile(xmlTextReaderPtr reader, const char * filename){
+// KW
+// KW xmlNodePtr node = xmlTextReaderExpand(reader);
+// KW xmlBufferPtr buff = xmlBufferCreate();
+// KW xmlNodeDump(buff, node->doc, node, 0, 0);
+// KW FILE * file = fopen(filename, "w");
+// KW if(file == NULL){
+// KW LogError("Error while trying to open file "<<filename);
+// KW return -1;
+// KW }
+// KW int ret = xmlBufferDump(file, buff);
+// KW fclose(file);
+// KW xmlBufferFree(buff);
+// KW return ret;
+// KW
+// KW }
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ *
+ *
+ * @file AceDAOConversions.h
+ * @author Grzegorz Krawczyk (g.krawczyk@samsung.com)
+ * @version 0.1
+ * @brief
+ */
+
+#ifndef WRT_ACE_DAO_CONVERSIONS_H_
+#define WRT_ACE_DAO_CONVERSIONS_H_
+
+#include <dpl/string.h>
+#include <dpl/ace-dao-ro/BaseAttribute.h>
+
+namespace AceDB {
+namespace AceDaoConversions {
+
+DPL::String convertToHash(const BaseAttributeSet &attributes);
+
+}
+}
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ *
+ *
+ * @file AceDAOReadOnly.h
+ * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @author Grzegorz Krawczyk (g.krawczyk@samsung.com)
+ * @version 0.1
+ * @brief
+ */
+
+#ifndef ACE_DAO_READ_ONLY_H_
+#define ACE_DAO_READ_ONLY_H_
+
+#include <openssl/md5.h>
+#include <dpl/string.h>
+#include <dpl/exception.h>
+#include <dpl/ace-dao-ro/PreferenceTypes.h>
+#include <dpl/ace-dao-ro/BaseAttribute.h>
+#include <dpl/ace-dao-ro/BasePermission.h>
+#include <dpl/ace-dao-ro/IRequest.h>
+#include <dpl/ace/PolicyEffect.h>
+#include <dpl/ace/PolicyResult.h>
+#include <dpl/ace/PromptDecision.h>
+#include <dpl/ace-dao-ro/wrt_db_types.h>
+
+namespace AceDB {
+
+class AceDAOReadOnly
+{
+ public:
+ class Exception
+ {
+ public:
+ DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+ DECLARE_EXCEPTION_TYPE(Base, DatabaseError)
+ };
+
+ AceDAOReadOnly() {}
+
+ static void attachToThread();
+ static void detachFromThread();
+
+ // policy effect/decision
+ static OptionalPolicyResult getPolicyResult(
+ const BaseAttributeSet &attributes);
+
+ static OptionalPolicyResult getPolicyResult(
+ const DPL::String &attrHash);
+
+ // prompt decision
+ static OptionalCachedPromptDecision getPromptDecision(
+ const DPL::String &hash,
+ const std::string &userParam);
+ static OptionalCachedPromptDecision getPromptDecision(
+ const BaseAttributeSet &attribites,
+ const std::string &userParam);
+
+ // resource settings
+ static PreferenceTypes getDevCapSetting(const std::string &resource);
+ static void getDevCapSettings(PreferenceTypesMap *preferences);
+
+ // user settings
+ static void getWidgetDevCapSettings(BasePermissionList *permissions);
+ static PreferenceTypes getWidgetDevCapSetting(
+ const std::string &resource,
+ WidgetHandle handler);
+
+ static void getAttributes(BaseAttributeSet *attributes);
+
+ // static dev cap permissions
+ //
+ // (For a given widget handle, a set of device caps is
+ // granted "statically", i.e. it is determined at installation
+ // time that the widget will always get (at launch) the SMACK
+ // permissions needed to use those device caps).
+ //
+ // 'permissions' is an output parameter - it must point to
+ // an existing set and the function will clear it and fill
+ // with the device cap names as described.
+ static void getStaticDevCapPermissions(
+ int widgetHandle,
+ std::set<DPL::String> *permissions);
+
+ protected:
+ static int promptDecisionToInt(PromptDecision decision);
+ static PromptDecision intToPromptDecision(int decision);
+};
+
+}
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ *
+ *
+ * @file AceDAOUtil.h
+ * @author Grzegorz Krawczyk (g.krawczyk@samsung.com)
+ * @version 0.1
+ * @brief
+ */
+
+#ifndef WRT_ACE_DAO_UTILITIES_H_
+#define WRT_ACE_DAO_UTILITIES_H_
+
+#include <dpl/db/thread_database_support.h>
+#include <dpl/ace-dao-ro/BaseAttribute.h>
+#include <dpl/ace-dao-ro/PreferenceTypes.h>
+#include <dpl/ace-dao-ro/VerdictTypes.h>
+#include <orm_generator_ace.h>
+
+namespace AceDB {
+
+namespace AceDaoUtilities {
+
+BaseAttribute::Type intToAttributeType(int val);
+int attributeTypeToInt(BaseAttribute::Type type);
+int preferenceToInt(PreferenceTypes p);
+PreferenceTypes intToPreference(int p);
+VerdictTypes intToVerdict(int v);
+int verdictToInt(VerdictTypes v);
+bool getSubjectByUri(const std::string &uri,
+ DPL::DB::ORM::ace::AceSubject::Row &row);
+bool getResourceByUri(const std::string &uri,
+ DPL::DB::ORM::ace::AceDevCap::Row &row);
+
+extern DPL::DB::ThreadDatabaseSupport m_databaseInterface;
+
+}
+
+}
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file AceDatabase.h
+ * @author Lukasz Marek (l.marek@samsung.com)
+ * @version 1.0
+ * @brief This file contains the declaration of ace database
+ */
+
+#ifndef WRT_ENGINE_SRC_ACCESS_CONTROL_ACE_DATABASE_H
+#define WRT_ENGINE_SRC_ACCESS_CONTROL_ACE_DATABASE_H
+
+#include <dpl/thread.h>
+#include <dpl/mutex.h>
+
+extern DPL::Mutex g_aceDbQueriesMutex;
+
+#define ACE_DB_INTERNAL(tlsCommand, InternalType, interface) \
+ static DPL::ThreadLocalVariable<InternalType> *tlsCommand ## Ptr = NULL; \
+ { \
+ DPL::Mutex::ScopedLock lock(&g_aceDbQueriesMutex); \
+ if (!tlsCommand ## Ptr) { \
+ static DPL::ThreadLocalVariable<InternalType> tmp; \
+ tlsCommand ## Ptr = &tmp; \
+ } \
+ } \
+ DPL::ThreadLocalVariable<InternalType> &tlsCommand = *tlsCommand ## Ptr; \
+ if (tlsCommand.IsNull()) { tlsCommand = InternalType(interface); }
+
+#define ACE_DB_SELECT(name, type, interface) \
+ ACE_DB_INTERNAL(name, type::Select, interface)
+
+#define ACE_DB_INSERT(name, type, interface) \
+ ACE_DB_INTERNAL(name, type::Insert, interface)
+
+#define ACE_DB_UPDATE(name, type, interface) \
+ ACE_DB_INTERNAL(name, type::Update, interface)
+
+#define ACE_DB_DELETE(name, type, interface) \
+ ACE_DB_INTERNAL(name, type::Delete, interface)
+
+
+#endif // WRT_ENGINE_SRC_ACCESS_CONTROL_ACE_DATABASE_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ *
+ *
+ * @file IAttribute.h
+ * @author Grzegorz Krawczyk (g.krawczyk@samsung.com)
+ * @version 0.1
+ * @brief
+ */
+
+#ifndef ACCESS_CONTROL_DAO_BASEATTRIBUTE_H_
+#define ACCESS_CONTROL_DAO_BASEATTRIBUTE_H_
+
+#include <list>
+#include <set>
+#include <string>
+#include <dpl/shared_ptr.h>
+#include <dpl/assert.h>
+
+namespace AceDB {
+
+class BaseAttribute;
+typedef DPL::SharedPtr<BaseAttribute> BaseAttributePtr;
+
+class BaseAttribute
+{
+
+ public:
+ /**
+ * Types of attributes
+ */
+ enum class Type { Subject, Environment, Resource, FunctionParam, Undefined };
+
+ struct UnaryPredicate
+ {
+ public:
+ UnaryPredicate(const AceDB::BaseAttribute *comp = NULL) :
+ m_priv(comp)
+ {
+ }
+
+ bool operator()(const AceDB::BaseAttributePtr &comp)
+ {
+ Assert(m_priv != NULL);
+ if (m_priv->getName()->compare(*comp->getName()) != 0) {
+ return false;
+ }
+ return m_priv->getType() == comp->getType();
+ }
+
+ bool operator()(const AceDB::BaseAttributePtr &comp1,
+ const AceDB::BaseAttributePtr &comp2)
+ {
+ if (comp1->getType() != comp2->getType()) {
+ return comp1->getType() < comp2->getType();
+ }
+ return comp1->getName()->compare(*comp2->getName()) < 0;
+ }
+
+ private:
+ const AceDB::BaseAttribute *m_priv;
+ };
+
+ public:
+ BaseAttribute() :
+ m_typeId(Type::Undefined),
+ m_undetermindState(false)
+ {}
+
+ virtual void setName(const std::string& name)
+ {
+ m_name = name;
+ }
+ virtual void setName(const std::string* name)
+ {
+ m_name = *name;
+ }
+
+ virtual void setType(const Type& type)
+ {
+ m_typeId = type;
+ }
+ virtual Type getType() const
+ {
+ return m_typeId;
+ }
+
+ virtual const std::string* getName() const
+ {
+ return &m_name;
+ }
+
+ //TODO think
+ virtual void setUndetermind(bool tmp)
+ {
+ m_undetermindState = tmp;
+ }
+ virtual bool isUndetermind() const
+ {
+ return m_undetermindState;
+ }
+ virtual std::list<std::string> * getValue() const
+ {
+ return const_cast<std::list<std::string>* >(&value);
+ }
+ virtual bool isValueEmpty() const
+ {
+ return value.empty();
+ }
+
+ virtual void setValue(const std::list<std::string>& arg)
+ {
+ value = arg;
+ }
+
+ virtual ~BaseAttribute()
+ {
+ }
+
+ static const char * typeToString(Type type);
+
+ virtual std::string toString() const;
+
+ protected:
+ std::string m_name;
+ Type m_typeId;
+ bool m_undetermindState;
+ std::list<std::string> value; //string bag list
+};
+
+typedef std::set<BaseAttributePtr, BaseAttribute::UnaryPredicate> BaseAttributeSet;
+
+}
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ *
+ *
+ * @file IPermission.h
+ * @author Grzegorz Krawczyk (g.krawczyk@samsung.com)
+ * @version 0.1
+ * @brief
+ */
+
+#ifndef ACCESS_CONTROL_DAO_BASEPERMISSION_H_
+#define ACCESS_CONTROL_DAO_BASEPERMISSION_H_
+
+#include <dpl/ace-dao-ro/PreferenceTypes.h>
+#include <dpl/ace-dao-ro/wrt_db_types.h>
+
+namespace AceDB{
+
+struct BasePermission
+{
+ BasePermission(WidgetHandle handler,
+ const std::string& devCap,
+ PreferenceTypes accessAllowed) :
+ appId(handler),
+ devCap(devCap),
+ access(accessAllowed)
+ {
+ }
+
+ WidgetHandle appId;
+ std::string devCap;
+ PreferenceTypes access;
+};
+
+typedef std::list<BasePermission> BasePermissionList;
+
+}
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ *
+ *
+ * @file IRequest.h
+ * @author Grzegorz Krawczyk (g.krawczyk@samsung.com)
+ * @version 0.1
+ * @brief
+ */
+
+#ifndef ACCESS_CONTROL_DAO_IREQUEST_H_
+#define ACCESS_CONTROL_DAO_IREQUEST_H_
+
+namespace AceDB{
+
+class IRequest
+{
+public:
+ virtual ~IRequest(){}
+};
+
+}
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ *
+ *
+ * @file PreferenceTypes.h
+ * @author Grzegorz Krawczyk (g.krawczyk@samsung.com)
+ * @version 0.1
+ * @brief
+ */
+
+#ifndef ACCESS_CONTROL_DAO_PREFERENCETYPES_H_
+#define ACCESS_CONTROL_DAO_PREFERENCETYPES_H_
+
+#include <map>
+#include <string>
+
+namespace AceDB{
+
+enum class PreferenceTypes
+{
+ PREFERENCE_PERMIT,
+ PREFERENCE_DENY,
+ PREFERENCE_DEFAULT,
+ PREFERENCE_BLANKET_PROMPT,
+ PREFERENCE_SESSION_PROMPT,
+ PREFERENCE_ONE_SHOT_PROMPT
+};
+
+
+typedef std::map<std::string, PreferenceTypes> PreferenceTypesMap;
+
+}
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/* @file PromptModel.h
+ * @author Justyna Mejzner (j.kwiatkowsk@samsung.com)
+ * @author Jaroslaw Osmanski (j.osmanski@samsung.com)
+ * @version 1.0
+ *
+ */
+
+#ifndef WRT_SRC_ACCESSCONTROL_ENGINE_PROMPT_MODEL_H_
+#define WRT_SRC_ACCESSCONTROL_ENGINE_PROMPT_MODEL_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <dpl/optional_typedefs.h>
+#include <dpl/singleton.h>
+
+namespace Prompt {
+typedef std::vector<std::string> ButtonLabels;
+
+class PromptLabels
+{
+public:
+ PromptLabels(int promptType,
+ const Prompt::ButtonLabels& questionLabel,
+ const std::string& mainLabel);
+ DPL::OptionalString getCheckLabel() const;
+ bool isAllowed(const size_t buttonNumber) const;
+ int getPromptType() const;
+ const ButtonLabels& getButtonLabels() const;
+ const std::string& getMainLabel() const;
+
+private:
+ int m_promptType;
+ ButtonLabels m_buttonLabels;
+ std::string m_mainLabel;
+};
+
+typedef std::unique_ptr<PromptLabels> PromptLabelsPtr;
+
+enum Validity
+{
+ ONCE,
+ SESSION,
+ ALWAYS
+};
+
+class PromptAnswer
+{
+public:
+ PromptAnswer(bool isAccessAllowed, Validity validity);
+ PromptAnswer(int aPromptType, unsigned int buttonAns, bool checkAns);
+ bool isAccessAllowed() const;
+ Validity getValidity() const;
+
+private:
+ bool m_isAccessAllowed;
+ Validity m_validity;
+};
+
+class PromptModel
+{
+ public:
+ static PromptLabels* getOneShotModel(const std::string& resourceId);
+ static PromptLabels* getSessionModel(const std::string& resourceId);
+ static PromptLabels* getBlanketModel(const std::string& resourceId);
+
+ enum PromptType
+ {
+ PROMPT_ONESHOT,
+ PROMPT_SESSION,
+ PROMPT_BLANKET
+ };
+};
+
+} // Prompt
+
+#endif /* WRT_SRC_ACCESSCONTROL_ENGINE_PROMPT_MODEL_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ *
+ *
+ * @file TimedVerdict.h
+ * @author Grzegorz Krawczyk (g.krawczyk@samsung.com)
+ * @version 0.1
+ * @brief
+ */
+
+#ifndef ACCESS_CONTROL_DAO_TIMEDVERDICT_H_
+#define ACCESS_CONTROL_DAO_TIMEDVERDICT_H_
+
+#include <dpl/ace-dao-ro/VerdictTypes.h>
+
+namespace AceDB{
+
+struct TimedVerdict
+{
+ VerdictTypes decision;
+ /*Below values are optional,its filled only when verdict depend on session*/
+ std::string session;
+ int subjectVerdictId;
+};
+
+}
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ *
+ *
+ * @file ValidityTypes.h
+ * @author Grzegorz Krawczyk (g.krawczyk@samsung.com)
+ * @version 0.1
+ * @brief
+ */
+
+#ifndef ACCESS_CONTROL_DAO_VALIDITYTYPES_H_
+#define ACCESS_CONTROL_DAO_VALIDITYTYPES_H_
+
+namespace AceDB{
+
+enum class ValidityTypes
+{
+ ONCE,
+ SESSION,
+ ALWAYS,
+ UNWRITEABLE
+};
+
+}
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ *
+ *
+ * @file VerdictTypes.h
+ * @author Grzegorz Krawczyk (g.krawczyk@samsung.com)
+ * @version 0.1
+ * @brief
+ */
+
+#ifndef ACCESS_CONTROL_DAO_VERDICTTYPES_H_
+#define ACCESS_CONTROL_DAO_VERDICTTYPES_H_
+
+namespace AceDB{
+
+enum class VerdictTypes
+{
+ VERDICT_PERMIT,
+ VERDICT_DENY,
+ //Verdict is innapplicable if policy evaluate to INAPPLICABLE,
+ //in this case WRT should decide what to do
+ VERDICT_INAPPLICABLE,
+ VERDICT_UNDETERMINED,
+ VERDICT_UNKNOWN, //Verdict is unknown if Verdicts manager cannot find it
+ VERDICT_ASYNC,
+ VERDICT_ERROR
+};
+
+}
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_SRC_CONFIGURATION_COMMON_DAO_TYPES_H_
+#define WRT_SRC_CONFIGURATION_COMMON_DAO_TYPES_H_
+
+#include <set>
+#include <string>
+#include <map>
+#include <vector>
+#include <list>
+#include <dpl/optional_typedefs.h>
+#include <dpl/shared_ptr.h>
+
+namespace WrtDB {
+namespace Powder {
+
+typedef std::set<DPL::String> StringSet;
+//! Widget description
+struct Description
+{
+ //!Content level
+ typedef enum
+ {
+ Level0 = 0,
+ Level1,
+ Level2,
+ Level3,
+ Level4,
+ Level5,
+ LevelUnknown
+ } LevelEnum;
+ struct LevelEntry
+ {
+ LevelEnum level; //!< content level
+
+ typedef StringSet Context;
+
+ //! POWDER context
+ //! xa This material appears in an artistic context
+ //! xb This material appears in an educational context
+ //! xc This material appears in a medical context
+ //! xd This material appears in a sports context
+ //! xe This material appears in a violent context
+ Context context;
+ explicit LevelEntry(LevelEnum level = LevelUnknown);
+ //! Function checks if context is valid
+ //! \param[in] level POWDER content level
+ //! \param[in] context POWDER context
+ bool isContextValid(LevelEnum level,
+ const DPL::OptionalString& context) const;
+ };
+
+ struct CategoryEntry
+ {
+ //! Levels entries for POWDER description
+ typedef std::vector <LevelEntry> LevelsContainer;
+ LevelsContainer levels;
+ //! Function checks if context is valid
+ //! \param[out] reason set if context invalid
+ //! \param[in] level POWDER content level
+ //! \param[in] context POWDER context
+ bool isCategoryValid(LevelEntry& reason,
+ LevelEnum level,
+ const DPL::OptionalString& context) const;
+ };
+
+ //! POWDER Category -> Category entry map for Widget
+ //!
+ //! nu Nudity
+ //! se Sex
+ //! vi Violence
+ //! la Potentially offensive language
+ //! dr Drug use
+ //! ga Gambling
+ //! ha Hate or harmful activities
+ //! ug Use of user-generated content
+ typedef std::map<DPL::String, CategoryEntry> CategoryEntries;
+
+ CategoryEntries categories;
+
+ //! Age rating for widget
+ //! If Null not set
+ DPL::OptionalInt ageRating;
+};
+} // namespace Powder
+
+namespace ChildProtection {
+
+//! Blacklist with forbidden URLs
+//! It should be stored in WidgetDAO
+typedef std::vector<DPL::String> BlackList;
+
+//! Widget Child protection record
+//! Record should be stored in WingetDAO
+struct Record
+{
+ //! Child protection enabled
+ bool enabled;
+ explicit Record(bool enabled) :
+ enabled(enabled)
+ {
+ }
+};
+
+//! Powder processing
+struct PowderRules
+{
+ //! Rule set by parent about forbidden category
+ //! Powder category
+ //! nu Nudity
+ //! se Sex
+ //! vi Violence
+ //! la Potentially offensive language
+ //! dr Drug use
+ //! ga Gambling
+ //! ha Hate or harmful activities
+ //! ug Use of user-generated content
+ //! Powder context
+ //! xa This material appears in an artistic conteaxt
+ //! xb This material appears in an educational context
+ //! xc This material appears in a medical context
+ //! xd This material appears in a sports context
+ //! xe This material appears in a violent context
+ struct CategoryRule
+ {
+ DPL::String category;
+ Powder::Description::LevelEnum level;
+ DPL::OptionalString context;
+ explicit CategoryRule(const DPL::String& category = DPL::String(),
+ Powder::Description::LevelEnum level =
+ Powder::Description::LevelUnknown,
+ const DPL::OptionalString& context = DPL::OptionalString());
+ };
+
+ struct PowderResult
+ {
+ //! Reasoning outcome: part of POWDER description used to invalidate
+ Powder::Description::LevelEntry invalidDescription;
+ //! Reasoning outcome: rule set by parent not full filed by description
+ CategoryRule invalidRule;
+
+ //! Reasoning outcome: type of invalidity
+ enum InvalidReason
+ {
+ InvalidRule, //!< One of rules was not fulfilled
+ InvalidAge, //!< Age is invalid
+ AgeRatingNotSet, //!< Age rating for widget is not set
+ Valid //!< Description valid
+ };
+ InvalidReason reason;
+ explicit PowderResult(InvalidReason reason = Valid,
+ const Powder::Description::LevelEntry& invalidDescription =
+ Powder::Description::LevelEntry(),
+ const CategoryRule& invalidRule = CategoryRule());
+ };
+
+ typedef std::pair<bool, PowderResult> ResultPair;
+
+ //! Function checks if rule is fulfilled by description
+ //! \param[in] rule checked rule
+ //! \param[in] description
+ //! \retval true rule is valid
+ //! \retval false rule is invalid
+ ResultPair isRuleValidForDescription(const CategoryRule& rule,
+ const Powder::Description& description) const;
+ //! Function checks if age limit is fulfilled by description
+ //! \param[in] description
+ //! \retval true age is valid
+ //! \retval false age is invalid
+ ResultPair isAgeValidForDescription(
+ const Powder::Description& description) const;
+
+ //! It is the maximum age rating valid for child
+ //! Uniform age is stored in WidgetDAO
+ DPL::OptionalInt ageLimit;
+
+ //! Set to true if age rating is required
+ //! If ageLimit is not set value is ignored
+ bool isAgeRatingRequired;
+
+ //! Set of rules configured by parent
+ //! Rules are stored in WidgetDAO and are uniform for all widgets
+ typedef std::vector<CategoryRule> RulesContainer;
+ RulesContainer rules;
+
+ //! Function check if Widget description is valid for ChildProtection
+ //! configuration
+ //! \param description widget description
+ //! \retval true widget is valid
+ //! \retval false widget is invalid
+ ResultPair isDescriptionValid(const Powder::Description& description)
+ const;
+
+ PowderRules() :
+ isAgeRatingRequired(false)
+ {
+ }
+};
+} // namespace ChildProtection
+
+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;
+ std::string m_featuresInstallURI;
+ std::string m_featuresKeyCN;
+ std::string m_featuresRootCN;
+ std::string m_featuresRootFingerprint;
+
+ FeatureContainer m_featureContainer;
+};
+
+class PluginObjectsDAO
+{
+ public:
+ typedef std::set<std::string> Objects;
+ typedef DPL::SharedPtr<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;
+
+/**
+ * @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;
+
+typedef std::list<DPL::String> WindowModeList;
+
+/**
+ * @brief Widget configuration parameter key
+ */
+typedef DPL::String WidgetParamKey;
+
+/**
+ * @brief Widget configuration parameter value
+ */
+typedef DPL::String WidgetParamValue;
+
+/**
+ * @brief A map of widget configuration parameters.
+ *
+ * Widget configuration parameters are read from database and are stored
+ * along with feature that they describe.
+ */
+typedef std::multimap<WidgetParamKey, WidgetParamValue> WidgetParamMap;
+
+/**
+ * @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 required; /// Whether feature is required
+ DbPluginHandle pluginId; /// Plugin id that implement this feature
+ WidgetParamMap params; /// Widget's params
+
+ DbWidgetFeature() :
+ required(false),
+ 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.required == featureB.required &&
+ 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;
+
+/**
+ * @brief Widget specific type
+ *
+ * Widget type describes belowed in WAC, TIZEN WebApp
+ */
+enum AppType
+{
+ APP_TYPE_UNKNOWN = 0, // unknown
+ APP_TYPE_WAC10, // WAC 1.0
+ APP_TYPE_WAC20, // WAC 2.0
+ APP_TYPE_TIZENWEBAPP, // Tizen webapp
+};
+
+class WidgetType
+{
+ public:
+ WidgetType()
+ :appType(APP_TYPE_UNKNOWN)
+ {
+ }
+ WidgetType(const AppType type)
+ :appType(type)
+ {
+ }
+ 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_WAC10)
+ X(APP_TYPE_WAC20)
+ X(APP_TYPE_TIZENWEBAPP)
+#undef X
+ default:
+ return "UNKNOWN";
+ }
+ }
+
+ AppType appType;
+};
+
+} // namespace WrtDB
+
+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 Application Service
+ *
+ * Application sercvice describes details of behaviour
+ * when widget receives aul bundle data.
+ */
+struct WidgetApplicationService
+{
+ public:
+ DPL::String src; /* start uri */
+ DPL::String operation; /* service name */
+ DPL::String scheme; /* scheme type*/
+ DPL::String mime; /* mime type */
+
+ bool operator== (const WidgetApplicationService& other) const
+ {
+ return src == other.src &&
+ operation == other.operation &&
+ scheme == other.scheme &&
+ mime == other.mime;
+ }
+};
+
+typedef std::list<WidgetApplicationService> WidgetApplicationServiceList;
+#endif /* WRT_SRC_CONFIGURATION_COMMON_DAO_TYPES_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_types.h
+ *
+ * Created on: Nov 21, 2011
+ * Author: Krzysztof Jackiewicz(k.jackiewicz@samsung.com)
+ */
+
+#ifndef WRT_DB_TYPES_H_
+#define WRT_DB_TYPES_H_
+
+#include <dpl/ace-dao-ro/common_dao_types.h>
+
+typedef WrtDB::DbWidgetHandle WidgetHandle;
+typedef WrtDB::DbWidgetHandleList WidgetHandleList;
+
+typedef WrtDB::DbWidgetFeature WidgetFeature;
+typedef WrtDB::DbWidgetFeatureSet WidgetFeatureSet;
+
+typedef WrtDB::DbWidgetSize WidgetSize;
+
+typedef WrtDB::DbPluginHandle PluginHandle;
+
+#endif /* WRT_DB_TYPES_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ *
+ *
+ * @file AceDAO.h
+ * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @version 0.1
+ * @brief
+ */
+
+#ifndef ACEDAO_H_
+#define ACEDAO_H_
+
+#include <set>
+#include <list>
+#include <map>
+#include <string>
+
+#include <dpl/optional_typedefs.h>
+#include <dpl/string.h>
+#include <dpl/ace-dao-ro/AceDAOReadOnly.h>
+#include <dpl/ace-dao-ro/ValidityTypes.h>
+
+namespace AceDB {
+/*
+ *
+ */
+class AceDAO : public AceDAOReadOnly
+{
+ public:
+
+ AceDAO() {}
+
+ // Policy Decisions
+ static void setPolicyResult(
+ const BaseAttributeSet &attributes,
+ const PolicyResult &policyResult);
+
+ static void removePolicyResult(
+ const BaseAttributeSet &attributes);
+
+ // PromptDecision
+ static void setPromptDecision(
+ const DPL::String &hash,
+ const DPL::String &userParam,
+ const DPL::OptionalString &session,
+ PromptDecision decision);
+ static void setPromptDecision(
+ const BaseAttributeSet &attributes,
+ const DPL::String &userParam,
+ const DPL::OptionalString &session,
+ PromptDecision decision);
+
+ static void clearPromptDecisions(void);
+
+ // reseting database
+ static void clearWidgetDevCapSettings(void);
+ static void clearDevCapSettings(void);
+ static void clearAllSettings(void);
+ static void resetDatabase(void);
+
+ // resource settings
+ static void setDevCapSetting(const std::string &resource,
+ PreferenceTypes preference);
+ static void removeDevCapSetting(const std::string &resource);
+
+ // user settings
+ static void setWidgetDevCapSetting(
+ const std::string &resource,
+ WidgetHandle handler,
+ PreferenceTypes);
+ static void removeWidgetDevCapSetting(
+ const std::string &resource,
+ WidgetHandle handler);
+
+ // resource and subject management
+ static int addResource(const std::string &request);
+
+ // utilities
+ static void addAttributes(const BaseAttributeSet &attributes);
+
+ // set static dev cap permissions
+ //
+ // (For a given widget handle, a set of device caps is
+ // granted "statically", i.e. it is determined at installation
+ // time that the widget will always get (at launch) the SMACK
+ // permissions needed to use those device caps).
+ //
+ // 'permissions' is the set of device cap names to be assigned
+ // as "statically permitted" to the given widget handle
+ static void setStaticDevCapPermissions(
+ int widgetHandle,
+ const std::set<DPL::String> &permissions);
+
+};
+}
+#endif /* ACEDAO_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_ACCESS_CONTROL_LOGIC_ABSTRACT_POLICY_ENFORCEMENT_POINTS_H
+#define WRT_SRC_ACCESS_CONTROL_LOGIC_ABSTRACT_POLICY_ENFORCEMENT_POINTS_H
+
+#include <dpl/ace/WRT_INTERFACE.h>
+#include <dpl/event/inter_context_delegate.h>
+#include <dpl/ace/PolicyResult.h>
+
+class AbstractPolicyEnforcementPoint
+{
+ public:
+ typedef DPL::Event::ICDelegate<PolicyResult> ResponseReceiver;
+ virtual PolicyResult check(Request &request) = 0;
+};
+
+#endif /* WRT_SRC_ACCESS_CONTROL_LOGIC_ABSTRACT_POLICY_ENFORCEMENT_POINTS_H */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+class AbstractPolicyInformationPoint
+{
+ public:
+ virtual ~AbstractPolicyInformationPoint() {}
+};
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//
+//
+//
+// @ Project : Access Control Engine
+// @ File Name : AbstractTreeElement.h
+// @ Date : 2009-05-25
+// @ Author : Samsung
+//
+//
+#if !defined(_ABSTRACTTREEELEMENT_H)
+#define _ABSTRACTTREEELEMENT_H
+
+#include <list>
+#include "Effect.h"
+#include <iostream>
+
+class AbstractTreeElement
+{
+ public:
+
+ virtual ~AbstractTreeElement()
+ {
+ }
+
+ virtual void printData() = 0;
+
+ virtual void serialize(std::ostream& os) = 0;
+ protected:
+};
+
+#endif //_ABSTRACTTREEELEMENT_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 _ASYNCVERDICT_H
+#define _ASYNCVERDICT_H
+
+#include <dpl/ace/Verdict.h>
+#include <dpl/ace/WRT_INTERFACE.h>
+#include <dpl/ace/Request.h>
+
+class AsyncVerdictResultListener
+{
+ public:
+ virtual void onVerdict(const Verdict &verdict,
+ const Request *request) = 0;
+ virtual ~AsyncVerdictResultListener()
+ {
+ }
+};
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//
+//
+//
+// @ Project : Access Control Engine
+// @ File Name : Attribute.h
+// @ Date : 2009-05-06
+// @ Author : Samsung
+//
+//
+
+#if !defined(_ATTRIBUTE_H)
+#define _ATTRIBUTE_H
+
+#include <string>
+#include <iostream>
+#include <set>
+#include <list>
+
+#include <dpl/ace-dao-ro/BaseAttribute.h>
+
+class Attribute : public AceDB::BaseAttribute
+{
+ public:
+ /**
+ * Types of match functions
+ */
+ enum class Match { Equal, Glob, Regexp, Error };
+ /**
+ * Types of attribute value modifiers
+ */
+ enum class Modifier { Non, Scheme, Authority, SchemeAuthority, Host, Path };
+ /**
+ * Possible match results
+ */
+ enum class MatchResult { MRUndetermined = -1, MRFalse = 0, MRTrue = 1};
+
+ public:
+
+ /**
+ * New attribute constructor
+ * @param name name of the new attribute
+ * @param matchFunction match function used in the attribute
+ * @param type attribute type
+ */
+ Attribute(const std::string *name,
+ const Match matchFunction,
+ const Type type);
+
+ /**
+ * Constructor used by ACE serializer
+ * @param is Input stream to which the object will be serialized
+ * @deprecated
+ */
+ Attribute(std::istream& is);
+
+ /**
+ * Constructor used to create default attribute ( used for unit tests )
+ * @param nm name of the default attribute
+ */
+ Attribute(const std::string& nm) :
+ matchFunction(Match::Error),
+ modifierFunction(Modifier::Non)
+ {
+ m_name = nm;
+ m_typeId = Type::Subject;
+ m_undetermindState = false;
+ }
+
+ /**
+ * Destructor
+ */
+ virtual ~Attribute();
+
+ bool serialize(std::ostream& os) const;
+
+ std::list<std::string> * getValue() const
+ {
+ return AceDB::BaseAttribute::getValue();
+ }
+ Match getMatchFunction() const
+ {
+ return matchFunction;
+ }
+
+ /* --- Setters --- */
+ void addValue (const std::string *value);
+
+ MatchResult matchAttributes(const BaseAttribute *) const;
+
+ /**
+ * Operator used in for attribute set,used to distinguished only attribute names
+ * It cannot take attribute type into consideration
+ */
+ bool operator< (const Attribute & obj) const
+ {
+ int result = this->m_name.compare(*obj.getName());
+ if (result == 0) { //If names are equal check attribute types
+ if (this->m_typeId < obj.getType()) {
+ result = -1;
+ } else if (this->m_typeId > obj.getType()) {
+ result = 1;
+ }
+ }
+ //If result is negative that means that 'this' was '<' than obj
+ return result < 0;
+ }
+
+ /** Checks if object type is equal to argument */
+ bool instanceOf(Type type_)
+ {
+ return type_ == m_typeId;
+ }
+
+ friend std::ostream & operator<<(std::ostream & out,
+ const Attribute & attr);
+
+ protected:
+
+ bool searchAndCut(const char *);
+
+ /*
+ * URI definition from rfc2396
+ *
+ * <scheme>://<authority><path>?<query>
+ * Each of the components may be absent, apart from the scheme.
+ * Host is a part of authority as in definition below:
+ *
+ * authority = server | reg_name
+ * server = [ [ userinfo "@" ] hostport ]
+ * <userinfo>@<host>:<port>
+ *
+ * Extract from rfc2396
+ * The authority component is preceded by a double slash "//" and is
+ * terminated by the next slash "/", question-mark "?", or by the end of
+ * the URI. Within the authority component, the characters ";", ":",
+ * "@", "?", and "/" are reserved.
+ *
+ * Modifiers should return pointer to empty string if given part of string was empty.
+ * Modifiers should return NULL if the string to be modified was not an URI.
+ */
+ std::string * uriScheme(const std::string *) const;
+ std::string * uriAuthority(const std::string *) const;
+ std::string * uriSchemeAuthority(const std::string *) const;
+ std::string * uriHost(const std::string *) const;
+ std::string * uriPath(const std::string *) const;
+ std::string * applyModifierFunction(const std::string * val) const;
+
+ bool parse(const std::string *input,
+ std::string *part) const;
+ bool find_error(const std::string *part) const;
+
+ bool checkScheme(const std::string *scheme) const;
+ bool checkAuthority(const std::string *scheme) const;
+ std::string * getHost(const std::string *scheme) const;
+ bool checkPath(const std::string *scheme) const;
+
+ bool isSchemeAllowedCharacter(int c) const;
+ bool isSegmentAllowedCharacter(int c) const;
+ bool isUserInfoAllowedString(const std::string *str) const;
+ bool isHostAllowedString(const std::string *str) const;
+ bool isHostNameAllowedString(const std::string * str) const;
+ bool isIPv4AllowedString(const std::string * str) const;
+ bool isDomainLabelAllowedString(const char * data,
+ int lenght) const;
+ bool isTopLabelAllowedString(const char* data,
+ int lenght) const;
+
+ bool isUnreserved(int c) const;
+ bool isAlphanum(int c) const;
+ bool isEscaped(const char esc[3]) const;
+ bool isHex(int c) const;
+
+ MatchResult lists_comparator(
+ const std::list<std::string> *first,
+ const std::list<std::string> *second,
+ MatchResult (*comparator)(const std::string *,
+ const std::string *)) const;
+
+ /**
+ * Map used to check if character is a 'mark'
+ */
+ static const bool mark[256];
+ /**
+ * Map used to check if character is a 'digit'
+ *
+ */
+ static const bool digit[256];
+ /**
+ * Map used to check if character is an 'alphanumeric' value
+ *
+ */
+ static const bool alpha[256];
+
+ protected:
+ Match matchFunction;
+ Modifier modifierFunction;
+};
+
+typedef AceDB::BaseAttributeSet AttributeSet;
+
+//TODO remove later or ifdef debug methods
+void printAttributes(const AttributeSet& attrs);
+void printAttributes(const std::list<Attribute> & attrs);
+
+#endif //_ATTRIBUTE_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//
+//
+//
+// @ Project : Access Control Engine
+// @ File Name : Combiner.h
+// @ Date : 2009-05-06
+// @ Author : Samsung
+//
+//
+
+#if !defined(_COMBINER_H)
+#define _COMBINER_H
+
+#include <set>
+
+#include <dpl/ace/Attribute.h>
+#include <dpl/ace/TreeNode.h>
+
+class Combiner
+{
+ protected:
+
+ const AttributeSet * attrSet;
+
+ public:
+
+ virtual Effect combineRules(const TreeNode * rule) = 0;
+ virtual Effect combinePolicies(const TreeNode * policy) = 0;
+
+ const AttributeSet * getAttributeSet() const
+ {
+ return this->attrSet;
+ }
+ void setAttributeSet(const AttributeSet * attrSet)
+ {
+ this->attrSet = attrSet;
+ }
+ virtual ~Combiner()
+ {
+ } //attrSet is deleted elsewhere
+};
+
+#endif //_COMBINER_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//
+//
+//
+// @ Project : Access Control Engine
+// @ File Name : CombinerImpl.h
+// @ Date : 2009-05-06
+// @ Author : Samsung
+//
+//
+
+#ifndef _COMBINER_IMPL_H
+#define _COMBINER_IMPL_H
+
+#include <list>
+#include <dpl/log/log.h>
+
+#include "Combiner.h"
+#include "Effect.h"
+#include "Policy.h"
+#include "Subject.h"
+
+class CombinerImpl : public Combiner
+{
+ public:
+
+ virtual Effect combineRules(const TreeNode * rule);
+ virtual Effect combinePolicies(const TreeNode * policy);
+
+ virtual ~CombinerImpl()
+ {
+ }
+
+ protected:
+
+ bool checkIfTargetMatches(const std::list<const Subject *> * subjectsSet,
+ bool &isUndetermined);
+
+ Effect combine(Policy::CombineAlgorithm algorithm,
+ std::list<Effect> & effects);
+
+ Effect denyOverrides(const std::list<Effect> & effects);
+ Effect permitOverrides(const std::list<Effect> & effects);
+ Effect firstApplicable(const std::list<Effect> & effects);
+ Effect firstMatchingTarget(const std::list<Effect> & effects);
+
+ std::list<int> * convertEffectsToInts(const std::list<Effect> * effects);
+ Effect convertIntToEffect(int intEffect);
+
+ void showEffectList(std::list<Effect> & effects)
+ {
+ std::list<Effect>::iterator it = effects.begin();
+ for (; it != effects.end(); ++it) {
+ LogDebug(toString(*it));
+ }
+ }
+
+ private:
+ bool isError(const std::list<Effect> & effects);
+ static const int
+ DenyInt,
+ UndeterminedInt,
+ PromptOneShotInt,
+ PromptSessionInt,
+ PromptBlanketInt,
+ PermitInt,
+ InapplicableInt,
+ NotMatchingTargetInt,
+ ErrorInt;
+};
+
+#endif //_COMBINERIMPL_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//
+// File: Condition.h
+// Author: notroot
+//
+// Created on June 3, 2009, 9:00 AM
+//
+#ifndef _CONDITION_H
+#define _CONDITION_H
+
+#include <list>
+#include <set>
+#include <iostream>
+#include <dpl/foreach.h>
+
+#include "Attribute.h"
+#include "Effect.h"
+#include "TreeNode.h"
+
+class Condition
+{
+ public:
+ enum CombineType
+ {
+ AND, OR
+ };
+
+ void addCondition(const Condition & condition)
+ {
+ this->conditions.push_back(condition);
+ }
+
+ void addAttribute(const Attribute & attribute)
+ {
+ this->attributes.push_back(attribute);
+ }
+
+ void setCombineType(CombineType type)
+ {
+ this->combineType = type;
+ }
+
+ Condition() : combineType(AND),
+ parent(NULL)
+ {
+ }
+
+ Condition(CombineType type) : combineType(type),
+ parent(NULL)
+ {
+ }
+
+ virtual ~Condition()
+ {
+ }
+
+ Condition * getParent()
+ {
+ return this->parent;
+ }
+
+ void setParent(Condition * condition)
+ {
+ this->parent = condition;
+ }
+
+ Attribute::MatchResult evaluateCondition(
+ const AttributeSet * attrSet) const;
+
+ friend std::ostream & operator<<(std::ostream & out,
+ Condition & condition)
+ {
+ FOREACH (it, condition.attributes)
+ {
+ out << *it;
+ }
+ return out;
+ }
+ //[CR] change function name
+ void getAttributes(AttributeSet * attrSet);
+
+ //deserializer, TODO - first condition doesnt have Condtion parent
+ Condition(std::istream&,
+ Condition* parent = NULL);
+
+ bool serialize(std::ostream&);
+
+ private:
+ Attribute::MatchResult evaluateChildConditions(
+ const AttributeSet * attrSet,
+ bool &isFinalMatch,
+ bool & undefinedMatchFound) const;
+
+ Attribute::MatchResult evaluateAttributes(
+ const AttributeSet * attrSet,
+ bool& isFinalMatch,
+ bool & undefinedMatchFound) const;
+
+ // KW Attribute::MatchResult performANDalgorithm(const std::set<Attribute> * attributes) const;
+
+ // KW Attribute::MatchResult performORalgorithm(const std::set<Attribute> * attributes) const;
+
+ bool isEmpty() const
+ {
+ return attributes.empty() && conditions.empty();
+ }
+
+ bool isAndCondition() const
+ {
+ return combineType == AND;
+ }
+
+ bool isOrCondition() const
+ {
+ return combineType == OR;
+ }
+
+ std::list<Condition> conditions;
+ CombineType combineType;
+ std::list<Attribute> attributes;
+ Condition *parent;
+};
+
+#endif /* _CONDITION_H */
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 _CONFIGURATIONMANAGER_H_
+#define _CONFIGURATIONMANAGER_H_
+
+#include <list>
+#include <string.h>
+#include <string>
+#include <libxml/xmlreader.h>
+#include "Constants.h"
+#include <fstream>
+#include <iostream>
+#include <dpl/log/log.h>
+
+#define ATTR_ACTIVE_POLICY BAD_CAST("active")
+
+#define PARSER_ERROR 1
+#define PARSER_SUCCESS 0
+
+class ConfigurationManager
+{
+ public:
+ enum ConfigurationManagerResult
+ {
+ CM_OPERATION_SUCCESS = 0,
+ CM_GENERAL_ERROR = -1,
+ CM_FILE_EXISTS = -2,
+ CM_REMOVE_ERROR = -3,
+ CM_REMOVE_CURRENT = -4,
+ CM_REMOVE_NOT_EXISTING = -5
+ };
+
+ /**
+ * Current policy file getter
+ * @return Name of the current ACE policy file
+ */
+ std::string getCurrentPolicyFile(void) const;
+
+ /**
+ * ACE policy file path getter
+ * @return Full path to ACE current policy file
+ */
+ std::string getFullPathToCurrentPolicyFile(void) const;
+
+ /**
+ * ACE policy dtd file path getter
+ * @return Full path to ACE current policy file
+ */
+ std::string getFullPathToCurrentPolicyXMLSchema(void) const;
+
+ /**
+ * ACE policy storage path getter
+ * @return Full path to ACE policy file storage
+ */
+ std::string getStoragePath(void) const;
+
+ /**
+ * Adds file to ACE policy storage
+ * @param filePath full path to policy to be added
+ * @return CM_OPERATION_SUCCESS on success,
+ * CM_FILE_EXISTS if file with the same name already exists in the storage (the new file is not added),
+ * other error code on other error
+ *
+ */
+ int addPolicyFile(const std::string & filePath);
+
+ /**
+ * Removes file with a given filename from ACE policy storage
+ * @param fileName name of the policy to be removed
+ * @return CM_OPERATION_SUCCESS on success,
+ * CM_REMOVE_CURRENT if file to be removed is a current file (it cannot be removed)
+ * CM_REMOVE_NOT_EXISTING if file already doesn't exists
+ * other error code on other error
+ *
+ */
+ int removePolicyFile(const std::string& fileName);
+
+ //change current PolicyFile
+ /**
+ * @param filePath Name of the policy file in the policy storage that should be made
+ * a current policy file
+ * @param CM_OPERATION_SUCCESS on success or error code on error
+ */
+ int changeCurrentPolicyFile(const std::string& filePath);
+
+ //TODO this getInstance() method is a little bit to complicated
+ /**
+ * Method to obtain instance of configuration manager
+ * @return retuns pointer to configuration manager or NULL in case of error
+ */
+ static ConfigurationManager * getInstance()
+ {
+ if (!instance) {
+ instance = new ConfigurationManager();
+ if (instance->parse(std::string(ACE_CONFIGURATION_PATH)) !=
+ PARSER_SUCCESS) {
+ delete instance;
+ LogError(
+ "Couldn't parse configuration file " ACE_CONFIGURATION_PATH);
+ return NULL;
+ }
+ }
+ return instance;
+ }
+
+ /**
+ * Extracts filename from full path
+ * @param path Full path from which filename should be extracted
+ * @return returns extracted filename
+ */
+ std::string extractFilename(const std::string& path) const;
+
+ protected:
+
+ /**
+ * Parse given ACE configuration file
+ * @param configFileName full path to configuration file to be parsed
+ * @return PARSER_SUCCESS on succes, PARSER_ERROR on error
+ */
+ int parse(const std::string &configFileName);
+ /**
+ * @param path full path to the file which size should be obtained
+ * @return size of a given file in bytes
+ */
+ int getFileSize(const std::string & path) const;
+ bool copyFile(FILE * source,
+ FILE * destination,
+ int lenght = 1024) const;
+ bool checkIfFileExistst(const std::string & newFilePath) const;
+
+ const std::list<std::string> & getPolicyFiles() const
+ {
+ return policyFiles;
+ }
+
+ const std::string & getConfigFile() const
+ {
+ return configFile;
+ }
+
+ ConfigurationManager() : xmlActive(false)
+ {
+ }
+ virtual ~ConfigurationManager()
+ {
+ }
+
+ private:
+
+ /**
+ * Internal parser methods
+ */
+ void extractFileAttributes(void);
+ void startNodeHandler(void);
+ void endNodeHandler(void);
+ void textNodeHandler(void);
+ void processNode(void);
+ //Save configuration file
+ int saveConfig();
+
+ //Private fields for parser state representation
+ xmlTextReaderPtr reader;
+ std::string currentText;
+ bool xmlActive;
+
+ static ConfigurationManager * instance;
+
+ /**
+ * Full path to ACE configuration file
+ */
+ std::string configFile;
+ /**
+ * ACE policy file storage path
+ */
+ std::string storagePath;
+ /**
+ * Name of the current ACE policy
+ */
+ std::string currentPolicyFile;
+ /**
+ * List of available ACE policy files
+ */
+ std::list<std::string> policyFiles;
+
+ //////////NEW
+};
+
+#endif
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @file Constants.h
+ * @author Piotr Fatyga (p.fatyga@samsung.com)
+ * @version 0.1
+ * @brief
+ */
+
+#ifndef _CONSTANTS_H
+#define _CONSTANTS_H
+
+#define ACE_MAIN_STORAGE "/usr/etc/ace"
+#define ACE_CONFIGURATION_PATH ACE_MAIN_STORAGE "/config.xml"
+#define ACE_CONFIGURATION_DTD ACE_MAIN_STORAGE "/config.dtd"
+#define ACE_DTD_LOCATION ACE_MAIN_STORAGE "/bondixml.dtd"
+
+/////////////////FOR GUI//////////////////////
+
+#define MYSTERIOUS_BITMAP "/usr/apps/org.tizen.policy/d.png"
+#define MYSTERIOUS_BITMAP2 "/usr/apps/org.tizen.policy/file.png"
+
+///////////////////FOR TESTS//////////////////////////
+
+#define COMBINER_TEST "/usr/etc/ace/CMTest/com_general-test.xml"
+#define CONFIGURATION_MGR_TEST_PATH "/usr/etc/ace/CMTest/"
+#define CONFIGURATION_MGR_TEST_CONFIG ACE_MAIN_STORAGE "/CMTest/pms_config.xml"
+#define CONFIGURATION_MGR_TEST_POLICY_STORAGE ACE_MAIN_STORAGE "/CMTest/active"
+#define CONFIGURATION_MGR_TEST_POLICY_STORAGE_MOVED ACE_MAIN_STORAGE \
+ "/CMTest/activeMoved"
+#define CONFIGURATION_MGR_TEST_POLICY CONFIGURATION_MGR_TEST_POLICY_STORAGE \
+ "/pms_general-test.xml"
+#define POLICIES_TO_SIGN_DIR ACE_MAIN_STORAGE "/SignerTests/"
+
+#define OUTPUT_DIR ACE_MAIN_STORAGE "/SignerTests/signedPolicies/"
+#define PRIVATE_KEY_DIR ACE_MAIN_STORAGE "/SignerTests/PrvKey/"
+#define X509_DATA_BASE_DIR ACE_MAIN_STORAGE "/SignerTests/X509Data/"
+
+#endif /* _CONSTANTS_H */
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//
+//
+//
+// @ Project : Access Control Engine
+// @ File Name : Effect.h
+// @ Date : 2009-05-06
+// @ Author : Samsung
+//
+//
+
+#if !defined(_EFFECT_H)
+#define _EFFECT_H
+
+enum Effect
+{
+ Deny =0,
+ Undetermined=1, // jk mb added this enum, so the ones below are inceremented!!!!!!!
+ PromptOneShot =2,
+ PromptSession =3,
+ PromptBlanket =4,
+ Permit =5,
+ Inapplicable =6,
+ NotMatchingTarget=7,
+ Error
+};
+
+const char * toString(Effect);
+
+#endif //_EFFECT_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#if !defined(_NODE_FACTORY_H)
+#define _NODE_FACTORY_H
+
+#include <iostream>
+#include "TreeNode.h"
+#include "Policy.h"
+#include "PolicySet.h"
+#include "Rule.h"
+
+class NodeFactory
+{
+ public:
+ static NodeFactory* getInstance();
+ AbstractTreeElement* create(std::istream&,
+ TreeNode:: TypeID);
+ private:
+ NodeFactory()
+ {
+ }
+ static NodeFactory* pInstance;
+};
+
+#endif
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//
+//
+//
+// @ Project : Access Control Engine
+// @ File Name : PermissionTriple.h
+// @ Date : 2009-05-06
+// @ Author : Samsung
+//
+//
+
+#if !defined(_PERMISSION_TRIPLE_H)
+#define _PERMISSION_TRIPLE_H
+
+#include <string>
+#include <list>
+#include <dpl/ace-dao-ro/PreferenceTypes.h>
+#include <dpl/ace-dao-ro/BasePermission.h>
+
+typedef AceDB::BasePermission PermissionTriple;
+typedef AceDB::BasePermissionList PermissionList;
+
+struct GeneralSetting
+{
+ GeneralSetting(const std::string& resourceName,
+ AceDB::PreferenceTypes accessAllowed) : generalSettingName(resourceName),
+ access(accessAllowed)
+ {
+ }
+ std::string generalSettingName;
+ AceDB::PreferenceTypes access;
+};
+
+#endif //_PERMISSION_TRIPLE_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//
+//
+//
+// @ Project : Access Control Engine
+// @ File Name : Policy.h
+// @ Date : 2009-05-06
+// @ Author : Samsung
+//
+//
+
+#if !defined(_POLICY_H)
+#define _POLICY_H
+
+#include <list>
+
+#include <dpl/ace/AbstractTreeElement.h>
+#include <dpl/ace/Effect.h>
+#include <dpl/ace/Attribute.h>
+#include <dpl/ace/Subject.h>
+#include <iostream>
+#include <dpl/noncopyable.h>
+
+class Policy : public AbstractTreeElement,
+ DPL::Noncopyable
+{
+ public:
+ enum CombineAlgorithm { DenyOverride, PermitOverride, FirstApplicable,
+ FirstTargetMatching };
+
+ Policy(std::istream& is);
+
+ void serialize(std::ostream& os);
+
+ Policy()
+ {
+ combineAlgorithm = DenyOverride;
+ subjects = new std::list<const Subject *>();
+ }
+
+ CombineAlgorithm getCombineAlgorithm() const
+ {
+ return this->combineAlgorithm;
+ }
+
+ void setCombineAlgorithm(CombineAlgorithm algorithm)
+ {
+ this->combineAlgorithm = algorithm;
+ }
+
+ const std::list<const Subject *> * getSubjects() const
+ {
+ return this->subjects;
+ }
+
+ void addSubject(const Subject * subject)
+ {
+ if (this->subjects == NULL) {
+ return;
+ }
+ this->subjects->push_back(subject);
+ }
+
+ virtual ~Policy();
+
+ void printData();
+
+ std::string printCombineAlgorithm(CombineAlgorithm algorithm);
+
+ private:
+ std::list<const Subject *> *subjects;
+ CombineAlgorithm combineAlgorithm;
+};
+
+const char * toString(Policy::CombineAlgorithm algorithm);
+
+#endif //_POLICY_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file PolicyEffect.h
+ * @author B.Grzelewski (b.grzelewski@samsung.com)
+ * @version 1.0
+ * @brief This file contains the declaration of PolicyEffect type.
+ */
+#ifndef _SRC_ACCESS_CONTROL_COMMON_POLICY_EFFECT_H_
+#define _SRC_ACCESS_CONTROL_COMMON_POLICY_EFFECT_H_
+
+enum class PolicyEffect {
+ DENY = 0,
+ PERMIT,
+ PROMPT_ONESHOT,
+ PROMPT_SESSION,
+ PROMPT_BLANKET
+};
+
+inline static std::ostream & operator<<(std::ostream& stream,
+ PolicyEffect effect)
+{
+ switch (effect) {
+ case PolicyEffect::DENY: stream << "DENY"; break;
+ case PolicyEffect::PERMIT: stream << "PERMIT"; break;
+ case PolicyEffect::PROMPT_ONESHOT: stream << "PROMPT_ONESHOT"; break;
+ case PolicyEffect::PROMPT_SESSION: stream << "PROMPT_SESSION"; break;
+ case PolicyEffect::PROMPT_BLANKET: stream << "PROMPT_BLANKET"; break;
+ default: Assert(false && "Invalid PolicyEffect constant");
+ }
+ return stream;
+}
+
+#endif // _SRC_ACCESS_CONTROL_COMMON_POLICY_EFFECT_H_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 class simply redirects the access requests to access control engine.
+ * The aim is to hide access control engine specific details from WRT modules.
+ * It also implements WRT_INTERFACE.h interfaces, so that ACE could access
+ * WRT specific and other information during the decision making.
+ *
+ * @file security_logic.h
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @author Ming Jin(ming79.jin@samsung.com)
+ * @brief Implementation file for security logic
+ */
+#ifndef POLICY_ENFORCEMENT_POINT_H
+#define POLICY_ENFORCEMENT_POINT_H
+
+#include <memory>
+#include <string>
+#include <map>
+
+//#include <glib/gthread.h>
+//#include <glib/gerror.h>
+//#include <glib.h>
+
+//#include <dpl/optional.h>
+#include <dpl/event/inter_context_delegate.h>
+#include <dpl/event/property.h>
+
+#include <dpl/ace/AbstractPolicyEnforcementPoint.h>
+#include <dpl/ace/PolicyResult.h>
+
+// Forwards
+class IWebRuntime;
+class IResourceInformation;
+class IOperationSystem;
+class PolicyEvaluator;
+class PolicyInformationPoint;
+class Request;
+
+class PolicyEnforcementPoint : public AbstractPolicyEnforcementPoint
+{
+ public:
+ OptionalPolicyResult checkFromCache(Request &request);
+ PolicyResult check(Request &request);
+ OptionalPolicyResult check(Request &request,
+ bool fromCacheOnly);
+
+ virtual ~PolicyEnforcementPoint();
+
+ class PEPException
+ {
+ public:
+ DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+ DECLARE_EXCEPTION_TYPE(Base, AlreadyInitialized)
+ };
+
+ /**
+ * This function take ownership of objects pass in call.
+ * Object will be deleted after call Deinitialize function.
+ */
+ void initialize(IWebRuntime *wrt,
+ IResourceInformation *resource,
+ IOperationSystem *operation);
+ void terminate();
+
+ void updatePolicy(const std::string &policy);
+
+ PolicyEvaluator *getPdp() const { return this->m_pdp; }
+ PolicyInformationPoint *getPip() const { return this->m_pip; }
+
+ protected:
+ PolicyEnforcementPoint();
+ friend class SecurityLogic;
+ private: // private data
+ IWebRuntime *m_wrt;
+ IResourceInformation *m_res;
+ IOperationSystem *m_sys;
+ PolicyEvaluator *m_pdp;
+ PolicyInformationPoint *m_pip;
+};
+
+#endif // POLICY_ENFORCEMENT_POINT_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//
+//
+//
+// @ Project : Access Control Engine
+// @ File Name : PolicyEvaluator.h
+// @ Date : 2009-05-06
+// @ Author : Samsung
+//
+//
+
+#ifndef _POLICY_EVALUATOR_H
+#define _POLICY_EVALUATOR_H
+
+#include <memory>
+#include <set>
+#include <string>
+
+#include <dpl/event/event_listener.h>
+#include <dpl/log/log.h>
+#include <dpl/noncopyable.h>
+
+#include <dpl/ace/AsyncVerdictResultListener.h>
+#include <dpl/ace/Attribute.h>
+#include <dpl/ace/ConfigurationManager.h>
+#include <dpl/ace/Constants.h>
+#include <dpl/ace/Effect.h>
+#include <dpl/ace/Policy.h>
+#include <dpl/ace/PolicyInformationPoint.h>
+#include <dpl/ace/PolicyResult.h>
+#include <dpl/ace/Request.h>
+#include <dpl/ace/Subject.h>
+#include <dpl/ace/Verdict.h>
+#include <dpl/ace/UserDecision.h>
+#include <dpl/ace/CombinerImpl.h>
+
+
+class PolicyEvaluator : DPL::Noncopyable
+{
+ protected:
+
+ /**
+ * Internal method used to initiate policy evaluation. Called after attribute set has been fetched
+ * by PIP.
+ * @param root root of the policies tree to be evaluated
+ */
+ virtual Effect evaluatePolicies(const TreeNode * root);
+
+ enum updateErrors
+ {
+ POLICY_PARSING_SUCCESS = 0,
+ POLICY_FILE_ERROR = 1,
+ PARSER_CREATION_ERROR,
+ POLICY_PARSING_ERROR
+ };
+ private:
+ AttributeSet m_attributeSet;
+
+ TreeNode * m_root;
+ Combiner * m_combiner;
+ AsyncVerdictResultListener * m_verdictListener;
+ PolicyInformationPoint * m_pip;
+ // Required by unittests.
+ std::string m_currentPolicyFile;
+
+ /**
+ * Method used to extract attributes from subtree defined by PolicySet
+ * @param root original TreeStructure root node
+ * @param newRoot copy of TreeStructure containing only policies that matches current request
+ *
+ */
+ void extractAttributesFromSubtree(const TreeNode *root);
+
+ /**
+ * Method used to extract attributes from Tree Structure
+ * @return pointer to set of attributes needed to evaluate current request
+ * @return if extraction has been successful
+ * TODO return reducte tree structure
+ * TODO change comments
+ */
+ bool extractAttributesFromRules(const TreeNode *);
+
+ /**
+ * Extracts attributes from target of a given policy that are required to be fetched by PIP
+ */
+ void extractTargetAttributes(const Policy *policy);
+ bool extractAttributes();
+
+ OptionalPolicyResult getPolicyForRequestInternal(bool fromCacheOnly);
+ PolicyResult effectToPolicyResult(Effect effect);
+ public:
+ PolicyEvaluator(PolicyInformationPoint * pip) :
+ m_root(NULL),
+ m_combiner(new CombinerImpl()),
+ m_verdictListener(NULL),
+ m_pip(pip)
+ {
+ }
+
+ bool extractAttributesTest()
+ {
+ m_attributeSet.clear();
+ if (!extractAttributes()) {
+ LogInfo("Warnign attribute set cannot be extracted. Returning Deny");
+ return true;
+ }
+
+ return extractAttributes();
+ }
+
+ AttributeSet * getAttributeSet()
+ {
+ return &m_attributeSet;
+ }
+
+ virtual bool initPDP();
+ virtual ~PolicyEvaluator();
+ virtual PolicyResult getPolicyForRequest(const Request &request);
+ virtual OptionalPolicyResult getPolicyForRequestFromCache(
+ const Request &request);
+ virtual OptionalPolicyResult getPolicyForRequest(const Request &request,
+ bool fromCacheOnly);
+ bool fillAttributeWithPolicy();
+
+ virtual int updatePolicy(const char *);
+ // Required by unittests.
+ // It's used to check environment before each unittest.
+ std::string getCurrentPolicy();
+};
+
+#endif //_POLICYEVALUATOR_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @file AbstractObjectFactory.h
+ * @author Piotr Fatyga (p.fatyga@samsung.com)
+ * @version 0.1
+ * @brief
+ */
+
+#ifndef _ABSTRACTOBJECTFACTORY_H
+#define _ABSTRACTOBJECTFACTORY_H
+
+#include <dpl/ace/PolicyEvaluator.h>
+
+class AbstractPolicyEvaluatorFactory
+{
+ public:
+ virtual PolicyEvaluator * createPolicyEvaluator(PolicyInformationPoint *pip)
+ const = 0;
+};
+
+class PolicyEvaluatorFactory : public AbstractPolicyEvaluatorFactory
+{
+ public:
+ PolicyEvaluator * createPolicyEvaluator(PolicyInformationPoint *pip) const
+ {
+ return new PolicyEvaluator(pip);
+ }
+};
+
+#endif /* _ABSTRACTOBJECTFACTORY_H */
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//
+//
+//
+// @ Project : Access Control Engine
+// @ File Name : PolicyInformationPoint.h
+// @ Date : 2009-05-06
+// @ Author : Samsung
+//
+//
+
+#ifndef _POLICY_INFORMATION_POINT_H
+#define _POLICY_INFORMATION_POINT_H
+
+#include <set>
+
+#include <dpl/ace/Attribute.h>
+#include <dpl/ace/Request.h>
+
+#include <dpl/ace-dao-ro/BaseAttribute.h>
+
+#include <dpl/ace/WRT_INTERFACE.h>
+
+typedef int PipResponse;
+
+class PolicyInformationPoint
+{
+ private:
+
+ /** queries for interfaces*/
+ std::list<ATTRIBUTE> resourceAttributesQuery;
+ std::list<ATTRIBUTE> environmentAttributesQuery;
+ std::list<ATTRIBUTE> subjectAttributesQuery;
+ std::list<ATTRIBUTE> functionParamAttributesQuery;
+
+ /** create queries */
+ void createQueries(AttributeSet* attributes);
+
+ IWebRuntime* wrtInterface;
+ IResourceInformation* resourceInformation;
+ IOperationSystem* operationSystem;
+
+ public:
+ static const int ERROR_SHIFT_RESOURCE = 3;
+ static const int ERROR_SHIFT_OS = 6;
+ static const int ERROR_SHIFT_FP = 9;
+
+ /** Mask used to identify PIP error */
+ enum ResponseTypeMask
+ {
+ SUCCESS = 0,
+ /* WebRuntime Error */
+ WRT_UNKNOWN_SUBJECT = 1 << 0,
+ WRT_UNKNOWN_ATTRIBUTE = 1 << 1,
+ WRT_INTERNAL_ERROR = 1 << 2,
+ /* Resource Information Storage Error */
+ RIS_UNKNOWN_RESOURCE = 1 << 3,
+ RIS_UNKNOWN_ATTRIBUTE = 1 << 4,
+ RIS_INTERNAL_ERROR = 1 << 5,
+ /*Operating system */
+ OS_UNKNOWN_ATTRIBUTE = 1 << 6,
+ OS_INTERNAL_ERROR = 1 << 7
+ };
+
+ //TODO add checking values of attributes
+ /** gather attributes values from adequate interfaces */
+ virtual PipResponse getAttributesValues(const Request* request,
+ AttributeSet* attributes);
+ virtual ~PolicyInformationPoint();
+ PolicyInformationPoint(IWebRuntime *wrt,
+ IResourceInformation *resource,
+ IOperationSystem *system) : wrtInterface(wrt),
+ resourceInformation(resource),
+ operationSystem(system)
+ {
+ }
+ virtual void update(IWebRuntime *wrt,
+ IResourceInformation *resource,
+ IOperationSystem *system)
+ {
+ wrtInterface = wrt;
+ resourceInformation = resource;
+ operationSystem = system;
+ }
+ IWebRuntime * getWebRuntime()
+ {
+ return wrtInterface;
+ }
+};
+
+#endif //_POLICY_INFORMATION_POINT_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 _SRC_ACCESS_CONTROL_COMMON_POLICY_RESULT_H_
+#define _SRC_ACCESS_CONTROL_COMMON_POLICY_RESULT_H_
+
+#include <dpl/assert.h>
+#include <dpl/optional.h>
+#include <dpl/optional_typedefs.h>
+
+#include <dpl/ace/PolicyEffect.h>
+
+typedef DPL::Optional<PolicyEffect> OptionalPolicyEffect;
+
+class PolicyDecision
+{
+public:
+ enum Value { NOT_APPLICABLE = -1 };
+
+ PolicyDecision(PolicyEffect effect)
+ : m_isPolicyEffect(true)
+ , m_effect(effect)
+ {}
+
+ PolicyDecision(const PolicyDecision &decision)
+ : m_isPolicyEffect(decision.m_isPolicyEffect)
+ , m_effect(decision.m_effect)
+ {}
+
+ PolicyDecision(Value)
+ : m_isPolicyEffect(false)
+ {}
+
+ bool operator==(const PolicyDecision &decision) const {
+ return (m_isPolicyEffect
+ && decision.m_isPolicyEffect
+ && m_effect == decision.m_effect)
+ || (!m_isPolicyEffect && !decision.m_isPolicyEffect);
+ }
+
+ bool operator==(Value) const {
+ return !m_isPolicyEffect;
+ }
+
+ bool operator!=(const PolicyDecision &decision) const {
+ return !(*this == decision);
+ }
+
+ bool operator!=(Value value) const {
+ return !(*this == value);
+ }
+
+ OptionalPolicyEffect getEffect() const
+ {
+ if (!m_isPolicyEffect) {
+ return OptionalPolicyEffect();
+ }
+ return OptionalPolicyEffect(m_effect);
+ }
+
+ std::ostream & toStream(std::ostream& stream) {
+ if (m_isPolicyEffect)
+ stream << m_effect;
+ else
+ stream << "NOT-APPLICABLE";
+ return stream;
+ }
+
+private:
+ bool m_isPolicyEffect;
+ PolicyEffect m_effect;
+};
+
+inline static bool operator==(PolicyEffect e, const PolicyDecision &d) {
+ return d.operator==(e);
+}
+
+inline static bool operator!=(PolicyEffect e, const PolicyDecision &d) {
+ return !(e == d);
+}
+
+inline static std::ostream & operator<<(std::ostream& stream,
+ PolicyDecision decision)
+{
+ return decision.toStream(stream);
+}
+
+class PolicyResult {
+public:
+ enum Value { UNDETERMINED = -2 };
+
+ // This constructor is required by dpl controller and by dpl optional
+ PolicyResult()
+ : m_isDecision(false)
+ , m_decision(PolicyDecision::Value::NOT_APPLICABLE) // don't care
+ {}
+
+ PolicyResult(PolicyEffect effect)
+ : m_isDecision(true)
+ , m_decision(effect)
+ {}
+
+ PolicyResult(const PolicyDecision &decision)
+ : m_isDecision(true)
+ , m_decision(decision)
+ {}
+
+ PolicyResult(const PolicyResult &result)
+ : m_isDecision(result.m_isDecision)
+ , m_decision(result.m_decision)
+ {}
+
+ PolicyResult(PolicyDecision::Value value)
+ : m_isDecision(true)
+ , m_decision(value)
+ {}
+
+ PolicyResult(Value)
+ : m_isDecision(false)
+ , m_decision(PolicyDecision::Value::NOT_APPLICABLE) // don't care
+ {}
+
+ bool operator==(const PolicyResult &result) const {
+ return (m_isDecision
+ && result.m_isDecision
+ && m_decision == result.m_decision)
+ || (!m_isDecision && !result.m_isDecision);
+ }
+
+ bool operator==(Value) const {
+ return !m_isDecision;
+ }
+
+ bool operator!=(const PolicyResult &result) const {
+ return !(*this == result);
+ }
+
+ bool operator!=(Value value) const {
+ return !(*this == value);
+ }
+
+ OptionalPolicyEffect getEffect() const
+ {
+ if (!m_isDecision) {
+ return OptionalPolicyEffect();
+ }
+ return m_decision.getEffect();
+ }
+
+ static int serialize(const PolicyResult &policyResult)
+ {
+ if (!policyResult.m_isDecision) {
+ return BD_UNDETERMINED;
+ } else if (policyResult.m_decision ==
+ PolicyDecision::Value::NOT_APPLICABLE)
+ {
+ return BD_NOT_APPLICABLE;
+ } else if (policyResult.m_decision == PolicyEffect::PROMPT_BLANKET) {
+ return BD_PROMPT_BLANKET;
+ } else if (policyResult.m_decision == PolicyEffect::PROMPT_SESSION) {
+ return BD_PROMPT_SESSION;
+ } else if (policyResult.m_decision == PolicyEffect::PROMPT_ONESHOT) {
+ return BD_PROMPT_ONESHOT;
+ } else if (policyResult.m_decision == PolicyEffect::PERMIT) {
+ return BD_PERMIT;
+ } else if (policyResult.m_decision == PolicyEffect::DENY) {
+ return BD_DENY;
+ }
+ Assert(false && "Unknown value of policyResult.");
+ }
+
+ static PolicyResult deserialize(int dec){
+ switch (dec) {
+ case BD_DENY:
+ return PolicyEffect::DENY;
+ case BD_PERMIT:
+ return PolicyEffect::PERMIT;
+ case BD_PROMPT_ONESHOT:
+ return PolicyEffect::PROMPT_ONESHOT;
+ case BD_PROMPT_SESSION:
+ return PolicyEffect::PROMPT_SESSION;
+ case BD_PROMPT_BLANKET:
+ return PolicyEffect::PROMPT_BLANKET;
+ case BD_NOT_APPLICABLE:
+ return PolicyDecision::Value::NOT_APPLICABLE;
+ case BD_UNDETERMINED:
+ return Value::UNDETERMINED;
+ }
+ Assert(false && "Broken database");
+ }
+
+ std::ostream & toStream(std::ostream& stream) {
+ if (m_isDecision)
+ stream << m_decision;
+ else
+ stream << "UNDETERMINED";
+ return stream;
+ }
+
+private:
+ static const int BD_UNDETERMINED = 6;
+ static const int BD_NOT_APPLICABLE = 5;
+ static const int BD_PROMPT_BLANKET = 4;
+ static const int BD_PROMPT_SESSION = 3;
+ static const int BD_PROMPT_ONESHOT = 2;
+ static const int BD_PERMIT = 1;
+ static const int BD_DENY = 0;
+
+ bool m_isDecision;
+ PolicyDecision m_decision;
+};
+
+inline static bool operator==(const PolicyDecision &d, const PolicyResult &r) {
+ return r == d;
+}
+
+inline static bool operator!=(const PolicyDecision &d, const PolicyResult &r) {
+ return !(d == r);
+}
+
+inline static bool operator==(const PolicyEffect &e, const PolicyResult &r) {
+ return e == r;
+}
+
+inline static bool operator!=(const PolicyEffect &e, const PolicyResult &r) {
+ return !(e == r);
+}
+
+inline static std::ostream & operator<<(std::ostream& stream,
+ PolicyResult result)
+{
+ return result.toStream(stream);
+}
+
+typedef DPL::Optional<PolicyResult> OptionalPolicyResult;
+
+#endif // _SRC_ACCESS_CONTROL_COMMON_POLICY_RESULT_H_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//
+//
+//
+// @ Project : Access Control Engine
+// @ File Name : PolicySet.h
+// @ Date : 2009-05-06
+// @ Author : Samsung
+//
+//
+
+#if !defined(_POLICYSET_H)
+#define _POLICYSET_H
+
+#include "Policy.h"
+#include <iostream>
+
+class PolicySet : public Policy
+{
+ public:
+
+ //TODO Clean this class
+ //PolicySet(CombineAlgorithm algorithm, std::list<Attribute> * targetAttr,const std::string & subjectId)
+ // : Policy(algorithm,targetAttr,subjectId)
+ // {}
+ PolicySet()
+ {
+ }
+ ~PolicySet()
+ {
+ }
+
+ PolicySet(std::istream& is) : Policy(is)
+ {
+ }
+};
+
+#endif //_POLICYSET_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//
+//
+//
+// @ Project : Access Control Engine
+// @ File Name : Preference.h
+// @ Date : 2009-05-2
+// @ Author : Samsung
+//
+//
+
+#ifndef _Preference_H_
+#define _Preference_H_
+
+#include <map>
+#include <string>
+
+#include <dpl/ace-dao-ro/PreferenceTypes.h>
+
+typedef AceDB::PreferenceTypes Preference;
+typedef AceDB::PreferenceTypesMap PreferenceMap;
+
+#endif //_Preference_H
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 _SRC_ACCESS_CONTROL_COMMON_PROMPT_DECISION_H_
+#define _SRC_ACCESS_CONTROL_COMMON_PROMPT_DECISION_H_
+
+#include <dpl/optional.h>
+#include <dpl/optional_typedefs.h>
+
+enum class PromptDecision {
+ ALLOW_ALWAYS,
+ DENY_ALWAYS,
+ ALLOW_THIS_TIME,
+ DENY_THIS_TIME,
+ ALLOW_FOR_SESSION,
+ DENY_FOR_SESSION
+};
+
+typedef DPL::Optional<PromptDecision> OptionalPromptDecision;
+
+struct CachedPromptDecision {
+ PromptDecision decision;
+ DPL::OptionalString session;
+};
+
+typedef DPL::Optional<CachedPromptDecision> OptionalCachedPromptDecision;
+
+#endif // _SRC_ACCESS_CONTROL_COMMON_PROMPT_DECISION_H_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//
+//
+//
+// @ Project : Access Control Engine
+// @ File Name : Request.h
+// @ Date : 2009-05-06
+// @ Author : Samsung
+//
+//
+
+#ifndef _REQUEST_H_
+#define _REQUEST_H_
+
+#include <set>
+#include <string>
+#include <vector>
+
+#include <dpl/ace-dao-ro/IRequest.h>
+
+#include <dpl/ace/WRT_INTERFACE.h>
+
+class Request : public AceDB::IRequest
+{
+ public:
+ typedef std::string DeviceCapability;
+ typedef std::set<DeviceCapability> DeviceCapabilitySet;
+
+ Request(WidgetHandle widgetHandle,
+ WidgetExecutionPhase phase,
+ IFunctionParam *functionParam = 0)
+ : m_widgetHandle(widgetHandle)
+ , m_phase(phase)
+ , m_functionParam(functionParam)
+ {}
+
+ WidgetHandle getWidgetHandle() const
+ {
+ return m_widgetHandle;
+ }
+
+ WidgetExecutionPhase getExecutionPhase() const
+ {
+ return m_phase;
+ }
+
+ IFunctionParam *getFunctionParam() const
+ {
+ return m_functionParam;
+ }
+
+ void addDeviceCapability(const std::string& device)
+ {
+ m_devcapSet.insert(device);
+ }
+
+ DeviceCapabilitySet getDeviceCapabilitySet() const
+ {
+ return m_devcapSet;
+ }
+
+ private:
+ WidgetHandle m_widgetHandle;
+ WidgetExecutionPhase m_phase;
+ //! \brief list of function param (only for intercept)
+ IFunctionParam *m_functionParam;
+ //! \brief Set of defice capabilities
+ DeviceCapabilitySet m_devcapSet;
+};
+
+typedef std::vector <Request> Requests;
+
+#endif //_REQUEST_H_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//
+//
+//
+// @ Project : Access Control Engine
+// @ File Name : Rule.h
+// @ Date : 2009-05-06
+// @ Author : Samsung
+//
+//
+
+#if !defined(_RULE_H)
+#define _RULE_H
+
+#include "Attribute.h"
+#include "Effect.h"
+#include "Condition.h"
+#include <dpl/assert.h>
+
+class Rule : public AbstractTreeElement
+{
+ public:
+
+ Effect evaluateRule(const AttributeSet * attrSet) const;
+
+ // KW Rule(Effect effect, Condition condition) : effect(effect), condition(condition) {
+ // KW //TODO we should set it to deny or smth, not inapplicable
+ // KW }
+
+ Rule()
+ {
+ //TODO we should set it to deny or smth, not inapplicable
+ this->effect = Inapplicable;
+ }
+
+ // KW Effect getEffect() const {
+ // KW return this->effect;
+ // KW };
+
+ void setEffect(Effect effect)
+ {
+ //We should not allow to set "Inapplicable" effect.
+ //Rules cannot have effect that is inapplicable, evaluation of the rules may however
+ //render the effect inapplicable.
+ Assert(effect != Inapplicable);
+ this->effect = effect;
+ }
+ void setCondition(Condition condition)
+ {
+ this->condition = condition;
+ }
+ void getAttributes(AttributeSet * attrSet)
+ {
+ condition.getAttributes(attrSet);
+ }
+
+ //deserialize
+ Rule(std::istream& is);
+ void serialize(std::ostream& os);
+
+ //DEBUG methods
+ std::string printEffect(const Effect effect) const;
+ void printData();
+
+ private:
+
+ Effect effect;
+ Condition condition;
+};
+
+#endif //_RULE_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#if !defined(_SERIALIZER_H)
+#define _SERIALIZER_H
+
+#include <string>
+#include <iostream>
+#include <fstream>
+
+#include "TreeNode.h"
+#include "Attribute.h"
+#include "Subject.h"
+#include "Policy.h"
+#include "Condition.h"
+
+class Serializer
+{
+ public:
+ static Serializer* getInstance();
+
+ /**** Interaface ****************/
+
+ /**
+ * Serialized tree given by
+ * @param root
+ * */
+ // KW void serializeTree(TreeNode* root);
+
+ /**
+ * deserialize tree
+ * @return pointer to deserialized tree
+ * or NULL if error occur
+ * */
+ // KW TreeNode* deserializeTree();
+
+ /* ------------------------------*/
+
+ void serializeInt(std::ostream& os,
+ const int value);
+ int deserializeInt(std::istream& is);
+
+ void serializeString(std::ostream& os,
+ const std::string& text) const;
+ std::string deserializeString(std::istream& is);
+
+ void serializeListAttributes(std::ostream& os,
+ const std::list<Attribute>& inputList);
+ std::list<Attribute> deserializeListAttributes(std::istream& is);
+
+ void serializeType(std::ostream& os,
+ const Attribute::Type& typeId) const;
+ Attribute::Type deserializeType(std::istream& is);
+
+ void serializeListStrings(std::ostream& os,
+ const std::list<std::string>& inputList) const;
+
+ std::list<std::string> deserializeListStrings(std::istream&is);
+
+ void serializeMatch(std::ostream& os,
+ const Attribute::Match& match) const;
+ Attribute::Match deserializeMatch(std::istream& is);
+ //TODO add smartptr
+ bool serializeModifier(std::ostream& os,
+ const Attribute::Modifier& modifier) const;
+ Attribute::Modifier deserializeModifier(std::istream& is);
+
+ void serializeListTreeNode(std::ostream& os,
+ std::list<TreeNode*>& inputList);
+ std::list<TreeNode* > deserializeListTreeNode(std::istream&is,
+ TreeNode* parent);
+
+ void serializeTypeAbstract(std::ostream& os,
+ const TreeNode::TypeID& typeId);
+ TreeNode::TypeID deserializeTypeAbstract(std::istream& is);
+
+ void serializeAbstractElement(std::ostream& os,
+ AbstractTreeElement* element);
+ AbstractTreeElement* deserializeAbstractElement(std::istream& is,
+ TreeNode::TypeID&);
+
+ void serializeListSubjects(std::ostream& os,
+ std::list<const Subject*>& inputList);
+ std::list<const Subject*>* deserializeListSubjects(std::istream& is);
+
+ void serializeCombineAlgorithm(std::ostream& os,
+ const Policy::CombineAlgorithm & combAlg);
+ Policy::CombineAlgorithm deserializeCombineAlgorithm(std::istream& is);
+
+ void serializeCombineType(std::ostream& os,
+ const Condition::CombineType& combType);
+ Condition::CombineType deserializeCombineType(std::istream& is);
+
+ void serializeListConditions(std::ostream& os,
+ std::list<Condition>& inputList);
+ std::list<Condition> deserializeListConditions(std::istream& is,
+ Condition* parent);
+
+ void serializeEffect(std::ostream& os,
+ Effect effect);
+ Effect deserializeEffect(std::istream& is);
+
+ void serializeCondition(std::ostream& os,
+ Condition& cond);
+ Condition& deserializeCondition(std::istream& is);
+
+ private:
+ Serializer()
+ {
+ }
+ static Serializer* pInstance;
+
+ std::filebuf fileBuffer;
+};
+
+#endif
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ *
+ *
+ * @file SettingsLogic.h
+ * @author Tomasz Swierczek (t.swierczek@samsung.com)
+ * @version 0.1
+ * @brief Header file for class getting/setting user/global ACE settings
+ */
+
+#ifndef WRT_SRC_ACCESS_CONTROL_LOGIC_SETTINGS_LOGIC_H_
+#define WRT_SRC_ACCESS_CONTROL_LOGIC_SETTINGS_LOGIC_H_
+
+#include <set>
+#include <list>
+#include <map>
+#include <string>
+#include <dpl/ace-dao-ro/PreferenceTypes.h>
+#include <dpl/ace/Request.h>
+#include <dpl/ace/PermissionTriple.h>
+#include <dpl/ace-dao-rw/AceDAO.h>
+#include <dpl/ace-dao-ro/wrt_db_types.h>
+
+class SettingsLogic
+{
+ public:
+ class Exception
+ {
+ public:
+ DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+ DECLARE_EXCEPTION_TYPE(Base, DatabaseError)
+ };
+
+ // global settings
+ static AceDB::PreferenceTypes findGlobalUserSettings(
+ const std::string &resource,
+ WidgetHandle handler);
+
+ static AceDB::PreferenceTypes findGlobalUserSettings(
+ const Request &request);
+
+ // resource settings
+ static AceDB::PreferenceTypes getDevCapSetting(
+ const std::string &request);
+ static void getDevCapSettings(AceDB::PreferenceTypesMap *preferences);
+ static void setDevCapSetting(const std::string &resource,
+ AceDB::PreferenceTypes preference);
+ static void setAllDevCapSettings(
+ const std::list<std::pair<const std::string *,
+ AceDB::PreferenceTypes> > &resourcesList);
+ static void removeDevCapSetting(const std::string &resource);
+ static void updateDevCapSetting(const std::string &resource,
+ AceDB::PreferenceTypes p);
+
+ // user settings
+ static AceDB::PreferenceTypes getWidgetDevCapSetting(
+ const std::string &resource,
+ WidgetHandle handler);
+ static void getWidgetDevCapSettings(PermissionList *permissions);
+ static void setWidgetDevCapSetting(const std::string &resource,
+ WidgetHandle handler,
+ AceDB::PreferenceTypes preference);
+ static void setWidgetDevCapSettings(const PermissionList &tripleList);
+ static void removeWidgetDevCapSetting(const std::string &resource,
+ WidgetHandle handler);
+
+ private:
+ SettingsLogic()
+ {
+ }
+
+};
+
+#endif /* WRT_SRC_ACCESS_CONTROL_LOGIC_SETTINGS_LOGIC_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//
+// File: Subject.h
+// Author: notroot
+//
+// Created on June 2, 2009, 8:47 AM
+//
+
+#ifndef _SUBJECT_H
+#define _SUBJECT_H
+
+#include <set>
+#include <list>
+#include <iostream>
+#include <dpl/assert.h>
+#include <dpl/noncopyable.h>
+
+#include "Attribute.h"
+
+class Subject : DPL::Noncopyable
+{
+ std::string subjectId;
+ std::list<Attribute> targetAttributes;
+
+ public:
+ Subject()
+ {}
+
+ //deserialize
+ Subject(std::istream&);
+
+ virtual bool serialize (std::ostream& os);
+
+ const std::list<Attribute>& getTargetAttributes() const;
+
+ void setSubjectId(const std::string & subjectId)
+ {
+ this->subjectId = subjectId;
+ }
+
+ //TODO maybe we should remove that becuase this causes a memory leak right now!! [CR] maybe thats true, maybe whe can remove this fun
+ // KW void setTargetAttributes(std::list<Attribute> * targetAttributes){ this->targetAttributes = targetAttributes; }
+
+ const std::string & getSubjectId() const
+ {
+ return this->subjectId;
+ }
+
+ void addNewAttribute(Attribute & attr)
+ {
+ this->targetAttributes.push_back(attr);
+ }
+
+ //TODO in 1.0 change to true/false/undetermined
+ bool matchSubject(const AttributeSet *attrSet,
+ bool &isUndetermined) const;
+
+ ~Subject()
+ {}
+};
+
+#endif /* _SUBJECT_H */
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef _TEST_TIMER_H
+#define _TEST_TIMER_H
+
+#include <time.h>
+
+class TestTimer
+{
+ time_t startt, endt;
+
+ public:
+ void start()
+ {
+ time(&startt);
+ }
+ void stop()
+ {
+ time(&endt);
+ }
+ double getTime()
+ {
+ return difftime(endt, startt);
+ }
+};
+
+#endif //_TEST_TIMER_H
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//
+//
+//
+// @ Project : Access Control Engine
+// @ File Name : TreeNode.h
+// @ Date : 2009-05-06
+// @ Author : Samsung
+//
+//
+
+#ifndef _TREE_NODE_H
+#define _TREE_NODE_H
+
+#include <iostream>
+#include <list>
+
+#include <dpl/ace/AbstractTreeElement.h>
+
+class TreeNode;
+
+typedef std::list<TreeNode *> ChildrenSet;
+typedef std::list<TreeNode *>::iterator ChildrenIterator;
+typedef std::list<TreeNode *>::const_iterator ChildrenConstIterator;
+
+class TreeNode
+{
+ public:
+ //TODO nazwac pozadnie TYPY - moze jakas konwencja ... ??!!
+ enum TypeID { Policy =0, PolicySet=1, Rule=2};
+
+ virtual bool serialize(std::ostream& os);
+
+ TreeNode(std::istream& is,
+ TreeNode* parent);
+
+ const ChildrenSet & getChildrenSet() const
+ {
+ return children;
+ }
+
+ TreeNode * getParent() const
+ {
+ return this->parent;
+ }
+
+ void setParent(TreeNode *parent)
+ {
+ this->parent = parent;
+ }
+
+ TypeID getTypeID() const
+ {
+ return this->typeID;
+ }
+
+ void addChild(TreeNode *child)
+ {
+ child->setParent(this);
+ children.push_back(child);
+ }
+
+ /**
+ * Clone the node
+ */
+ // KW TreeNode * clone() { return new TreeNode(NULL,this->getTypeID(),this->getElement()); }
+
+ TreeNode(TreeNode * parent,
+ TypeID type,
+ AbstractTreeElement * element) :
+ parent(parent),
+ typeID(type),
+ element(element)
+ {
+ }
+
+ AbstractTreeElement * getElement() const
+ {
+ return element;
+ }
+
+ private:
+ virtual ~TreeNode();
+
+ public:
+ /*
+ * It is common that we create a copy of tree structure created out of xml file. However we don't want to
+ * copy abstract elements ( Policies and Rules ) because we need them only for reading. We want to modify the
+ * tree structure though. Therefore we copy TreeNode. When the copy of the original tree is being destroyed method
+ * releaseTheSubtree should be called on "root". It automatically traverse the tree and call TreeNode destructors for
+ * each TreeNode in the tree. It doesn't remove the abstract elements in the tree ( there is always at most one abstract
+ * element instance, when tree is copied it is a shallow copy.
+ * When we want to completely get rid of the the tree and abstract elements we have to call releaseResources on tree root.
+ * We may want to do this for instance when we want to serialize the tree to disc. releaseResource method traverses the tree
+ * and releses the resources, as well as the TreeNode so NO releaseTheSubtree is required any more
+ */
+ void releaseResources();
+
+ /**
+ * Used to delete the copies of tree structure. The original tree structure should be removed with releaseResources method.
+ * ReleaseTheSubtree method doesn't delete the abstract elements, only TreeNodes. It traverses the whole tree, so it should be
+ * called on behalf of root of the tree
+ */
+ // KW void releaseTheSubtree();
+
+ friend std::ostream & operator<<(std::ostream & out,
+ const TreeNode * node);
+ // KW void printSubtree();
+
+ private:
+ // KW TreeNode(const TreeNode& pattern){ (void)pattern; }
+
+ std::list<TreeNode *> children;
+ TreeNode * parent;
+ //TODO standarize ID case
+ TypeID typeID;
+ AbstractTreeElement * element;
+ static int level;
+};
+
+#endif //_TREE_NODE_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//
+//
+//
+// @ Project : Access Control Engine
+// @ File Name : UserDecision.h
+// @ Date : 2009-05-22
+// @ Author : Samsung
+//
+//
+
+#ifndef _USERDECISION_H
+#define _USERDECISION_H
+
+#include <dpl/ace/Verdict.h>
+#include <dpl/ace-dao-ro/ValidityTypes.h>
+
+typedef AceDB::ValidityTypes Validity;
+
+const char * toString(Validity validity);
+
+#endif //_USERDECISION_H
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//
+//
+//
+// @ Project : Access Control Engine
+// @ File Name : Verdict.h
+// @ Date : 2009-05-2
+// @ Author : Samsung
+//
+//
+
+#ifndef _VERDICT_H
+#define _VERDICT_H
+
+#include <string>
+#include <dpl/ace-dao-ro/VerdictTypes.h>
+#include <dpl/ace-dao-ro/TimedVerdict.h>
+
+typedef AceDB::VerdictTypes Verdict;
+//typedef AceDB::TimedVerdict TimedVerdict;
+
+const char * toString(Verdict verditct);
+
+#endif //_VERDICT_H
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_INERFACE_4_ACE_EXAMPLE_H_
+#define _WRT_INERFACE_4_ACE_EXAMPLE_H_
+
+#include <list>
+#include <map>
+#include <string>
+
+#include <dpl/ace-dao-ro/wrt_db_types.h>
+
+class Request;
+
+enum WidgetExecutionPhase
+{
+ WidgetExecutionPhase_Unknown = 0,
+ WidgetExecutionPhase_WidgetInstall = 1 << 0,
+ WidgetExecutionPhase_WidgetInstantiate = 1 << 1,
+ WidgetExecutionPhase_WebkitBind = 1 << 2,
+ WidgetExecutionPhase_Invoke = 1 << 3
+};
+
+struct RequestContext
+{
+ const WidgetHandle Handle;
+ WidgetExecutionPhase Phase;
+
+ RequestContext(WidgetHandle handle,
+ WidgetExecutionPhase phase) :
+ Handle(handle),
+ Phase(phase)
+ {
+ }
+};
+
+// Pair of pointer to attribute name and pointer to list of value for
+// this attribute name
+typedef std::pair< const std::string* const, std::list<std::string>* >
+ATTRIBUTE;
+
+/*
+ * Each function should return 0 as success and positive value as error
+ *
+ * Possible return value:
+ * 0 - succes
+ * 1 - subjectId/resourceId name unknown
+ * 2 - unknown attribute name
+ * 4 - interface error
+ **/
+
+/************** Web Runtime ********************/
+
+class IWebRuntime
+{
+ public:
+
+ /**
+ * gather and set attributes values for specified subjectId
+ * and attribute name
+ * @param subjectId is a name of subject (widget or internet site URI )
+ * @param attributes is a list of pairs(
+ * first: pointer to attribute name
+ * second: list of values for attribute (std::string) -
+ * its a list of string (BONDI requirement), but usually there will
+ * be only one string
+ * */
+ virtual int getAttributesValues(const Request &request,
+ std::list<ATTRIBUTE> *attributes) = 0;
+
+ /*return current sessionId */
+ virtual std::string getSessionId(const Request &request) = 0;
+
+ virtual ~IWebRuntime()
+ {
+ }
+};
+
+/************** Resource Information ********************/
+class IResourceInformation
+{
+ public:
+ /**
+ * gather and set attributes values for specified resourceId
+ * and attribute name
+ * @param resourceId is a name of subject (widget or internet site URI )
+ * @param attributes is a list of pairs(
+ * first: pointer to attribute name
+ * second: list of values for attribute (std::string) -
+ * its a list of string (BONDI requirement), but usually there will
+ * be only one string
+ * */
+ virtual int getAttributesValues(const Request &request,
+ std::list<ATTRIBUTE> *attributes) = 0;
+
+ virtual ~IResourceInformation()
+ {
+ }
+};
+
+/************** Operation System ********************/
+class IOperationSystem
+{
+ public:
+
+ /**
+ * gather and set attributes values for specified attribute name
+ * @param attributes is a list of pairs(
+ * first: pointer to attribute name
+ * second: list of values for attribute (std::string) -
+ * its a list of string (BONDI requirement), but usually
+ * there will be only one string
+ * */
+ virtual int getAttributesValues(const Request &request,
+ std::list<ATTRIBUTE> *attributes) = 0;
+
+ virtual ~IOperationSystem()
+ {
+ }
+};
+
+class IFunctionParam
+{
+ public:
+ virtual int getAttributesValues(const Request &request,
+ std::list<ATTRIBUTE> *attributes) = 0;
+ virtual ~IFunctionParam()
+ {
+ }
+};
+
+#endif //_WRT_INERFACE_4_ACE_EXAMPLE_H_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//
+// @ Project : Access Control Engine
+// @ File Name : UserDecision.h
+// @ Date : 2009-05-22
+// @ Author : Samsung
+//
+//
+
+#ifndef _WIDGET_USAGE_H
+#define _WIDGET_USAGE_H
+
+#include <dpl/event/event_support.h>
+
+#include "Request.h"
+#include "AsyncVerdictResultListener.h"
+
+enum UsageValidity
+{
+ USAGE_UNKNOWN,
+ USAGE_ONCE,
+ USAGE_SESSION,
+ USAGE_ALWAYS
+};
+
+enum UsageVerdict
+{
+ USAGE_VERDICT_PERMIT,
+ USAGE_VERDICT_DENY,
+ USAGE_VERDICT_INAPPLICABLE,
+ USAGE_VERDICT_UNDETERMINED,
+ USAGE_VERDICT_UNKNOWN,
+ USAGE_VERDICT_ERROR
+};
+//Forward declaration
+class PolicyEvaluator;
+
+class PolicyEvaluatorData
+{
+ private:
+ Request m_request;
+ UsageValidity m_validity;
+ UsageVerdict m_verdict;
+ AsyncVerdictResultListener *m_listener;
+ public:
+
+ PolicyEvaluatorData(const Request& request,
+ AsyncVerdictResultListener *listener) :
+ m_request(request),
+ m_validity(USAGE_UNKNOWN),
+ m_verdict(USAGE_VERDICT_ERROR),
+ m_listener(listener)
+ {
+ }
+
+ // KW UsageValidity getValidity() const {
+ // KW return m_validity;
+ // KW }
+ // KW
+ // KW UsageVerdict getVerdict() const {
+ // KW return m_verdict;
+ // KW }
+ // KW
+ // KW void setValidity(UsageValidity validity) {
+ // KW this->m_validity = validity;
+ // KW }
+ // KW
+ // KW void setVerdict(UsageVerdict verdict) {
+ // KW this->m_verdict = verdict;
+ // KW }
+
+ const Request& getRequest() const
+ {
+ return m_request;
+ }
+
+ AsyncVerdictResultListener* getListener() const
+ {
+ return m_listener;
+ }
+};
+
+#endif //_USERDECISION_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 contain consts for Signing Template and Policy Manager
+ * This values will be used to specified and identified algorithms in xml policy documents.
+ * Its consistent with BONDI 1.0 released requirements
+ *
+ * NOTE: This values should be verified when ACF will be updated to the latest version of BONDI requirements
+ * This values comes from widget digital signature 1.0 - required version of this doc is very important
+ *
+ **/
+
+#ifndef ACF_CONSTS_TYPES_H
+#define ACF_CONSTS_TYPES_H
+
+//Digest Algorithms
+extern const char* DIGEST_ALG_SHA256;
+
+//Canonicalization Algorithms
+extern const char* CANONICAL_ALG_C14N;
+
+//Signature Algorithms
+extern const char* SIGNATURE_ALG_RSA_with_SHA256;
+extern const char* SIGNATURE_ALG_DSA_with_SHA1;
+extern const char* SIGNATURE_ALG_ECDSA_with_SHA256;
+
+#endif
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//
+//
+//
+// @ Project : Access Control Engine
+// @ File Name : parser.h
+// @ Date : 2009-05-06
+// @ Author : Samsung
+//
+//
+
+#ifndef _PARSER_H_
+#define _PARSER_H_
+
+//#include "/usr/include/libxml2/libxml/parser.h"
+#include <string>
+#include <libxml/xmlreader.h>
+#include <libxml/c14n.h>
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+
+#include "Policy.h"
+#include "PolicySet.h"
+#include "Request.h"
+#include "Rule.h"
+#include "Attribute.h"
+#include "TreeNode.h"
+#include "Subject.h"
+#include "Condition.h"
+
+#define whitespaces " \n\t\r"
+
+enum CanonicalizationAlgorithm
+{
+ C14N,
+ C14NEXCLUSIVE
+};
+
+class Parser
+{
+ private:
+
+ xmlTextReaderPtr reader;
+
+ TreeNode * root;
+ TreeNode * currentRoot;
+ Subject * currentSubject;
+ Condition * currentCondition;
+ Attribute * currentAttribute;
+ std::string * currentText;
+
+ bool processingSignature;
+ bool canonicalizeOnce;
+
+ void processNode(xmlTextReaderPtr reader);
+
+ //Node Handlers
+ void endNodeHandler(xmlTextReaderPtr reader);
+ void textNodeHandler(xmlTextReaderPtr reader);
+ void startNodeHandler(xmlTextReaderPtr reader);
+
+ //Node names handlers
+ void handleAttr(xmlTextReaderPtr reader);
+ void handleRule(xmlTextReaderPtr reader);
+ void handleSubject();
+ void handleCondition(xmlTextReaderPtr reader);
+ void handleSubjectMatch(xmlTextReaderPtr reader);
+ void handleMatch(xmlTextReaderPtr reader,
+ Attribute::Type);
+ void handlePolicy(xmlTextReaderPtr reader,
+ TreeNode::TypeID type);
+
+ //helpers
+ Policy::CombineAlgorithm convertToCombineAlgorithm(xmlChar*);
+ Effect convertToEffect(xmlChar *effect);
+ Attribute::Match convertToMatchFunction(xmlChar * func);
+ void consumeCurrentText();
+ void consumeCurrentAttribute();
+ void consumeSubjectMatch(xmlChar * value = NULL);
+ void consumeCurrentSubject();
+ void consumeCurrentCondition();
+ void trim(std::string *);
+ // KW void canonicalize(const char *, const char *, CanonicalizationAlgorithm canonicalizationAlgorithm);
+ // KW int extractNodeToFile(xmlTextReaderPtr reader, const char * filename);
+
+ static const char *TOKEN_PARAM;
+ public:
+ Parser();
+ ~Parser();
+ TreeNode * parse(const std::string& filename, const std::string& schema);
+};
+
+#endif //_PARSER_H
--- /dev/null
+SQL(
+ PRAGMA foreign_keys = ON;
+ BEGIN TRANSACTION;
+)
+
+CREATE_TABLE(AcePolicyResult)
+ COLUMN_NOT_NULL(decision, INTEGER, check(decision between 0 and 6))
+ COLUMN_NOT_NULL(hash, TEXT,)
+ TABLE_CONSTRAINTS(
+ PRIMARY KEY(hash)
+ )
+CREATE_TABLE_END()
+
+CREATE_TABLE(AcePromptDecision)
+ COLUMN_NOT_NULL(user_param, TEXT,)
+ COLUMN_NOT_NULL(decision, INTEGER, check(decision between 0 and 5))
+ COLUMN(session, TEXT,)
+ COLUMN_NOT_NULL(hash, TEXT,)
+ TABLE_CONSTRAINTS(
+ PRIMARY KEY(hash,user_param)
+ )
+CREATE_TABLE_END()
+
+CREATE_TABLE(AceAttribute)
+ COLUMN_NOT_NULL(attr_id, INTEGER, primary key autoincrement)
+ COLUMN_NOT_NULL(name, TEXT,)
+ COLUMN_NOT_NULL(type, INTEGER, check(type between 0 and 3))
+
+ TABLE_CONSTRAINTS(unique(name,type))
+CREATE_TABLE_END()
+
+CREATE_TABLE(AceSubject)
+ COLUMN_NOT_NULL(subject_id, INTEGER, primary key autoincrement)
+ COLUMN_NOT_NULL(id_uri, TEXT, unique)
+CREATE_TABLE_END()
+
+CREATE_TABLE(AceDevCap)
+ COLUMN_NOT_NULL(resource_id, INTEGER, primary key autoincrement)
+ COLUMN_NOT_NULL(id_uri, TEXT, unique)
+ COLUMN_NOT_NULL(general_setting,INTEGER, check(general_setting between -1 and 4))
+CREATE_TABLE_END()
+
+CREATE_TABLE(AceWidgetDevCapSetting)
+ COLUMN_NOT_NULL(app_id, INTEGER, not null)
+ COLUMN_NOT_NULL(resource_id, INTEGER, references AceDevCap(resource_id))
+ COLUMN_NOT_NULL(access_value, INTEGER, check(access_value between -1 and 4))
+
+ TABLE_CONSTRAINTS(unique(app_id,resource_id))
+CREATE_TABLE_END()
+
+CREATE_TABLE(AceStaticDevCapPermission)
+ COLUMN_NOT_NULL(app_id, INTEGER, not null)
+ COLUMN_NOT_NULL(dev_cap, TEXT,)
+
+ TABLE_CONSTRAINTS(unique(app_id,dev_cap))
+CREATE_TABLE_END()
+
+SQL(
+ COMMIT;
+)
--- /dev/null
+DATABASE_START(ace)
+
+#include "ace_db"
+#include "version_db"
+
+DATABASE_END()
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "ace_db_definitions"
--- /dev/null
+#!/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}
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_ACE_H
+#define ORM_GENERATOR_ACE_H
+
+#define ORM_GENERATOR_DATABASE_NAME ace_db_definitions
+#include <dpl/db/orm_generator.h>
+#undef ORM_GENERATOR_DATABASE_NAME
+
+#endif
--- /dev/null
+SQL(
+ BEGIN TRANSACTION;
+ CREATE TABLE DB_CHECKSUM (version INT);
+ COMMIT;
+)
--- /dev/null
+Main library code
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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/fast_delegate.cpp
+ ${PROJECT_SOURCE_DIR}/modules/core/src/file_input.cpp
+ ${PROJECT_SOURCE_DIR}/modules/core/src/file_input_mapping.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/mutex.cpp
+ ${PROJECT_SOURCE_DIR}/modules/core/src/named_base_pipe.cpp
+ ${PROJECT_SOURCE_DIR}/modules/core/src/named_input_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/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/task_list.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/binary_queue.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/fast_delegate.h
+ ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/file_input.h
+ ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/file_input_mapping.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/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/noreturn.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/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/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_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/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/task_list.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/unused.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
+)
+
+SET(DPL_3RDPARTY_HEADERS
+ ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/3rdparty/fastdelegate/FastDelegate.h
+ ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/3rdparty/fastdelegate/FastDelegateBind.h
+ PARENT_SCOPE
+)
+
--- /dev/null
+!!!options!!! stop
+Header files, including template implementations
--- /dev/null
+// FastDelegate.h \r
+// Efficient delegates in C++ that generate only two lines of asm code!\r
+// Documentation is found at http://www.codeproject.com/cpp/FastDelegate.asp\r
+//\r
+// - Don Clugston, Mar 2004.\r
+// Major contributions were made by Jody Hagins.\r
+// History:\r
+// 24-Apr-04 1.0 * Submitted to CodeProject. \r
+// 28-Apr-04 1.1 * Prevent most unsafe uses of evil static function hack.\r
+// * Improved syntax for horrible_cast (thanks Paul Bludov).\r
+// * Tested on Metrowerks MWCC and Intel ICL (IA32)\r
+// * Compiled, but not run, on Comeau C++ and Intel Itanium ICL.\r
+// 27-Jun-04 1.2 * Now works on Borland C++ Builder 5.5\r
+// * Now works on /clr "managed C++" code on VC7, VC7.1\r
+// * Comeau C++ now compiles without warnings.\r
+// * Prevent the virtual inheritance case from being used on \r
+// VC6 and earlier, which generate incorrect code.\r
+// * Improved warning and error messages. Non-standard hacks\r
+// now have compile-time checks to make them safer.\r
+// * implicit_cast used instead of static_cast in many cases.\r
+// * If calling a const member function, a const class pointer can be used.\r
+// * MakeDelegate() global helper function added to simplify pass-by-value.\r
+// * Added fastdelegate.clear()\r
+// 16-Jul-04 1.2.1* Workaround for gcc bug (const member function pointers in templates)\r
+// 30-Oct-04 1.3 * Support for (non-void) return values.\r
+// * No more workarounds in client code!\r
+// MSVC and Intel now use a clever hack invented by John Dlugosz:\r
+// - The FASTDELEGATEDECLARE workaround is no longer necessary.\r
+// - No more warning messages for VC6\r
+// * Less use of macros. Error messages should be more comprehensible.\r
+// * Added include guards\r
+// * Added FastDelegate::empty() to test if invocation is safe (Thanks Neville Franks).\r
+// * Now tested on VS 2005 Express Beta, PGI C++\r
+// 24-Dec-04 1.4 * Added DelegateMemento, to allow collections of disparate delegates.\r
+// * <,>,<=,>= comparison operators to allow storage in ordered containers.\r
+// * Substantial reduction of code size, especially the 'Closure' class.\r
+// * Standardised all the compiler-specific workarounds.\r
+// * MFP conversion now works for CodePlay (but not yet supported in the full code).\r
+// * Now compiles without warnings on _any_ supported compiler, including BCC 5.5.1\r
+// * New syntax: FastDelegate< int (char *, double) >. \r
+// 14-Feb-05 1.4.1* Now treats =0 as equivalent to .clear(), ==0 as equivalent to .empty(). (Thanks elfric).\r
+// * Now tested on Intel ICL for AMD64, VS2005 Beta for AMD64 and Itanium.\r
+// 30-Mar-05 1.5 * Safebool idiom: "if (dg)" is now equivalent to "if (!dg.empty())"\r
+// * Fully supported by CodePlay VectorC\r
+// * Bugfix for Metrowerks: empty() was buggy because a valid MFP can be 0 on MWCC!\r
+// * More optimal assignment,== and != operators for static function pointers.\r
+\r
+#ifndef FASTDELEGATE_H\r
+#define FASTDELEGATE_H\r
+#if _MSC_VER > 1000\r
+#pragma once\r
+#endif // _MSC_VER > 1000\r
+\r
+#include <memory.h> // to allow <,> comparisons\r
+\r
+////////////////////////////////////////////////////////////////////////////////\r
+// Configuration options\r
+//\r
+////////////////////////////////////////////////////////////////////////////////\r
+\r
+// Uncomment the following #define for optimally-sized delegates.\r
+// In this case, the generated asm code is almost identical to the code you'd get\r
+// if the compiler had native support for delegates.\r
+// It will not work on systems where sizeof(dataptr) < sizeof(codeptr). \r
+// Thus, it will not work for DOS compilers using the medium model.\r
+// It will also probably fail on some DSP systems.\r
+#define FASTDELEGATE_USESTATICFUNCTIONHACK\r
+\r
+// Uncomment the next line to allow function declarator syntax.\r
+// It is automatically enabled for those compilers where it is known to work.\r
+//#define FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX\r
+\r
+////////////////////////////////////////////////////////////////////////////////\r
+// Compiler identification for workarounds\r
+//\r
+////////////////////////////////////////////////////////////////////////////////\r
+\r
+// Compiler identification. It's not easy to identify Visual C++ because\r
+// many vendors fraudulently define Microsoft's identifiers.\r
+#if defined(_MSC_VER) && !defined(__MWERKS__) && !defined(__VECTOR_C) && !defined(__ICL) && !defined(__BORLANDC__)\r
+#define FASTDLGT_ISMSVC\r
+\r
+#if (_MSC_VER <1300) // Many workarounds are required for VC6.\r
+#define FASTDLGT_VC6\r
+#pragma warning(disable:4786) // disable this ridiculous warning\r
+#endif\r
+\r
+#endif\r
+\r
+// Does the compiler uses Microsoft's member function pointer structure?\r
+// If so, it needs special treatment.\r
+// Metrowerks CodeWarrior, Intel, and CodePlay fraudulently define Microsoft's \r
+// identifier, _MSC_VER. We need to filter Metrowerks out.\r
+#if defined(_MSC_VER) && !defined(__MWERKS__)\r
+#define FASTDLGT_MICROSOFT_MFP\r
+\r
+#if !defined(__VECTOR_C)\r
+// CodePlay doesn't have the __single/multi/virtual_inheritance keywords\r
+#define FASTDLGT_HASINHERITANCE_KEYWORDS\r
+#endif\r
+#endif\r
+\r
+// Does it allow function declarator syntax? The following compilers are known to work:\r
+#if defined(FASTDLGT_ISMSVC) && (_MSC_VER >=1310) // VC 7.1\r
+#define FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX\r
+#endif\r
+\r
+// Gcc(2.95+), and versions of Digital Mars, Intel and Comeau in common use.\r
+#if defined (__DMC__) || defined(__GNUC__) || defined(__ICL) || defined(__COMO__)\r
+#define FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX\r
+#endif\r
+\r
+// It works on Metrowerks MWCC 3.2.2. From boost.Config it should work on earlier ones too.\r
+#if defined (__MWERKS__)\r
+#define FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX\r
+#endif\r
+\r
+#ifdef __GNUC__ // Workaround GCC bug #8271 \r
+ // At present, GCC doesn't recognize constness of MFPs in templates\r
+#define FASTDELEGATE_GCC_BUG_8271\r
+#endif\r
+\r
+\r
+\r
+////////////////////////////////////////////////////////////////////////////////\r
+// General tricks used in this code\r
+//\r
+// (a) Error messages are generated by typdefing an array of negative size to\r
+// generate compile-time errors.\r
+// (b) Warning messages on MSVC are generated by declaring unused variables, and\r
+// enabling the "variable XXX is never used" warning.\r
+// (c) Unions are used in a few compiler-specific cases to perform illegal casts.\r
+// (d) For Microsoft and Intel, when adjusting the 'this' pointer, it's cast to\r
+// (char *) first to ensure that the correct number of *bytes* are added.\r
+//\r
+////////////////////////////////////////////////////////////////////////////////\r
+// Helper templates\r
+//\r
+////////////////////////////////////////////////////////////////////////////////\r
+\r
+\r
+namespace fastdelegate {\r
+namespace detail { // we'll hide the implementation details in a nested namespace.\r
+\r
+// implicit_cast< >\r
+// I believe this was originally going to be in the C++ standard but \r
+// was left out by accident. It's even milder than static_cast.\r
+// I use it instead of static_cast<> to emphasize that I'm not doing\r
+// anything nasty. \r
+// Usage is identical to static_cast<>\r
+template <class OutputClass, class InputClass>\r
+inline OutputClass implicit_cast(InputClass input){\r
+ return input;\r
+}\r
+\r
+// horrible_cast< >\r
+// This is truly evil. It completely subverts C++'s type system, allowing you \r
+// to cast from any class to any other class. Technically, using a union \r
+// to perform the cast is undefined behaviour (even in C). But we can see if\r
+// it is OK by checking that the union is the same size as each of its members.\r
+// horrible_cast<> should only be used for compiler-specific workarounds. \r
+// Usage is identical to reinterpret_cast<>.\r
+\r
+// This union is declared outside the horrible_cast because BCC 5.5.1\r
+// can't inline a function with a nested class, and gives a warning.\r
+template <class OutputClass, class InputClass>\r
+union horrible_union{\r
+ OutputClass out;\r
+ InputClass in;\r
+};\r
+\r
+template <class OutputClass, class InputClass>\r
+inline OutputClass horrible_cast(const InputClass input){\r
+ horrible_union<OutputClass, InputClass> u;\r
+ // Cause a compile-time error if in, out and u are not the same size.\r
+ // If the compile fails here, it means the compiler has peculiar\r
+ // unions which would prevent the cast from working.\r
+ typedef int ERROR_CantUseHorrible_cast[sizeof(InputClass)==sizeof(u) \r
+ && sizeof(InputClass)==sizeof(OutputClass) ? 1 : -1];\r
+ u.in = input;\r
+ return u.out;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////////////\r
+// Workarounds\r
+//\r
+////////////////////////////////////////////////////////////////////////////////\r
+\r
+// Backwards compatibility: This macro used to be necessary in the virtual inheritance\r
+// case for Intel and Microsoft. Now it just forward-declares the class.\r
+#define FASTDELEGATEDECLARE(CLASSNAME) class CLASSNAME;\r
+\r
+// Prevent use of the static function hack with the DOS medium model.\r
+#ifdef __MEDIUM__\r
+#undef FASTDELEGATE_USESTATICFUNCTIONHACK\r
+#endif\r
+\r
+// DefaultVoid - a workaround for 'void' templates in VC6.\r
+//\r
+// (1) VC6 and earlier do not allow 'void' as a default template argument.\r
+// (2) They also doesn't allow you to return 'void' from a function.\r
+//\r
+// Workaround for (1): Declare a dummy type 'DefaultVoid' which we use\r
+// when we'd like to use 'void'. We convert it into 'void' and back\r
+// using the templates DefaultVoidToVoid<> and VoidToDefaultVoid<>.\r
+// Workaround for (2): On VC6, the code for calling a void function is\r
+// identical to the code for calling a non-void function in which the\r
+// return value is never used, provided the return value is returned\r
+// in the EAX register, rather than on the stack. \r
+// This is true for most fundamental types such as int, enum, void *.\r
+// Const void * is the safest option since it doesn't participate \r
+// in any automatic conversions. But on a 16-bit compiler it might\r
+// cause extra code to be generated, so we disable it for all compilers\r
+// except for VC6 (and VC5).\r
+#ifdef FASTDLGT_VC6\r
+// VC6 workaround\r
+typedef const void * DefaultVoid;\r
+#else\r
+// On any other compiler, just use a normal void.\r
+typedef void DefaultVoid;\r
+#endif\r
+\r
+// Translate from 'DefaultVoid' to 'void'.\r
+// Everything else is unchanged\r
+template <class T>\r
+struct DefaultVoidToVoid { typedef T type; };\r
+\r
+template <>\r
+struct DefaultVoidToVoid<DefaultVoid> { typedef void type; };\r
+\r
+// Translate from 'void' into 'DefaultVoid'\r
+// Everything else is unchanged\r
+template <class T>\r
+struct VoidToDefaultVoid { typedef T type; };\r
+\r
+template <>\r
+struct VoidToDefaultVoid<void> { typedef DefaultVoid type; };\r
+\r
+\r
+\r
+////////////////////////////////////////////////////////////////////////////////\r
+// Fast Delegates, part 1:\r
+//\r
+// Conversion of member function pointer to a standard form\r
+//\r
+////////////////////////////////////////////////////////////////////////////////\r
+\r
+// GenericClass is a fake class, ONLY used to provide a type.\r
+// It is vitally important that it is never defined, so that the compiler doesn't\r
+// think it can optimize the invocation. For example, Borland generates simpler\r
+// code if it knows the class only uses single inheritance.\r
+\r
+// Compilers using Microsoft's structure need to be treated as a special case.\r
+#ifdef FASTDLGT_MICROSOFT_MFP\r
+\r
+#ifdef FASTDLGT_HASINHERITANCE_KEYWORDS\r
+ // For Microsoft and Intel, we want to ensure that it's the most efficient type of MFP \r
+ // (4 bytes), even when the /vmg option is used. Declaring an empty class \r
+ // would give 16 byte pointers in this case....\r
+ class __single_inheritance GenericClass;\r
+#endif\r
+ // ...but for Codeplay, an empty class *always* gives 4 byte pointers.\r
+ // If compiled with the /clr option ("managed C++"), the JIT compiler thinks\r
+ // it needs to load GenericClass before it can call any of its functions,\r
+ // (compiles OK but crashes at runtime!), so we need to declare an \r
+ // empty class to make it happy.\r
+ // Codeplay and VC4 can't cope with the unknown_inheritance case either.\r
+ class GenericClass {};\r
+#else\r
+ class GenericClass;\r
+#endif\r
+\r
+// The size of a single inheritance member function pointer.\r
+const int SINGLE_MEMFUNCPTR_SIZE = sizeof(void (GenericClass::*)());\r
+\r
+// SimplifyMemFunc< >::Convert()\r
+//\r
+// A template function that converts an arbitrary member function pointer into the \r
+// simplest possible form of member function pointer, using a supplied 'this' pointer.\r
+// According to the standard, this can be done legally with reinterpret_cast<>.\r
+// For (non-standard) compilers which use member function pointers which vary in size \r
+// depending on the class, we need to use knowledge of the internal structure of a \r
+// member function pointer, as used by the compiler. Template specialization is used\r
+// to distinguish between the sizes. Because some compilers don't support partial \r
+// template specialisation, I use full specialisation of a wrapper struct.\r
+\r
+// general case -- don't know how to convert it. Force a compile failure\r
+template <int N>\r
+struct SimplifyMemFunc {\r
+ template <class X, class XFuncType, class GenericMemFuncType>\r
+ inline static GenericClass *Convert(X *pthis, XFuncType function_to_bind, \r
+ GenericMemFuncType &bound_func) { \r
+ // Unsupported member function type -- force a compile failure.\r
+ // (it's illegal to have a array with negative size).\r
+ typedef char ERROR_Unsupported_member_function_pointer_on_this_compiler[N-100];\r
+ return 0; \r
+ }\r
+};\r
+\r
+// For compilers where all member func ptrs are the same size, everything goes here.\r
+// For non-standard compilers, only single_inheritance classes go here.\r
+template <>\r
+struct SimplifyMemFunc<SINGLE_MEMFUNCPTR_SIZE> { \r
+ template <class X, class XFuncType, class GenericMemFuncType>\r
+ inline static GenericClass *Convert(X *pthis, XFuncType function_to_bind, \r
+ GenericMemFuncType &bound_func) {\r
+#if defined __DMC__ \r
+ // Digital Mars doesn't allow you to cast between abitrary PMF's, \r
+ // even though the standard says you can. The 32-bit compiler lets you\r
+ // static_cast through an int, but the DOS compiler doesn't.\r
+ bound_func = horrible_cast<GenericMemFuncType>(function_to_bind);\r
+#else \r
+ bound_func = reinterpret_cast<GenericMemFuncType>(function_to_bind);\r
+#endif\r
+ return reinterpret_cast<GenericClass *>(pthis);\r
+ }\r
+};\r
+\r
+////////////////////////////////////////////////////////////////////////////////\r
+// Fast Delegates, part 1b:\r
+//\r
+// Workarounds for Microsoft and Intel\r
+//\r
+////////////////////////////////////////////////////////////////////////////////\r
+\r
+\r
+// Compilers with member function pointers which violate the standard (MSVC, Intel, Codeplay),\r
+// need to be treated as a special case.\r
+#ifdef FASTDLGT_MICROSOFT_MFP\r
+\r
+// We use unions to perform horrible_casts. I would like to use #pragma pack(push, 1)\r
+// at the start of each function for extra safety, but VC6 seems to ICE\r
+// intermittently if you do this inside a template.\r
+\r
+// __multiple_inheritance classes go here\r
+// Nasty hack for Microsoft and Intel (IA32 and Itanium)\r
+template<>\r
+struct SimplifyMemFunc< SINGLE_MEMFUNCPTR_SIZE + sizeof(int) > {\r
+ template <class X, class XFuncType, class GenericMemFuncType>\r
+ inline static GenericClass *Convert(X *pthis, XFuncType function_to_bind, \r
+ GenericMemFuncType &bound_func) { \r
+ // We need to use a horrible_cast to do this conversion.\r
+ // In MSVC, a multiple inheritance member pointer is internally defined as:\r
+ union {\r
+ XFuncType func;\r
+ struct { \r
+ GenericMemFuncType funcaddress; // points to the actual member function\r
+ int delta; // #BYTES to be added to the 'this' pointer\r
+ }s;\r
+ } u;\r
+ // Check that the horrible_cast will work\r
+ typedef int ERROR_CantUsehorrible_cast[sizeof(function_to_bind)==sizeof(u.s)? 1 : -1];\r
+ u.func = function_to_bind;\r
+ bound_func = u.s.funcaddress;\r
+ return reinterpret_cast<GenericClass *>(reinterpret_cast<char *>(pthis) + u.s.delta); \r
+ }\r
+};\r
+\r
+// virtual inheritance is a real nuisance. It's inefficient and complicated.\r
+// On MSVC and Intel, there isn't enough information in the pointer itself to\r
+// enable conversion to a closure pointer. Earlier versions of this code didn't\r
+// work for all cases, and generated a compile-time error instead.\r
+// But a very clever hack invented by John M. Dlugosz solves this problem.\r
+// My code is somewhat different to his: I have no asm code, and I make no \r
+// assumptions about the calling convention that is used.\r
+\r
+// In VC++ and ICL, a virtual_inheritance member pointer \r
+// is internally defined as:\r
+struct MicrosoftVirtualMFP {\r
+ void (GenericClass::*codeptr)(); // points to the actual member function\r
+ int delta; // #bytes to be added to the 'this' pointer\r
+ int vtable_index; // or 0 if no virtual inheritance\r
+};\r
+// The CRUCIAL feature of Microsoft/Intel MFPs which we exploit is that the\r
+// m_codeptr member is *always* called, regardless of the values of the other\r
+// members. (This is *not* true for other compilers, eg GCC, which obtain the\r
+// function address from the vtable if a virtual function is being called).\r
+// Dlugosz's trick is to make the codeptr point to a probe function which\r
+// returns the 'this' pointer that was used.\r
+\r
+// Define a generic class that uses virtual inheritance.\r
+// It has a trival member function that returns the value of the 'this' pointer.\r
+struct GenericVirtualClass : virtual public GenericClass\r
+{\r
+ typedef GenericVirtualClass * (GenericVirtualClass::*ProbePtrType)();\r
+ GenericVirtualClass * GetThis() { return this; }\r
+};\r
+\r
+// __virtual_inheritance classes go here\r
+template <>\r
+struct SimplifyMemFunc<SINGLE_MEMFUNCPTR_SIZE + 2*sizeof(int) >\r
+{\r
+\r
+ template <class X, class XFuncType, class GenericMemFuncType>\r
+ inline static GenericClass *Convert(X *pthis, XFuncType function_to_bind, \r
+ GenericMemFuncType &bound_func) {\r
+ union {\r
+ XFuncType func;\r
+ GenericClass* (X::*ProbeFunc)();\r
+ MicrosoftVirtualMFP s;\r
+ } u;\r
+ u.func = function_to_bind;\r
+ bound_func = reinterpret_cast<GenericMemFuncType>(u.s.codeptr);\r
+ union {\r
+ GenericVirtualClass::ProbePtrType virtfunc;\r
+ MicrosoftVirtualMFP s;\r
+ } u2;\r
+ // Check that the horrible_cast<>s will work\r
+ typedef int ERROR_CantUsehorrible_cast[sizeof(function_to_bind)==sizeof(u.s)\r
+ && sizeof(function_to_bind)==sizeof(u.ProbeFunc)\r
+ && sizeof(u2.virtfunc)==sizeof(u2.s) ? 1 : -1];\r
+ // Unfortunately, taking the address of a MF prevents it from being inlined, so \r
+ // this next line can't be completely optimised away by the compiler.\r
+ u2.virtfunc = &GenericVirtualClass::GetThis;\r
+ u.s.codeptr = u2.s.codeptr;\r
+ return (pthis->*u.ProbeFunc)();\r
+ }\r
+};\r
+\r
+#if (_MSC_VER <1300)\r
+\r
+// Nasty hack for Microsoft Visual C++ 6.0\r
+// unknown_inheritance classes go here\r
+// There is a compiler bug in MSVC6 which generates incorrect code in this case!!\r
+template <>\r
+struct SimplifyMemFunc<SINGLE_MEMFUNCPTR_SIZE + 3*sizeof(int) >\r
+{\r
+ template <class X, class XFuncType, class GenericMemFuncType>\r
+ inline static GenericClass *Convert(X *pthis, XFuncType function_to_bind, \r
+ GenericMemFuncType &bound_func) {\r
+ // There is an apalling but obscure compiler bug in MSVC6 and earlier:\r
+ // vtable_index and 'vtordisp' are always set to 0 in the \r
+ // unknown_inheritance case!\r
+ // This means that an incorrect function could be called!!!\r
+ // Compiling with the /vmg option leads to potentially incorrect code.\r
+ // This is probably the reason that the IDE has a user interface for specifying\r
+ // the /vmg option, but it is disabled - you can only specify /vmg on \r
+ // the command line. In VC1.5 and earlier, the compiler would ICE if it ever\r
+ // encountered this situation.\r
+ // It is OK to use the /vmg option if /vmm or /vms is specified.\r
+\r
+ // Fortunately, the wrong function is only called in very obscure cases.\r
+ // It only occurs when a derived class overrides a virtual function declared \r
+ // in a virtual base class, and the member function \r
+ // points to the *Derived* version of that function. The problem can be\r
+ // completely averted in 100% of cases by using the *Base class* for the \r
+ // member fpointer. Ie, if you use the base class as an interface, you'll\r
+ // stay out of trouble.\r
+ // Occasionally, you might want to point directly to a derived class function\r
+ // that isn't an override of a base class. In this case, both vtable_index \r
+ // and 'vtordisp' are zero, but a virtual_inheritance pointer will be generated.\r
+ // We can generate correct code in this case. To prevent an incorrect call from\r
+ // ever being made, on MSVC6 we generate a warning, and call a function to \r
+ // make the program crash instantly. \r
+ typedef char ERROR_VC6CompilerBug[-100];\r
+ return 0; \r
+ }\r
+};\r
+\r
+\r
+#else \r
+\r
+// Nasty hack for Microsoft and Intel (IA32 and Itanium)\r
+// unknown_inheritance classes go here \r
+// This is probably the ugliest bit of code I've ever written. Look at the casts!\r
+// There is a compiler bug in MSVC6 which prevents it from using this code.\r
+template <>\r
+struct SimplifyMemFunc<SINGLE_MEMFUNCPTR_SIZE + 3*sizeof(int) >\r
+{\r
+ template <class X, class XFuncType, class GenericMemFuncType>\r
+ inline static GenericClass *Convert(X *pthis, XFuncType function_to_bind, \r
+ GenericMemFuncType &bound_func) {\r
+ // The member function pointer is 16 bytes long. We can't use a normal cast, but\r
+ // we can use a union to do the conversion.\r
+ union {\r
+ XFuncType func;\r
+ // In VC++ and ICL, an unknown_inheritance member pointer \r
+ // is internally defined as:\r
+ struct {\r
+ GenericMemFuncType m_funcaddress; // points to the actual member function\r
+ int delta; // #bytes to be added to the 'this' pointer\r
+ int vtordisp; // #bytes to add to 'this' to find the vtable\r
+ int vtable_index; // or 0 if no virtual inheritance\r
+ } s;\r
+ } u;\r
+ // Check that the horrible_cast will work\r
+ typedef int ERROR_CantUsehorrible_cast[sizeof(XFuncType)==sizeof(u.s)? 1 : -1];\r
+ u.func = function_to_bind;\r
+ bound_func = u.s.funcaddress;\r
+ int virtual_delta = 0;\r
+ if (u.s.vtable_index) { // Virtual inheritance is used\r
+ // First, get to the vtable. \r
+ // It is 'vtordisp' bytes from the start of the class.\r
+ const int * vtable = *reinterpret_cast<const int *const*>(\r
+ reinterpret_cast<const char *>(pthis) + u.s.vtordisp );\r
+\r
+ // 'vtable_index' tells us where in the table we should be looking.\r
+ virtual_delta = u.s.vtordisp + *reinterpret_cast<const int *>( \r
+ reinterpret_cast<const char *>(vtable) + u.s.vtable_index);\r
+ }\r
+ // The int at 'virtual_delta' gives us the amount to add to 'this'.\r
+ // Finally we can add the three components together. Phew!\r
+ return reinterpret_cast<GenericClass *>(\r
+ reinterpret_cast<char *>(pthis) + u.s.delta + virtual_delta);\r
+ };\r
+};\r
+#endif // MSVC 7 and greater\r
+\r
+#endif // MS/Intel hacks\r
+\r
+} // namespace detail\r
+\r
+////////////////////////////////////////////////////////////////////////////////\r
+// Fast Delegates, part 2:\r
+//\r
+// Define the delegate storage, and cope with static functions\r
+//\r
+////////////////////////////////////////////////////////////////////////////////\r
+\r
+// DelegateMemento -- an opaque structure which can hold an arbitary delegate.\r
+// It knows nothing about the calling convention or number of arguments used by\r
+// the function pointed to.\r
+// It supplies comparison operators so that it can be stored in STL collections.\r
+// It cannot be set to anything other than null, nor invoked directly: \r
+// it must be converted to a specific delegate.\r
+\r
+// Implementation:\r
+// There are two possible implementations: the Safe method and the Evil method.\r
+// DelegateMemento - Safe version\r
+//\r
+// This implementation is standard-compliant, but a bit tricky.\r
+// A static function pointer is stored inside the class. \r
+// Here are the valid values:\r
+// +-- Static pointer --+--pThis --+-- pMemFunc-+-- Meaning------+\r
+// | 0 | 0 | 0 | Empty |\r
+// | !=0 |(dontcare)| Invoker | Static function|\r
+// | 0 | !=0 | !=0* | Method call |\r
+// +--------------------+----------+------------+----------------+\r
+// * For Metrowerks, this can be 0. (first virtual function in a \r
+// single_inheritance class).\r
+// When stored stored inside a specific delegate, the 'dontcare' entries are replaced\r
+// with a reference to the delegate itself. This complicates the = and == operators\r
+// for the delegate class.\r
+\r
+// DelegateMemento - Evil version\r
+//\r
+// For compilers where data pointers are at least as big as code pointers, it is \r
+// possible to store the function pointer in the this pointer, using another \r
+// horrible_cast. In this case the DelegateMemento implementation is simple:\r
+// +--pThis --+-- pMemFunc-+-- Meaning---------------------+\r
+// | 0 | 0 | Empty |\r
+// | !=0 | !=0* | Static function or method call|\r
+// +----------+------------+-------------------------------+\r
+// * For Metrowerks, this can be 0. (first virtual function in a \r
+// single_inheritance class).\r
+// Note that the Sun C++ and MSVC documentation explicitly state that they \r
+// support static_cast between void * and function pointers.\r
+\r
+class DelegateMemento {\r
+protected: \r
+ // the data is protected, not private, because many\r
+ // compilers have problems with template friends.\r
+ typedef void (detail::GenericClass::*GenericMemFuncType)(); // arbitrary MFP.\r
+ detail::GenericClass *m_pthis;\r
+ GenericMemFuncType m_pFunction;\r
+\r
+#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK)\r
+ typedef void (*GenericFuncPtr)(); // arbitrary code pointer\r
+ GenericFuncPtr m_pStaticFunction;\r
+#endif\r
+\r
+public:\r
+#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK)\r
+ DelegateMemento() : m_pthis(0), m_pFunction(0), m_pStaticFunction(0) {};\r
+ void clear() {\r
+ m_pthis=0; m_pFunction=0; m_pStaticFunction=0;\r
+ }\r
+#else\r
+ DelegateMemento() : m_pthis(0), m_pFunction(0) {};\r
+ void clear() { m_pthis=0; m_pFunction=0; }\r
+#endif\r
+public:\r
+#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK)\r
+ inline bool IsEqual (const DelegateMemento &x) const{\r
+ // We have to cope with the static function pointers as a special case\r
+ if (m_pFunction!=x.m_pFunction) return false;\r
+ // the static function ptrs must either both be equal, or both be 0.\r
+ if (m_pStaticFunction!=x.m_pStaticFunction) return false;\r
+ if (m_pStaticFunction!=0) return m_pthis==x.m_pthis;\r
+ else return true;\r
+ }\r
+#else // Evil Method\r
+ inline bool IsEqual (const DelegateMemento &x) const{\r
+ return m_pthis==x.m_pthis && m_pFunction==x.m_pFunction;\r
+ }\r
+#endif\r
+ // Provide a strict weak ordering for DelegateMementos.\r
+ inline bool IsLess(const DelegateMemento &right) const {\r
+ // deal with static function pointers first\r
+#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK)\r
+ if (m_pStaticFunction !=0 || right.m_pStaticFunction!=0) \r
+ return m_pStaticFunction < right.m_pStaticFunction;\r
+#endif\r
+ if (m_pthis !=right.m_pthis) return m_pthis < right.m_pthis;\r
+ // There are no ordering operators for member function pointers, \r
+ // but we can fake one by comparing each byte. The resulting ordering is\r
+ // arbitrary (and compiler-dependent), but it permits storage in ordered STL containers.\r
+ return memcmp(&m_pFunction, &right.m_pFunction, sizeof(m_pFunction)) < 0;\r
+\r
+ }\r
+ // BUGFIX (Mar 2005):\r
+ // We can't just compare m_pFunction because on Metrowerks,\r
+ // m_pFunction can be zero even if the delegate is not empty!\r
+ inline bool operator ! () const // Is it bound to anything?\r
+ { return m_pthis==0 && m_pFunction==0; }\r
+ inline bool empty() const // Is it bound to anything?\r
+ { return m_pthis==0 && m_pFunction==0; }\r
+public:\r
+ DelegateMemento & operator = (const DelegateMemento &right) {\r
+ SetMementoFrom(right); \r
+ return *this;\r
+ }\r
+ inline bool operator <(const DelegateMemento &right) {\r
+ return IsLess(right);\r
+ }\r
+ inline bool operator >(const DelegateMemento &right) {\r
+ return right.IsLess(*this);\r
+ }\r
+ DelegateMemento (const DelegateMemento &right) : \r
+ m_pFunction(right.m_pFunction), m_pthis(right.m_pthis)\r
+#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK)\r
+ , m_pStaticFunction (right.m_pStaticFunction)\r
+#endif\r
+ {}\r
+protected:\r
+ void SetMementoFrom(const DelegateMemento &right) {\r
+ m_pFunction = right.m_pFunction;\r
+ m_pthis = right.m_pthis;\r
+#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK)\r
+ m_pStaticFunction = right.m_pStaticFunction;\r
+#endif\r
+ }\r
+};\r
+\r
+\r
+// ClosurePtr<>\r
+//\r
+// A private wrapper class that adds function signatures to DelegateMemento.\r
+// It's the class that does most of the actual work.\r
+// The signatures are specified by:\r
+// GenericMemFunc: must be a type of GenericClass member function pointer. \r
+// StaticFuncPtr: must be a type of function pointer with the same signature \r
+// as GenericMemFunc.\r
+// UnvoidStaticFuncPtr: is the same as StaticFuncPtr, except on VC6\r
+// where it never returns void (returns DefaultVoid instead).\r
+\r
+// An outer class, FastDelegateN<>, handles the invoking and creates the\r
+// necessary typedefs.\r
+// This class does everything else.\r
+\r
+namespace detail {\r
+\r
+template < class GenericMemFunc, class StaticFuncPtr, class UnvoidStaticFuncPtr>\r
+class ClosurePtr : public DelegateMemento {\r
+public:\r
+ // These functions are for setting the delegate to a member function.\r
+\r
+ // Here's the clever bit: we convert an arbitrary member function into a \r
+ // standard form. XMemFunc should be a member function of class X, but I can't \r
+ // enforce that here. It needs to be enforced by the wrapper class.\r
+ template < class X, class XMemFunc >\r
+ inline void bindmemfunc(X *pthis, XMemFunc function_to_bind ) {\r
+ m_pthis = SimplifyMemFunc< sizeof(function_to_bind) >\r
+ ::Convert(pthis, function_to_bind, m_pFunction);\r
+#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK)\r
+ m_pStaticFunction = 0;\r
+#endif\r
+ }\r
+ // For const member functions, we only need a const class pointer.\r
+ // Since we know that the member function is const, it's safe to \r
+ // remove the const qualifier from the 'this' pointer with a const_cast.\r
+ // VC6 has problems if we just overload 'bindmemfunc', so we give it a different name.\r
+ template < class X, class XMemFunc>\r
+ inline void bindconstmemfunc(const X *pthis, XMemFunc function_to_bind) {\r
+ m_pthis= SimplifyMemFunc< sizeof(function_to_bind) >\r
+ ::Convert(const_cast<X*>(pthis), function_to_bind, m_pFunction);\r
+#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK)\r
+ m_pStaticFunction = 0;\r
+#endif\r
+ }\r
+#ifdef FASTDELEGATE_GCC_BUG_8271 // At present, GCC doesn't recognize constness of MFPs in templates\r
+ template < class X, class XMemFunc>\r
+ inline void bindmemfunc(const X *pthis, XMemFunc function_to_bind) {\r
+ bindconstmemfunc(pthis, function_to_bind);\r
+#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK)\r
+ m_pStaticFunction = 0;\r
+#endif\r
+ }\r
+#endif\r
+ // These functions are required for invoking the stored function\r
+ inline GenericClass *GetClosureThis() const { return m_pthis; }\r
+ inline GenericMemFunc GetClosureMemPtr() const { return reinterpret_cast<GenericMemFunc>(m_pFunction); }\r
+\r
+// There are a few ways of dealing with static function pointers.\r
+// There's a standard-compliant, but tricky method.\r
+// There's also a straightforward hack, that won't work on DOS compilers using the\r
+// medium memory model. It's so evil that I can't recommend it, but I've\r
+// implemented it anyway because it produces very nice asm code.\r
+\r
+#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK)\r
+\r
+// ClosurePtr<> - Safe version\r
+//\r
+// This implementation is standard-compliant, but a bit tricky.\r
+// I store the function pointer inside the class, and the delegate then\r
+// points to itself. Whenever the delegate is copied, these self-references\r
+// must be transformed, and this complicates the = and == operators.\r
+public:\r
+ // The next two functions are for operator ==, =, and the copy constructor.\r
+ // We may need to convert the m_pthis pointers, so that\r
+ // they remain as self-references.\r
+ template< class DerivedClass >\r
+ inline void CopyFrom (DerivedClass *pParent, const DelegateMemento &x) {\r
+ SetMementoFrom(x);\r
+ if (m_pStaticFunction!=0) {\r
+ // transform self references...\r
+ m_pthis=reinterpret_cast<GenericClass *>(pParent);\r
+ }\r
+ }\r
+ // For static functions, the 'static_function_invoker' class in the parent \r
+ // will be called. The parent then needs to call GetStaticFunction() to find out \r
+ // the actual function to invoke.\r
+ template < class DerivedClass, class ParentInvokerSig >\r
+ inline void bindstaticfunc(DerivedClass *pParent, ParentInvokerSig static_function_invoker, \r
+ StaticFuncPtr function_to_bind ) {\r
+ if (function_to_bind==0) { // cope with assignment to 0\r
+ m_pFunction=0;\r
+ } else { \r
+ bindmemfunc(pParent, static_function_invoker);\r
+ }\r
+ m_pStaticFunction=reinterpret_cast<GenericFuncPtr>(function_to_bind);\r
+ }\r
+ inline UnvoidStaticFuncPtr GetStaticFunction() const { \r
+ return reinterpret_cast<UnvoidStaticFuncPtr>(m_pStaticFunction); \r
+ }\r
+#else\r
+\r
+// ClosurePtr<> - Evil version\r
+//\r
+// For compilers where data pointers are at least as big as code pointers, it is \r
+// possible to store the function pointer in the this pointer, using another \r
+// horrible_cast. Invocation isn't any faster, but it saves 4 bytes, and\r
+// speeds up comparison and assignment. If C++ provided direct language support\r
+// for delegates, they would produce asm code that was almost identical to this.\r
+// Note that the Sun C++ and MSVC documentation explicitly state that they \r
+// support static_cast between void * and function pointers.\r
+\r
+ template< class DerivedClass >\r
+ inline void CopyFrom (DerivedClass *pParent, const DelegateMemento &right) {\r
+ SetMementoFrom(right);\r
+ }\r
+ // For static functions, the 'static_function_invoker' class in the parent \r
+ // will be called. The parent then needs to call GetStaticFunction() to find out \r
+ // the actual function to invoke.\r
+ // ******** EVIL, EVIL CODE! *******\r
+ template < class DerivedClass, class ParentInvokerSig>\r
+ inline void bindstaticfunc(DerivedClass *pParent, ParentInvokerSig static_function_invoker, \r
+ StaticFuncPtr function_to_bind) {\r
+ if (function_to_bind==0) { // cope with assignment to 0\r
+ m_pFunction=0;\r
+ } else { \r
+ // We'll be ignoring the 'this' pointer, but we need to make sure we pass\r
+ // a valid value to bindmemfunc().\r
+ bindmemfunc(pParent, static_function_invoker);\r
+ }\r
+\r
+ // WARNING! Evil hack. We store the function in the 'this' pointer!\r
+ // Ensure that there's a compilation failure if function pointers \r
+ // and data pointers have different sizes.\r
+ // If you get this error, you need to #undef FASTDELEGATE_USESTATICFUNCTIONHACK.\r
+ typedef int ERROR_CantUseEvilMethod[sizeof(GenericClass *)==sizeof(function_to_bind) ? 1 : -1];\r
+ m_pthis = horrible_cast<GenericClass *>(function_to_bind);\r
+ // MSVC, SunC++ and DMC accept the following (non-standard) code:\r
+// m_pthis = static_cast<GenericClass *>(static_cast<void *>(function_to_bind));\r
+ // BCC32, Comeau and DMC accept this method. MSVC7.1 needs __int64 instead of long\r
+// m_pthis = reinterpret_cast<GenericClass *>(reinterpret_cast<long>(function_to_bind));\r
+ }\r
+ // ******** EVIL, EVIL CODE! *******\r
+ // This function will be called with an invalid 'this' pointer!!\r
+ // We're just returning the 'this' pointer, converted into\r
+ // a function pointer!\r
+ inline UnvoidStaticFuncPtr GetStaticFunction() const {\r
+ // Ensure that there's a compilation failure if function pointers \r
+ // and data pointers have different sizes.\r
+ // If you get this error, you need to #undef FASTDELEGATE_USESTATICFUNCTIONHACK.\r
+ typedef int ERROR_CantUseEvilMethod[sizeof(UnvoidStaticFuncPtr)==sizeof(this) ? 1 : -1];\r
+ return horrible_cast<UnvoidStaticFuncPtr>(this);\r
+ }\r
+#endif // !defined(FASTDELEGATE_USESTATICFUNCTIONHACK)\r
+\r
+ // Does the closure contain this static function?\r
+ inline bool IsEqualToStaticFuncPtr(StaticFuncPtr funcptr){\r
+ if (funcptr==0) return empty(); \r
+ // For the Evil method, if it doesn't actually contain a static function, this will return an arbitrary\r
+ // value that is not equal to any valid function pointer.\r
+ else return funcptr==reinterpret_cast<StaticFuncPtr>(GetStaticFunction());\r
+ }\r
+};\r
+\r
+\r
+} // namespace detail\r
+\r
+////////////////////////////////////////////////////////////////////////////////\r
+// Fast Delegates, part 3:\r
+//\r
+// Wrapper classes to ensure type safety\r
+//\r
+////////////////////////////////////////////////////////////////////////////////\r
+\r
+\r
+// Once we have the member function conversion templates, it's easy to make the\r
+// wrapper classes. So that they will work with as many compilers as possible, \r
+// the classes are of the form\r
+// FastDelegate3<int, char *, double>\r
+// They can cope with any combination of parameters. The max number of parameters\r
+// allowed is 8, but it is trivial to increase this limit.\r
+// Note that we need to treat const member functions seperately.\r
+// All this class does is to enforce type safety, and invoke the delegate with\r
+// the correct list of parameters.\r
+\r
+// Because of the weird rule about the class of derived member function pointers,\r
+// you sometimes need to apply a downcast to the 'this' pointer.\r
+// This is the reason for the use of "implicit_cast<X*>(pthis)" in the code below. \r
+// If CDerivedClass is derived from CBaseClass, but doesn't override SimpleVirtualFunction,\r
+// without this trick you'd need to write:\r
+// MyDelegate(static_cast<CBaseClass *>(&d), &CDerivedClass::SimpleVirtualFunction);\r
+// but with the trick you can write\r
+// MyDelegate(&d, &CDerivedClass::SimpleVirtualFunction);\r
+\r
+// RetType is the type the compiler uses in compiling the template. For VC6,\r
+// it cannot be void. DesiredRetType is the real type which is returned from\r
+// all of the functions. It can be void.\r
+\r
+// Implicit conversion to "bool" is achieved using the safe_bool idiom,\r
+// using member data pointers (MDP). This allows "if (dg)..." syntax\r
+// Because some compilers (eg codeplay) don't have a unique value for a zero\r
+// MDP, an extra padding member is added to the SafeBool struct.\r
+// Some compilers (eg VC6) won't implicitly convert from 0 to an MDP, so\r
+// in that case the static function constructor is not made explicit; this\r
+// allows "if (dg==0) ..." to compile.\r
+\r
+//N=0\r
+template<class RetType=detail::DefaultVoid>\r
+class FastDelegate0 {\r
+private:\r
+ typedef typename detail::DefaultVoidToVoid<RetType>::type DesiredRetType;\r
+ typedef DesiredRetType (*StaticFunctionPtr)();\r
+ typedef RetType (*UnvoidStaticFunctionPtr)();\r
+ typedef RetType (detail::GenericClass::*GenericMemFn)();\r
+ typedef detail::ClosurePtr<GenericMemFn, StaticFunctionPtr, UnvoidStaticFunctionPtr> ClosureType;\r
+ ClosureType m_Closure;\r
+public:\r
+ // Typedefs to aid generic programming\r
+ typedef FastDelegate0 type;\r
+\r
+ // Construction and comparison functions\r
+ FastDelegate0() { clear(); }\r
+ FastDelegate0(const FastDelegate0 &x) {\r
+ m_Closure.CopyFrom(this, x.m_Closure); }\r
+ void operator = (const FastDelegate0 &x) {\r
+ m_Closure.CopyFrom(this, x.m_Closure); }\r
+ bool operator ==(const FastDelegate0 &x) const {\r
+ return m_Closure.IsEqual(x.m_Closure); }\r
+ bool operator !=(const FastDelegate0 &x) const {\r
+ return !m_Closure.IsEqual(x.m_Closure); }\r
+ bool operator <(const FastDelegate0 &x) const {\r
+ return m_Closure.IsLess(x.m_Closure); }\r
+ bool operator >(const FastDelegate0 &x) const {\r
+ return x.m_Closure.IsLess(m_Closure); }\r
+ // Binding to non-const member functions\r
+ template < class X, class Y >\r
+ FastDelegate0(Y *pthis, DesiredRetType (X::* function_to_bind)() ) {\r
+ m_Closure.bindmemfunc(detail::implicit_cast<X*>(pthis), function_to_bind); }\r
+ template < class X, class Y >\r
+ inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)()) {\r
+ m_Closure.bindmemfunc(detail::implicit_cast<X*>(pthis), function_to_bind); }\r
+ // Binding to const member functions.\r
+ template < class X, class Y >\r
+ FastDelegate0(const Y *pthis, DesiredRetType (X::* function_to_bind)() const) {\r
+ m_Closure.bindconstmemfunc(detail::implicit_cast<const X*>(pthis), function_to_bind); }\r
+ template < class X, class Y >\r
+ inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)() const) {\r
+ m_Closure.bindconstmemfunc(detail::implicit_cast<const X *>(pthis), function_to_bind); }\r
+ // Static functions. We convert them into a member function call.\r
+ // This constructor also provides implicit conversion\r
+ FastDelegate0(DesiredRetType (*function_to_bind)() ) {\r
+ bind(function_to_bind); }\r
+ // for efficiency, prevent creation of a temporary\r
+ void operator = (DesiredRetType (*function_to_bind)() ) {\r
+ bind(function_to_bind); }\r
+ inline void bind(DesiredRetType (*function_to_bind)()) {\r
+ m_Closure.bindstaticfunc(this, &FastDelegate0::InvokeStaticFunction, \r
+ function_to_bind); }\r
+ // Invoke the delegate\r
+ RetType operator() () const {\r
+ return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(); }\r
+ // Implicit conversion to "bool" using the safe_bool idiom\r
+private:\r
+ typedef struct SafeBoolStruct {\r
+ int a_data_pointer_to_this_is_0_on_buggy_compilers;\r
+ StaticFunctionPtr m_nonzero;\r
+ } UselessTypedef;\r
+ typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type;\r
+public:\r
+ operator unspecified_bool_type() const {\r
+ return empty()? 0: &SafeBoolStruct::m_nonzero;\r
+ }\r
+ // necessary to allow ==0 to work despite the safe_bool idiom\r
+ inline bool operator==(StaticFunctionPtr funcptr) {\r
+ return m_Closure.IsEqualToStaticFuncPtr(funcptr); }\r
+ inline bool operator!=(StaticFunctionPtr funcptr) { \r
+ return !m_Closure.IsEqualToStaticFuncPtr(funcptr); }\r
+ inline bool operator ! () const { // Is it bound to anything?\r
+ return !m_Closure; }\r
+ inline bool empty() const {\r
+ return !m_Closure; }\r
+ void clear() { m_Closure.clear();}\r
+ // Conversion to and from the DelegateMemento storage class\r
+ const DelegateMemento & GetMemento() { return m_Closure; }\r
+ void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); }\r
+\r
+private: // Invoker for static functions\r
+ RetType InvokeStaticFunction() const {\r
+ return (*(m_Closure.GetStaticFunction()))(); }\r
+};\r
+\r
+//N=1\r
+template<class Param1, class RetType=detail::DefaultVoid>\r
+class FastDelegate1 {\r
+private:\r
+ typedef typename detail::DefaultVoidToVoid<RetType>::type DesiredRetType;\r
+ typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1);\r
+ typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1);\r
+ typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1);\r
+ typedef detail::ClosurePtr<GenericMemFn, StaticFunctionPtr, UnvoidStaticFunctionPtr> ClosureType;\r
+ ClosureType m_Closure;\r
+public:\r
+ // Typedefs to aid generic programming\r
+ typedef FastDelegate1 type;\r
+\r
+ // Construction and comparison functions\r
+ FastDelegate1() { clear(); }\r
+ FastDelegate1(const FastDelegate1 &x) {\r
+ m_Closure.CopyFrom(this, x.m_Closure); }\r
+ void operator = (const FastDelegate1 &x) {\r
+ m_Closure.CopyFrom(this, x.m_Closure); }\r
+ bool operator ==(const FastDelegate1 &x) const {\r
+ return m_Closure.IsEqual(x.m_Closure); }\r
+ bool operator !=(const FastDelegate1 &x) const {\r
+ return !m_Closure.IsEqual(x.m_Closure); }\r
+ bool operator <(const FastDelegate1 &x) const {\r
+ return m_Closure.IsLess(x.m_Closure); }\r
+ bool operator >(const FastDelegate1 &x) const {\r
+ return x.m_Closure.IsLess(m_Closure); }\r
+ // Binding to non-const member functions\r
+ template < class X, class Y >\r
+ FastDelegate1(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1) ) {\r
+ m_Closure.bindmemfunc(detail::implicit_cast<X*>(pthis), function_to_bind); }\r
+ template < class X, class Y >\r
+ inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1)) {\r
+ m_Closure.bindmemfunc(detail::implicit_cast<X*>(pthis), function_to_bind); }\r
+ // Binding to const member functions.\r
+ template < class X, class Y >\r
+ FastDelegate1(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1) const) {\r
+ m_Closure.bindconstmemfunc(detail::implicit_cast<const X*>(pthis), function_to_bind); }\r
+ template < class X, class Y >\r
+ inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1) const) {\r
+ m_Closure.bindconstmemfunc(detail::implicit_cast<const X *>(pthis), function_to_bind); }\r
+ // Static functions. We convert them into a member function call.\r
+ // This constructor also provides implicit conversion\r
+ FastDelegate1(DesiredRetType (*function_to_bind)(Param1 p1) ) {\r
+ bind(function_to_bind); }\r
+ // for efficiency, prevent creation of a temporary\r
+ void operator = (DesiredRetType (*function_to_bind)(Param1 p1) ) {\r
+ bind(function_to_bind); }\r
+ inline void bind(DesiredRetType (*function_to_bind)(Param1 p1)) {\r
+ m_Closure.bindstaticfunc(this, &FastDelegate1::InvokeStaticFunction, \r
+ function_to_bind); }\r
+ // Invoke the delegate\r
+ RetType operator() (Param1 p1) const {\r
+ return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1); }\r
+ // Implicit conversion to "bool" using the safe_bool idiom\r
+private:\r
+ typedef struct SafeBoolStruct {\r
+ int a_data_pointer_to_this_is_0_on_buggy_compilers;\r
+ StaticFunctionPtr m_nonzero;\r
+ } UselessTypedef;\r
+ typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type;\r
+public:\r
+ operator unspecified_bool_type() const {\r
+ return empty()? 0: &SafeBoolStruct::m_nonzero;\r
+ }\r
+ // necessary to allow ==0 to work despite the safe_bool idiom\r
+ inline bool operator==(StaticFunctionPtr funcptr) {\r
+ return m_Closure.IsEqualToStaticFuncPtr(funcptr); }\r
+ inline bool operator!=(StaticFunctionPtr funcptr) { \r
+ return !m_Closure.IsEqualToStaticFuncPtr(funcptr); }\r
+ inline bool operator ! () const { // Is it bound to anything?\r
+ return !m_Closure; }\r
+ inline bool empty() const {\r
+ return !m_Closure; }\r
+ void clear() { m_Closure.clear();}\r
+ // Conversion to and from the DelegateMemento storage class\r
+ const DelegateMemento & GetMemento() { return m_Closure; }\r
+ void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); }\r
+\r
+private: // Invoker for static functions\r
+ RetType InvokeStaticFunction(Param1 p1) const {\r
+ return (*(m_Closure.GetStaticFunction()))(p1); }\r
+};\r
+\r
+//N=2\r
+template<class Param1, class Param2, class RetType=detail::DefaultVoid>\r
+class FastDelegate2 {\r
+private:\r
+ typedef typename detail::DefaultVoidToVoid<RetType>::type DesiredRetType;\r
+ typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2);\r
+ typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2);\r
+ typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2);\r
+ typedef detail::ClosurePtr<GenericMemFn, StaticFunctionPtr, UnvoidStaticFunctionPtr> ClosureType;\r
+ ClosureType m_Closure;\r
+public:\r
+ // Typedefs to aid generic programming\r
+ typedef FastDelegate2 type;\r
+\r
+ // Construction and comparison functions\r
+ FastDelegate2() { clear(); }\r
+ FastDelegate2(const FastDelegate2 &x) {\r
+ m_Closure.CopyFrom(this, x.m_Closure); }\r
+ void operator = (const FastDelegate2 &x) {\r
+ m_Closure.CopyFrom(this, x.m_Closure); }\r
+ bool operator ==(const FastDelegate2 &x) const {\r
+ return m_Closure.IsEqual(x.m_Closure); }\r
+ bool operator !=(const FastDelegate2 &x) const {\r
+ return !m_Closure.IsEqual(x.m_Closure); }\r
+ bool operator <(const FastDelegate2 &x) const {\r
+ return m_Closure.IsLess(x.m_Closure); }\r
+ bool operator >(const FastDelegate2 &x) const {\r
+ return x.m_Closure.IsLess(m_Closure); }\r
+ // Binding to non-const member functions\r
+ template < class X, class Y >\r
+ FastDelegate2(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2) ) {\r
+ m_Closure.bindmemfunc(detail::implicit_cast<X*>(pthis), function_to_bind); }\r
+ template < class X, class Y >\r
+ inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2)) {\r
+ m_Closure.bindmemfunc(detail::implicit_cast<X*>(pthis), function_to_bind); }\r
+ // Binding to const member functions.\r
+ template < class X, class Y >\r
+ FastDelegate2(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2) const) {\r
+ m_Closure.bindconstmemfunc(detail::implicit_cast<const X*>(pthis), function_to_bind); }\r
+ template < class X, class Y >\r
+ inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2) const) {\r
+ m_Closure.bindconstmemfunc(detail::implicit_cast<const X *>(pthis), function_to_bind); }\r
+ // Static functions. We convert them into a member function call.\r
+ // This constructor also provides implicit conversion\r
+ FastDelegate2(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2) ) {\r
+ bind(function_to_bind); }\r
+ // for efficiency, prevent creation of a temporary\r
+ void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2) ) {\r
+ bind(function_to_bind); }\r
+ inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2)) {\r
+ m_Closure.bindstaticfunc(this, &FastDelegate2::InvokeStaticFunction, \r
+ function_to_bind); }\r
+ // Invoke the delegate\r
+ RetType operator() (Param1 p1, Param2 p2) const {\r
+ return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2); }\r
+ // Implicit conversion to "bool" using the safe_bool idiom\r
+private:\r
+ typedef struct SafeBoolStruct {\r
+ int a_data_pointer_to_this_is_0_on_buggy_compilers;\r
+ StaticFunctionPtr m_nonzero;\r
+ } UselessTypedef;\r
+ typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type;\r
+public:\r
+ operator unspecified_bool_type() const {\r
+ return empty()? 0: &SafeBoolStruct::m_nonzero;\r
+ }\r
+ // necessary to allow ==0 to work despite the safe_bool idiom\r
+ inline bool operator==(StaticFunctionPtr funcptr) {\r
+ return m_Closure.IsEqualToStaticFuncPtr(funcptr); }\r
+ inline bool operator!=(StaticFunctionPtr funcptr) { \r
+ return !m_Closure.IsEqualToStaticFuncPtr(funcptr); }\r
+ inline bool operator ! () const { // Is it bound to anything?\r
+ return !m_Closure; }\r
+ inline bool empty() const {\r
+ return !m_Closure; }\r
+ void clear() { m_Closure.clear();}\r
+ // Conversion to and from the DelegateMemento storage class\r
+ const DelegateMemento & GetMemento() { return m_Closure; }\r
+ void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); }\r
+\r
+private: // Invoker for static functions\r
+ RetType InvokeStaticFunction(Param1 p1, Param2 p2) const {\r
+ return (*(m_Closure.GetStaticFunction()))(p1, p2); }\r
+};\r
+\r
+//N=3\r
+template<class Param1, class Param2, class Param3, class RetType=detail::DefaultVoid>\r
+class FastDelegate3 {\r
+private:\r
+ typedef typename detail::DefaultVoidToVoid<RetType>::type DesiredRetType;\r
+ typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3);\r
+ typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3);\r
+ typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3);\r
+ typedef detail::ClosurePtr<GenericMemFn, StaticFunctionPtr, UnvoidStaticFunctionPtr> ClosureType;\r
+ ClosureType m_Closure;\r
+public:\r
+ // Typedefs to aid generic programming\r
+ typedef FastDelegate3 type;\r
+\r
+ // Construction and comparison functions\r
+ FastDelegate3() { clear(); }\r
+ FastDelegate3(const FastDelegate3 &x) {\r
+ m_Closure.CopyFrom(this, x.m_Closure); }\r
+ void operator = (const FastDelegate3 &x) {\r
+ m_Closure.CopyFrom(this, x.m_Closure); }\r
+ bool operator ==(const FastDelegate3 &x) const {\r
+ return m_Closure.IsEqual(x.m_Closure); }\r
+ bool operator !=(const FastDelegate3 &x) const {\r
+ return !m_Closure.IsEqual(x.m_Closure); }\r
+ bool operator <(const FastDelegate3 &x) const {\r
+ return m_Closure.IsLess(x.m_Closure); }\r
+ bool operator >(const FastDelegate3 &x) const {\r
+ return x.m_Closure.IsLess(m_Closure); }\r
+ // Binding to non-const member functions\r
+ template < class X, class Y >\r
+ FastDelegate3(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3) ) {\r
+ m_Closure.bindmemfunc(detail::implicit_cast<X*>(pthis), function_to_bind); }\r
+ template < class X, class Y >\r
+ inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3)) {\r
+ m_Closure.bindmemfunc(detail::implicit_cast<X*>(pthis), function_to_bind); }\r
+ // Binding to const member functions.\r
+ template < class X, class Y >\r
+ FastDelegate3(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3) const) {\r
+ m_Closure.bindconstmemfunc(detail::implicit_cast<const X*>(pthis), function_to_bind); }\r
+ template < class X, class Y >\r
+ inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3) const) {\r
+ m_Closure.bindconstmemfunc(detail::implicit_cast<const X *>(pthis), function_to_bind); }\r
+ // Static functions. We convert them into a member function call.\r
+ // This constructor also provides implicit conversion\r
+ FastDelegate3(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3) ) {\r
+ bind(function_to_bind); }\r
+ // for efficiency, prevent creation of a temporary\r
+ void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3) ) {\r
+ bind(function_to_bind); }\r
+ inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3)) {\r
+ m_Closure.bindstaticfunc(this, &FastDelegate3::InvokeStaticFunction, \r
+ function_to_bind); }\r
+ // Invoke the delegate\r
+ RetType operator() (Param1 p1, Param2 p2, Param3 p3) const {\r
+ return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3); }\r
+ // Implicit conversion to "bool" using the safe_bool idiom\r
+private:\r
+ typedef struct SafeBoolStruct {\r
+ int a_data_pointer_to_this_is_0_on_buggy_compilers;\r
+ StaticFunctionPtr m_nonzero;\r
+ } UselessTypedef;\r
+ typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type;\r
+public:\r
+ operator unspecified_bool_type() const {\r
+ return empty()? 0: &SafeBoolStruct::m_nonzero;\r
+ }\r
+ // necessary to allow ==0 to work despite the safe_bool idiom\r
+ inline bool operator==(StaticFunctionPtr funcptr) {\r
+ return m_Closure.IsEqualToStaticFuncPtr(funcptr); }\r
+ inline bool operator!=(StaticFunctionPtr funcptr) { \r
+ return !m_Closure.IsEqualToStaticFuncPtr(funcptr); }\r
+ inline bool operator ! () const { // Is it bound to anything?\r
+ return !m_Closure; }\r
+ inline bool empty() const {\r
+ return !m_Closure; }\r
+ void clear() { m_Closure.clear();}\r
+ // Conversion to and from the DelegateMemento storage class\r
+ const DelegateMemento & GetMemento() { return m_Closure; }\r
+ void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); }\r
+\r
+private: // Invoker for static functions\r
+ RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3) const {\r
+ return (*(m_Closure.GetStaticFunction()))(p1, p2, p3); }\r
+};\r
+\r
+//N=4\r
+template<class Param1, class Param2, class Param3, class Param4, class RetType=detail::DefaultVoid>\r
+class FastDelegate4 {\r
+private:\r
+ typedef typename detail::DefaultVoidToVoid<RetType>::type DesiredRetType;\r
+ typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4);\r
+ typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4);\r
+ typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4);\r
+ typedef detail::ClosurePtr<GenericMemFn, StaticFunctionPtr, UnvoidStaticFunctionPtr> ClosureType;\r
+ ClosureType m_Closure;\r
+public:\r
+ // Typedefs to aid generic programming\r
+ typedef FastDelegate4 type;\r
+\r
+ // Construction and comparison functions\r
+ FastDelegate4() { clear(); }\r
+ FastDelegate4(const FastDelegate4 &x) {\r
+ m_Closure.CopyFrom(this, x.m_Closure); }\r
+ void operator = (const FastDelegate4 &x) {\r
+ m_Closure.CopyFrom(this, x.m_Closure); }\r
+ bool operator ==(const FastDelegate4 &x) const {\r
+ return m_Closure.IsEqual(x.m_Closure); }\r
+ bool operator !=(const FastDelegate4 &x) const {\r
+ return !m_Closure.IsEqual(x.m_Closure); }\r
+ bool operator <(const FastDelegate4 &x) const {\r
+ return m_Closure.IsLess(x.m_Closure); }\r
+ bool operator >(const FastDelegate4 &x) const {\r
+ return x.m_Closure.IsLess(m_Closure); }\r
+ // Binding to non-const member functions\r
+ template < class X, class Y >\r
+ FastDelegate4(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4) ) {\r
+ m_Closure.bindmemfunc(detail::implicit_cast<X*>(pthis), function_to_bind); }\r
+ template < class X, class Y >\r
+ inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4)) {\r
+ m_Closure.bindmemfunc(detail::implicit_cast<X*>(pthis), function_to_bind); }\r
+ // Binding to const member functions.\r
+ template < class X, class Y >\r
+ FastDelegate4(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const) {\r
+ m_Closure.bindconstmemfunc(detail::implicit_cast<const X*>(pthis), function_to_bind); }\r
+ template < class X, class Y >\r
+ inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const) {\r
+ m_Closure.bindconstmemfunc(detail::implicit_cast<const X *>(pthis), function_to_bind); }\r
+ // Static functions. We convert them into a member function call.\r
+ // This constructor also provides implicit conversion\r
+ FastDelegate4(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4) ) {\r
+ bind(function_to_bind); }\r
+ // for efficiency, prevent creation of a temporary\r
+ void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4) ) {\r
+ bind(function_to_bind); }\r
+ inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4)) {\r
+ m_Closure.bindstaticfunc(this, &FastDelegate4::InvokeStaticFunction, \r
+ function_to_bind); }\r
+ // Invoke the delegate\r
+ RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4) const {\r
+ return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4); }\r
+ // Implicit conversion to "bool" using the safe_bool idiom\r
+private:\r
+ typedef struct SafeBoolStruct {\r
+ int a_data_pointer_to_this_is_0_on_buggy_compilers;\r
+ StaticFunctionPtr m_nonzero;\r
+ } UselessTypedef;\r
+ typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type;\r
+public:\r
+ operator unspecified_bool_type() const {\r
+ return empty()? 0: &SafeBoolStruct::m_nonzero;\r
+ }\r
+ // necessary to allow ==0 to work despite the safe_bool idiom\r
+ inline bool operator==(StaticFunctionPtr funcptr) {\r
+ return m_Closure.IsEqualToStaticFuncPtr(funcptr); }\r
+ inline bool operator!=(StaticFunctionPtr funcptr) { \r
+ return !m_Closure.IsEqualToStaticFuncPtr(funcptr); }\r
+ inline bool operator ! () const { // Is it bound to anything?\r
+ return !m_Closure; }\r
+ inline bool empty() const {\r
+ return !m_Closure; }\r
+ void clear() { m_Closure.clear();}\r
+ // Conversion to and from the DelegateMemento storage class\r
+ const DelegateMemento & GetMemento() { return m_Closure; }\r
+ void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); }\r
+\r
+private: // Invoker for static functions\r
+ RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const {\r
+ return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4); }\r
+};\r
+\r
+//N=5\r
+template<class Param1, class Param2, class Param3, class Param4, class Param5, class RetType=detail::DefaultVoid>\r
+class FastDelegate5 {\r
+private:\r
+ typedef typename detail::DefaultVoidToVoid<RetType>::type DesiredRetType;\r
+ typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5);\r
+ typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5);\r
+ typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5);\r
+ typedef detail::ClosurePtr<GenericMemFn, StaticFunctionPtr, UnvoidStaticFunctionPtr> ClosureType;\r
+ ClosureType m_Closure;\r
+public:\r
+ // Typedefs to aid generic programming\r
+ typedef FastDelegate5 type;\r
+\r
+ // Construction and comparison functions\r
+ FastDelegate5() { clear(); }\r
+ FastDelegate5(const FastDelegate5 &x) {\r
+ m_Closure.CopyFrom(this, x.m_Closure); }\r
+ void operator = (const FastDelegate5 &x) {\r
+ m_Closure.CopyFrom(this, x.m_Closure); }\r
+ bool operator ==(const FastDelegate5 &x) const {\r
+ return m_Closure.IsEqual(x.m_Closure); }\r
+ bool operator !=(const FastDelegate5 &x) const {\r
+ return !m_Closure.IsEqual(x.m_Closure); }\r
+ bool operator <(const FastDelegate5 &x) const {\r
+ return m_Closure.IsLess(x.m_Closure); }\r
+ bool operator >(const FastDelegate5 &x) const {\r
+ return x.m_Closure.IsLess(m_Closure); }\r
+ // Binding to non-const member functions\r
+ template < class X, class Y >\r
+ FastDelegate5(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) ) {\r
+ m_Closure.bindmemfunc(detail::implicit_cast<X*>(pthis), function_to_bind); }\r
+ template < class X, class Y >\r
+ inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5)) {\r
+ m_Closure.bindmemfunc(detail::implicit_cast<X*>(pthis), function_to_bind); }\r
+ // Binding to const member functions.\r
+ template < class X, class Y >\r
+ FastDelegate5(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const) {\r
+ m_Closure.bindconstmemfunc(detail::implicit_cast<const X*>(pthis), function_to_bind); }\r
+ template < class X, class Y >\r
+ inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const) {\r
+ m_Closure.bindconstmemfunc(detail::implicit_cast<const X *>(pthis), function_to_bind); }\r
+ // Static functions. We convert them into a member function call.\r
+ // This constructor also provides implicit conversion\r
+ FastDelegate5(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) ) {\r
+ bind(function_to_bind); }\r
+ // for efficiency, prevent creation of a temporary\r
+ void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) ) {\r
+ bind(function_to_bind); }\r
+ inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5)) {\r
+ m_Closure.bindstaticfunc(this, &FastDelegate5::InvokeStaticFunction, \r
+ function_to_bind); }\r
+ // Invoke the delegate\r
+ RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const {\r
+ return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4, p5); }\r
+ // Implicit conversion to "bool" using the safe_bool idiom\r
+private:\r
+ typedef struct SafeBoolStruct {\r
+ int a_data_pointer_to_this_is_0_on_buggy_compilers;\r
+ StaticFunctionPtr m_nonzero;\r
+ } UselessTypedef;\r
+ typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type;\r
+public:\r
+ operator unspecified_bool_type() const {\r
+ return empty()? 0: &SafeBoolStruct::m_nonzero;\r
+ }\r
+ // necessary to allow ==0 to work despite the safe_bool idiom\r
+ inline bool operator==(StaticFunctionPtr funcptr) {\r
+ return m_Closure.IsEqualToStaticFuncPtr(funcptr); }\r
+ inline bool operator!=(StaticFunctionPtr funcptr) { \r
+ return !m_Closure.IsEqualToStaticFuncPtr(funcptr); }\r
+ inline bool operator ! () const { // Is it bound to anything?\r
+ return !m_Closure; }\r
+ inline bool empty() const {\r
+ return !m_Closure; }\r
+ void clear() { m_Closure.clear();}\r
+ // Conversion to and from the DelegateMemento storage class\r
+ const DelegateMemento & GetMemento() { return m_Closure; }\r
+ void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); }\r
+\r
+private: // Invoker for static functions\r
+ RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const {\r
+ return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4, p5); }\r
+};\r
+\r
+//N=6\r
+template<class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class RetType=detail::DefaultVoid>\r
+class FastDelegate6 {\r
+private:\r
+ typedef typename detail::DefaultVoidToVoid<RetType>::type DesiredRetType;\r
+ typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6);\r
+ typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6);\r
+ typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6);\r
+ typedef detail::ClosurePtr<GenericMemFn, StaticFunctionPtr, UnvoidStaticFunctionPtr> ClosureType;\r
+ ClosureType m_Closure;\r
+public:\r
+ // Typedefs to aid generic programming\r
+ typedef FastDelegate6 type;\r
+\r
+ // Construction and comparison functions\r
+ FastDelegate6() { clear(); }\r
+ FastDelegate6(const FastDelegate6 &x) {\r
+ m_Closure.CopyFrom(this, x.m_Closure); }\r
+ void operator = (const FastDelegate6 &x) {\r
+ m_Closure.CopyFrom(this, x.m_Closure); }\r
+ bool operator ==(const FastDelegate6 &x) const {\r
+ return m_Closure.IsEqual(x.m_Closure); }\r
+ bool operator !=(const FastDelegate6 &x) const {\r
+ return !m_Closure.IsEqual(x.m_Closure); }\r
+ bool operator <(const FastDelegate6 &x) const {\r
+ return m_Closure.IsLess(x.m_Closure); }\r
+ bool operator >(const FastDelegate6 &x) const {\r
+ return x.m_Closure.IsLess(m_Closure); }\r
+ // Binding to non-const member functions\r
+ template < class X, class Y >\r
+ FastDelegate6(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) ) {\r
+ m_Closure.bindmemfunc(detail::implicit_cast<X*>(pthis), function_to_bind); }\r
+ template < class X, class Y >\r
+ inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6)) {\r
+ m_Closure.bindmemfunc(detail::implicit_cast<X*>(pthis), function_to_bind); }\r
+ // Binding to const member functions.\r
+ template < class X, class Y >\r
+ FastDelegate6(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const) {\r
+ m_Closure.bindconstmemfunc(detail::implicit_cast<const X*>(pthis), function_to_bind); }\r
+ template < class X, class Y >\r
+ inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const) {\r
+ m_Closure.bindconstmemfunc(detail::implicit_cast<const X *>(pthis), function_to_bind); }\r
+ // Static functions. We convert them into a member function call.\r
+ // This constructor also provides implicit conversion\r
+ FastDelegate6(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) ) {\r
+ bind(function_to_bind); }\r
+ // for efficiency, prevent creation of a temporary\r
+ void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) ) {\r
+ bind(function_to_bind); }\r
+ inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6)) {\r
+ m_Closure.bindstaticfunc(this, &FastDelegate6::InvokeStaticFunction, \r
+ function_to_bind); }\r
+ // Invoke the delegate\r
+ RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const {\r
+ return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4, p5, p6); }\r
+ // Implicit conversion to "bool" using the safe_bool idiom\r
+private:\r
+ typedef struct SafeBoolStruct {\r
+ int a_data_pointer_to_this_is_0_on_buggy_compilers;\r
+ StaticFunctionPtr m_nonzero;\r
+ } UselessTypedef;\r
+ typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type;\r
+public:\r
+ operator unspecified_bool_type() const {\r
+ return empty()? 0: &SafeBoolStruct::m_nonzero;\r
+ }\r
+ // necessary to allow ==0 to work despite the safe_bool idiom\r
+ inline bool operator==(StaticFunctionPtr funcptr) {\r
+ return m_Closure.IsEqualToStaticFuncPtr(funcptr); }\r
+ inline bool operator!=(StaticFunctionPtr funcptr) { \r
+ return !m_Closure.IsEqualToStaticFuncPtr(funcptr); }\r
+ inline bool operator ! () const { // Is it bound to anything?\r
+ return !m_Closure; }\r
+ inline bool empty() const {\r
+ return !m_Closure; }\r
+ void clear() { m_Closure.clear();}\r
+ // Conversion to and from the DelegateMemento storage class\r
+ const DelegateMemento & GetMemento() { return m_Closure; }\r
+ void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); }\r
+\r
+private: // Invoker for static functions\r
+ RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const {\r
+ return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4, p5, p6); }\r
+};\r
+\r
+//N=7\r
+template<class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class RetType=detail::DefaultVoid>\r
+class FastDelegate7 {\r
+private:\r
+ typedef typename detail::DefaultVoidToVoid<RetType>::type DesiredRetType;\r
+ typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7);\r
+ typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7);\r
+ typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7);\r
+ typedef detail::ClosurePtr<GenericMemFn, StaticFunctionPtr, UnvoidStaticFunctionPtr> ClosureType;\r
+ ClosureType m_Closure;\r
+public:\r
+ // Typedefs to aid generic programming\r
+ typedef FastDelegate7 type;\r
+\r
+ // Construction and comparison functions\r
+ FastDelegate7() { clear(); }\r
+ FastDelegate7(const FastDelegate7 &x) {\r
+ m_Closure.CopyFrom(this, x.m_Closure); }\r
+ void operator = (const FastDelegate7 &x) {\r
+ m_Closure.CopyFrom(this, x.m_Closure); }\r
+ bool operator ==(const FastDelegate7 &x) const {\r
+ return m_Closure.IsEqual(x.m_Closure); }\r
+ bool operator !=(const FastDelegate7 &x) const {\r
+ return !m_Closure.IsEqual(x.m_Closure); }\r
+ bool operator <(const FastDelegate7 &x) const {\r
+ return m_Closure.IsLess(x.m_Closure); }\r
+ bool operator >(const FastDelegate7 &x) const {\r
+ return x.m_Closure.IsLess(m_Closure); }\r
+ // Binding to non-const member functions\r
+ template < class X, class Y >\r
+ FastDelegate7(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) ) {\r
+ m_Closure.bindmemfunc(detail::implicit_cast<X*>(pthis), function_to_bind); }\r
+ template < class X, class Y >\r
+ inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7)) {\r
+ m_Closure.bindmemfunc(detail::implicit_cast<X*>(pthis), function_to_bind); }\r
+ // Binding to const member functions.\r
+ template < class X, class Y >\r
+ FastDelegate7(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const) {\r
+ m_Closure.bindconstmemfunc(detail::implicit_cast<const X*>(pthis), function_to_bind); }\r
+ template < class X, class Y >\r
+ inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const) {\r
+ m_Closure.bindconstmemfunc(detail::implicit_cast<const X *>(pthis), function_to_bind); }\r
+ // Static functions. We convert them into a member function call.\r
+ // This constructor also provides implicit conversion\r
+ FastDelegate7(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) ) {\r
+ bind(function_to_bind); }\r
+ // for efficiency, prevent creation of a temporary\r
+ void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) ) {\r
+ bind(function_to_bind); }\r
+ inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7)) {\r
+ m_Closure.bindstaticfunc(this, &FastDelegate7::InvokeStaticFunction, \r
+ function_to_bind); }\r
+ // Invoke the delegate\r
+ RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const {\r
+ return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4, p5, p6, p7); }\r
+ // Implicit conversion to "bool" using the safe_bool idiom\r
+private:\r
+ typedef struct SafeBoolStruct {\r
+ int a_data_pointer_to_this_is_0_on_buggy_compilers;\r
+ StaticFunctionPtr m_nonzero;\r
+ } UselessTypedef;\r
+ typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type;\r
+public:\r
+ operator unspecified_bool_type() const {\r
+ return empty()? 0: &SafeBoolStruct::m_nonzero;\r
+ }\r
+ // necessary to allow ==0 to work despite the safe_bool idiom\r
+ inline bool operator==(StaticFunctionPtr funcptr) {\r
+ return m_Closure.IsEqualToStaticFuncPtr(funcptr); }\r
+ inline bool operator!=(StaticFunctionPtr funcptr) { \r
+ return !m_Closure.IsEqualToStaticFuncPtr(funcptr); }\r
+ inline bool operator ! () const { // Is it bound to anything?\r
+ return !m_Closure; }\r
+ inline bool empty() const {\r
+ return !m_Closure; }\r
+ void clear() { m_Closure.clear();}\r
+ // Conversion to and from the DelegateMemento storage class\r
+ const DelegateMemento & GetMemento() { return m_Closure; }\r
+ void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); }\r
+\r
+private: // Invoker for static functions\r
+ RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const {\r
+ return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4, p5, p6, p7); }\r
+};\r
+\r
+//N=8\r
+template<class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class RetType=detail::DefaultVoid>\r
+class FastDelegate8 {\r
+private:\r
+ typedef typename detail::DefaultVoidToVoid<RetType>::type DesiredRetType;\r
+ typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8);\r
+ typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8);\r
+ typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8);\r
+ typedef detail::ClosurePtr<GenericMemFn, StaticFunctionPtr, UnvoidStaticFunctionPtr> ClosureType;\r
+ ClosureType m_Closure;\r
+public:\r
+ // Typedefs to aid generic programming\r
+ typedef FastDelegate8 type;\r
+\r
+ // Construction and comparison functions\r
+ FastDelegate8() { clear(); }\r
+ FastDelegate8(const FastDelegate8 &x) {\r
+ m_Closure.CopyFrom(this, x.m_Closure); }\r
+ void operator = (const FastDelegate8 &x) {\r
+ m_Closure.CopyFrom(this, x.m_Closure); }\r
+ bool operator ==(const FastDelegate8 &x) const {\r
+ return m_Closure.IsEqual(x.m_Closure); }\r
+ bool operator !=(const FastDelegate8 &x) const {\r
+ return !m_Closure.IsEqual(x.m_Closure); }\r
+ bool operator <(const FastDelegate8 &x) const {\r
+ return m_Closure.IsLess(x.m_Closure); }\r
+ bool operator >(const FastDelegate8 &x) const {\r
+ return x.m_Closure.IsLess(m_Closure); }\r
+ // Binding to non-const member functions\r
+ template < class X, class Y >\r
+ FastDelegate8(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) ) {\r
+ m_Closure.bindmemfunc(detail::implicit_cast<X*>(pthis), function_to_bind); }\r
+ template < class X, class Y >\r
+ inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8)) {\r
+ m_Closure.bindmemfunc(detail::implicit_cast<X*>(pthis), function_to_bind); }\r
+ // Binding to const member functions.\r
+ template < class X, class Y >\r
+ FastDelegate8(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const) {\r
+ m_Closure.bindconstmemfunc(detail::implicit_cast<const X*>(pthis), function_to_bind); }\r
+ template < class X, class Y >\r
+ inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const) {\r
+ m_Closure.bindconstmemfunc(detail::implicit_cast<const X *>(pthis), function_to_bind); }\r
+ // Static functions. We convert them into a member function call.\r
+ // This constructor also provides implicit conversion\r
+ FastDelegate8(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) ) {\r
+ bind(function_to_bind); }\r
+ // for efficiency, prevent creation of a temporary\r
+ void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) ) {\r
+ bind(function_to_bind); }\r
+ inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8)) {\r
+ m_Closure.bindstaticfunc(this, &FastDelegate8::InvokeStaticFunction, \r
+ function_to_bind); }\r
+ // Invoke the delegate\r
+ RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const {\r
+ return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4, p5, p6, p7, p8); }\r
+ // Implicit conversion to "bool" using the safe_bool idiom\r
+private:\r
+ typedef struct SafeBoolStruct {\r
+ int a_data_pointer_to_this_is_0_on_buggy_compilers;\r
+ StaticFunctionPtr m_nonzero;\r
+ } UselessTypedef;\r
+ typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type;\r
+public:\r
+ operator unspecified_bool_type() const {\r
+ return empty()? 0: &SafeBoolStruct::m_nonzero;\r
+ }\r
+ // necessary to allow ==0 to work despite the safe_bool idiom\r
+ inline bool operator==(StaticFunctionPtr funcptr) {\r
+ return m_Closure.IsEqualToStaticFuncPtr(funcptr); }\r
+ inline bool operator!=(StaticFunctionPtr funcptr) { \r
+ return !m_Closure.IsEqualToStaticFuncPtr(funcptr); }\r
+ inline bool operator ! () const { // Is it bound to anything?\r
+ return !m_Closure; }\r
+ inline bool empty() const {\r
+ return !m_Closure; }\r
+ void clear() { m_Closure.clear();}\r
+ // Conversion to and from the DelegateMemento storage class\r
+ const DelegateMemento & GetMemento() { return m_Closure; }\r
+ void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); }\r
+\r
+private: // Invoker for static functions\r
+ RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const {\r
+ return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4, p5, p6, p7, p8); }\r
+};\r
+\r
+\r
+////////////////////////////////////////////////////////////////////////////////\r
+// Fast Delegates, part 4:\r
+// \r
+// FastDelegate<> class (Original author: Jody Hagins)\r
+// Allows boost::function style syntax like:\r
+// FastDelegate< double (int, long) >\r
+// instead of:\r
+// FastDelegate2< int, long, double >\r
+//\r
+////////////////////////////////////////////////////////////////////////////////\r
+\r
+#ifdef FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX\r
+\r
+// Declare FastDelegate as a class template. It will be specialized\r
+// later for all number of arguments.\r
+template <typename Signature>\r
+class FastDelegate;\r
+\r
+//N=0\r
+// Specialization to allow use of\r
+// FastDelegate< R ( ) >\r
+// instead of \r
+// FastDelegate0 < R >\r
+template<typename R>\r
+class FastDelegate< R ( ) >\r
+ // Inherit from FastDelegate0 so that it can be treated just like a FastDelegate0\r
+ : public FastDelegate0 < R >\r
+{\r
+public:\r
+ // Make using the base type a bit easier via typedef.\r
+ typedef FastDelegate0 < R > BaseType;\r
+\r
+ // Allow users access to the specific type of this delegate.\r
+ typedef FastDelegate SelfType;\r
+\r
+ // Mimic the base class constructors.\r
+ FastDelegate() : BaseType() { }\r
+\r
+ template < class X, class Y >\r
+ FastDelegate(Y * pthis, \r
+ R (X::* function_to_bind)( ))\r
+ : BaseType(pthis, function_to_bind) { }\r
+\r
+ template < class X, class Y >\r
+ FastDelegate(const Y *pthis,\r
+ R (X::* function_to_bind)( ) const)\r
+ : BaseType(pthis, function_to_bind)\r
+ { }\r
+\r
+ FastDelegate(R (*function_to_bind)( ))\r
+ : BaseType(function_to_bind) { }\r
+ void operator = (const BaseType &x) { \r
+ *static_cast<BaseType*>(this) = x; }\r
+};\r
+\r
+//N=1\r
+// Specialization to allow use of\r
+// FastDelegate< R ( Param1 ) >\r
+// instead of \r
+// FastDelegate1 < Param1, R >\r
+template<typename R, class Param1>\r
+class FastDelegate< R ( Param1 ) >\r
+ // Inherit from FastDelegate1 so that it can be treated just like a FastDelegate1\r
+ : public FastDelegate1 < Param1, R >\r
+{\r
+public:\r
+ // Make using the base type a bit easier via typedef.\r
+ typedef FastDelegate1 < Param1, R > BaseType;\r
+\r
+ // Allow users access to the specific type of this delegate.\r
+ typedef FastDelegate SelfType;\r
+\r
+ // Mimic the base class constructors.\r
+ FastDelegate() : BaseType() { }\r
+\r
+ template < class X, class Y >\r
+ FastDelegate(Y * pthis, \r
+ R (X::* function_to_bind)( Param1 p1 ))\r
+ : BaseType(pthis, function_to_bind) { }\r
+\r
+ template < class X, class Y >\r
+ FastDelegate(const Y *pthis,\r
+ R (X::* function_to_bind)( Param1 p1 ) const)\r
+ : BaseType(pthis, function_to_bind)\r
+ { }\r
+\r
+ FastDelegate(R (*function_to_bind)( Param1 p1 ))\r
+ : BaseType(function_to_bind) { }\r
+ void operator = (const BaseType &x) { \r
+ *static_cast<BaseType*>(this) = x; }\r
+};\r
+\r
+//N=2\r
+// Specialization to allow use of\r
+// FastDelegate< R ( Param1, Param2 ) >\r
+// instead of \r
+// FastDelegate2 < Param1, Param2, R >\r
+template<typename R, class Param1, class Param2>\r
+class FastDelegate< R ( Param1, Param2 ) >\r
+ // Inherit from FastDelegate2 so that it can be treated just like a FastDelegate2\r
+ : public FastDelegate2 < Param1, Param2, R >\r
+{\r
+public:\r
+ // Make using the base type a bit easier via typedef.\r
+ typedef FastDelegate2 < Param1, Param2, R > BaseType;\r
+\r
+ // Allow users access to the specific type of this delegate.\r
+ typedef FastDelegate SelfType;\r
+\r
+ // Mimic the base class constructors.\r
+ FastDelegate() : BaseType() { }\r
+\r
+ template < class X, class Y >\r
+ FastDelegate(Y * pthis, \r
+ R (X::* function_to_bind)( Param1 p1, Param2 p2 ))\r
+ : BaseType(pthis, function_to_bind) { }\r
+\r
+ template < class X, class Y >\r
+ FastDelegate(const Y *pthis,\r
+ R (X::* function_to_bind)( Param1 p1, Param2 p2 ) const)\r
+ : BaseType(pthis, function_to_bind)\r
+ { }\r
+\r
+ FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2 ))\r
+ : BaseType(function_to_bind) { }\r
+ void operator = (const BaseType &x) { \r
+ *static_cast<BaseType*>(this) = x; }\r
+};\r
+\r
+//N=3\r
+// Specialization to allow use of\r
+// FastDelegate< R ( Param1, Param2, Param3 ) >\r
+// instead of \r
+// FastDelegate3 < Param1, Param2, Param3, R >\r
+template<typename R, class Param1, class Param2, class Param3>\r
+class FastDelegate< R ( Param1, Param2, Param3 ) >\r
+ // Inherit from FastDelegate3 so that it can be treated just like a FastDelegate3\r
+ : public FastDelegate3 < Param1, Param2, Param3, R >\r
+{\r
+public:\r
+ // Make using the base type a bit easier via typedef.\r
+ typedef FastDelegate3 < Param1, Param2, Param3, R > BaseType;\r
+\r
+ // Allow users access to the specific type of this delegate.\r
+ typedef FastDelegate SelfType;\r
+\r
+ // Mimic the base class constructors.\r
+ FastDelegate() : BaseType() { }\r
+\r
+ template < class X, class Y >\r
+ FastDelegate(Y * pthis, \r
+ R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3 ))\r
+ : BaseType(pthis, function_to_bind) { }\r
+\r
+ template < class X, class Y >\r
+ FastDelegate(const Y *pthis,\r
+ R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3 ) const)\r
+ : BaseType(pthis, function_to_bind)\r
+ { }\r
+\r
+ FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3 ))\r
+ : BaseType(function_to_bind) { }\r
+ void operator = (const BaseType &x) { \r
+ *static_cast<BaseType*>(this) = x; }\r
+};\r
+\r
+//N=4\r
+// Specialization to allow use of\r
+// FastDelegate< R ( Param1, Param2, Param3, Param4 ) >\r
+// instead of \r
+// FastDelegate4 < Param1, Param2, Param3, Param4, R >\r
+template<typename R, class Param1, class Param2, class Param3, class Param4>\r
+class FastDelegate< R ( Param1, Param2, Param3, Param4 ) >\r
+ // Inherit from FastDelegate4 so that it can be treated just like a FastDelegate4\r
+ : public FastDelegate4 < Param1, Param2, Param3, Param4, R >\r
+{\r
+public:\r
+ // Make using the base type a bit easier via typedef.\r
+ typedef FastDelegate4 < Param1, Param2, Param3, Param4, R > BaseType;\r
+\r
+ // Allow users access to the specific type of this delegate.\r
+ typedef FastDelegate SelfType;\r
+\r
+ // Mimic the base class constructors.\r
+ FastDelegate() : BaseType() { }\r
+\r
+ template < class X, class Y >\r
+ FastDelegate(Y * pthis, \r
+ R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4 ))\r
+ : BaseType(pthis, function_to_bind) { }\r
+\r
+ template < class X, class Y >\r
+ FastDelegate(const Y *pthis,\r
+ R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4 ) const)\r
+ : BaseType(pthis, function_to_bind)\r
+ { }\r
+\r
+ FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4 ))\r
+ : BaseType(function_to_bind) { }\r
+ void operator = (const BaseType &x) { \r
+ *static_cast<BaseType*>(this) = x; }\r
+};\r
+\r
+//N=5\r
+// Specialization to allow use of\r
+// FastDelegate< R ( Param1, Param2, Param3, Param4, Param5 ) >\r
+// instead of \r
+// FastDelegate5 < Param1, Param2, Param3, Param4, Param5, R >\r
+template<typename R, class Param1, class Param2, class Param3, class Param4, class Param5>\r
+class FastDelegate< R ( Param1, Param2, Param3, Param4, Param5 ) >\r
+ // Inherit from FastDelegate5 so that it can be treated just like a FastDelegate5\r
+ : public FastDelegate5 < Param1, Param2, Param3, Param4, Param5, R >\r
+{\r
+public:\r
+ // Make using the base type a bit easier via typedef.\r
+ typedef FastDelegate5 < Param1, Param2, Param3, Param4, Param5, R > BaseType;\r
+\r
+ // Allow users access to the specific type of this delegate.\r
+ typedef FastDelegate SelfType;\r
+\r
+ // Mimic the base class constructors.\r
+ FastDelegate() : BaseType() { }\r
+\r
+ template < class X, class Y >\r
+ FastDelegate(Y * pthis, \r
+ R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5 ))\r
+ : BaseType(pthis, function_to_bind) { }\r
+\r
+ template < class X, class Y >\r
+ FastDelegate(const Y *pthis,\r
+ R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5 ) const)\r
+ : BaseType(pthis, function_to_bind)\r
+ { }\r
+\r
+ FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5 ))\r
+ : BaseType(function_to_bind) { }\r
+ void operator = (const BaseType &x) { \r
+ *static_cast<BaseType*>(this) = x; }\r
+};\r
+\r
+//N=6\r
+// Specialization to allow use of\r
+// FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6 ) >\r
+// instead of \r
+// FastDelegate6 < Param1, Param2, Param3, Param4, Param5, Param6, R >\r
+template<typename R, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6>\r
+class FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6 ) >\r
+ // Inherit from FastDelegate6 so that it can be treated just like a FastDelegate6\r
+ : public FastDelegate6 < Param1, Param2, Param3, Param4, Param5, Param6, R >\r
+{\r
+public:\r
+ // Make using the base type a bit easier via typedef.\r
+ typedef FastDelegate6 < Param1, Param2, Param3, Param4, Param5, Param6, R > BaseType;\r
+\r
+ // Allow users access to the specific type of this delegate.\r
+ typedef FastDelegate SelfType;\r
+\r
+ // Mimic the base class constructors.\r
+ FastDelegate() : BaseType() { }\r
+\r
+ template < class X, class Y >\r
+ FastDelegate(Y * pthis, \r
+ R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6 ))\r
+ : BaseType(pthis, function_to_bind) { }\r
+\r
+ template < class X, class Y >\r
+ FastDelegate(const Y *pthis,\r
+ R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6 ) const)\r
+ : BaseType(pthis, function_to_bind)\r
+ { }\r
+\r
+ FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6 ))\r
+ : BaseType(function_to_bind) { }\r
+ void operator = (const BaseType &x) { \r
+ *static_cast<BaseType*>(this) = x; }\r
+};\r
+\r
+//N=7\r
+// Specialization to allow use of\r
+// FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7 ) >\r
+// instead of \r
+// FastDelegate7 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, R >\r
+template<typename R, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7>\r
+class FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7 ) >\r
+ // Inherit from FastDelegate7 so that it can be treated just like a FastDelegate7\r
+ : public FastDelegate7 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, R >\r
+{\r
+public:\r
+ // Make using the base type a bit easier via typedef.\r
+ typedef FastDelegate7 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, R > BaseType;\r
+\r
+ // Allow users access to the specific type of this delegate.\r
+ typedef FastDelegate SelfType;\r
+\r
+ // Mimic the base class constructors.\r
+ FastDelegate() : BaseType() { }\r
+\r
+ template < class X, class Y >\r
+ FastDelegate(Y * pthis, \r
+ R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7 ))\r
+ : BaseType(pthis, function_to_bind) { }\r
+\r
+ template < class X, class Y >\r
+ FastDelegate(const Y *pthis,\r
+ R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7 ) const)\r
+ : BaseType(pthis, function_to_bind)\r
+ { }\r
+\r
+ FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7 ))\r
+ : BaseType(function_to_bind) { }\r
+ void operator = (const BaseType &x) { \r
+ *static_cast<BaseType*>(this) = x; }\r
+};\r
+\r
+//N=8\r
+// Specialization to allow use of\r
+// FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8 ) >\r
+// instead of \r
+// FastDelegate8 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, R >\r
+template<typename R, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8>\r
+class FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8 ) >\r
+ // Inherit from FastDelegate8 so that it can be treated just like a FastDelegate8\r
+ : public FastDelegate8 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, R >\r
+{\r
+public:\r
+ // Make using the base type a bit easier via typedef.\r
+ typedef FastDelegate8 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, R > BaseType;\r
+\r
+ // Allow users access to the specific type of this delegate.\r
+ typedef FastDelegate SelfType;\r
+\r
+ // Mimic the base class constructors.\r
+ FastDelegate() : BaseType() { }\r
+\r
+ template < class X, class Y >\r
+ FastDelegate(Y * pthis, \r
+ R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8 ))\r
+ : BaseType(pthis, function_to_bind) { }\r
+\r
+ template < class X, class Y >\r
+ FastDelegate(const Y *pthis,\r
+ R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8 ) const)\r
+ : BaseType(pthis, function_to_bind)\r
+ { }\r
+\r
+ FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8 ))\r
+ : BaseType(function_to_bind) { }\r
+ void operator = (const BaseType &x) { \r
+ *static_cast<BaseType*>(this) = x; }\r
+};\r
+\r
+\r
+#endif //FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX\r
+\r
+////////////////////////////////////////////////////////////////////////////////\r
+// Fast Delegates, part 5:\r
+//\r
+// MakeDelegate() helper function\r
+//\r
+// MakeDelegate(&x, &X::func) returns a fastdelegate of the type\r
+// necessary for calling x.func() with the correct number of arguments.\r
+// This makes it possible to eliminate many typedefs from user code.\r
+//\r
+////////////////////////////////////////////////////////////////////////////////\r
+\r
+// Also declare overloads of a MakeDelegate() global function to \r
+// reduce the need for typedefs.\r
+// We need seperate overloads for const and non-const member functions.\r
+// Also, because of the weird rule about the class of derived member function pointers,\r
+// implicit downcasts may need to be applied later to the 'this' pointer.\r
+// That's why two classes (X and Y) appear in the definitions. Y must be implicitly\r
+// castable to X.\r
+\r
+// Workaround for VC6. VC6 needs void return types converted into DefaultVoid.\r
+// GCC 3.2 and later won't compile this unless it's preceded by 'typename',\r
+// but VC6 doesn't allow 'typename' in this context.\r
+// So, I have to use a macro.\r
+\r
+#ifdef FASTDLGT_VC6\r
+#define FASTDLGT_RETTYPE detail::VoidToDefaultVoid<RetType>::type\r
+#else \r
+#define FASTDLGT_RETTYPE RetType\r
+#endif\r
+\r
+//N=0\r
+template <class X, class Y, class RetType>\r
+FastDelegate0<FASTDLGT_RETTYPE> MakeDelegate(Y* x, RetType (X::*func)()) { \r
+ return FastDelegate0<FASTDLGT_RETTYPE>(x, func);\r
+}\r
+\r
+template <class X, class Y, class RetType>\r
+FastDelegate0<FASTDLGT_RETTYPE> MakeDelegate(Y* x, RetType (X::*func)() const) { \r
+ return FastDelegate0<FASTDLGT_RETTYPE>(x, func);\r
+}\r
+\r
+//N=1\r
+template <class X, class Y, class Param1, class RetType>\r
+FastDelegate1<Param1, FASTDLGT_RETTYPE> MakeDelegate(Y* x, RetType (X::*func)(Param1 p1)) { \r
+ return FastDelegate1<Param1, FASTDLGT_RETTYPE>(x, func);\r
+}\r
+\r
+template <class X, class Y, class Param1, class RetType>\r
+FastDelegate1<Param1, FASTDLGT_RETTYPE> MakeDelegate(Y* x, RetType (X::*func)(Param1 p1) const) { \r
+ return FastDelegate1<Param1, FASTDLGT_RETTYPE>(x, func);\r
+}\r
+\r
+//N=2\r
+template <class X, class Y, class Param1, class Param2, class RetType>\r
+FastDelegate2<Param1, Param2, FASTDLGT_RETTYPE> MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2)) { \r
+ return FastDelegate2<Param1, Param2, FASTDLGT_RETTYPE>(x, func);\r
+}\r
+\r
+template <class X, class Y, class Param1, class Param2, class RetType>\r
+FastDelegate2<Param1, Param2, FASTDLGT_RETTYPE> MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2) const) { \r
+ return FastDelegate2<Param1, Param2, FASTDLGT_RETTYPE>(x, func);\r
+}\r
+\r
+//N=3\r
+template <class X, class Y, class Param1, class Param2, class Param3, class RetType>\r
+FastDelegate3<Param1, Param2, Param3, FASTDLGT_RETTYPE> MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3)) { \r
+ return FastDelegate3<Param1, Param2, Param3, FASTDLGT_RETTYPE>(x, func);\r
+}\r
+\r
+template <class X, class Y, class Param1, class Param2, class Param3, class RetType>\r
+FastDelegate3<Param1, Param2, Param3, FASTDLGT_RETTYPE> MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3) const) { \r
+ return FastDelegate3<Param1, Param2, Param3, FASTDLGT_RETTYPE>(x, func);\r
+}\r
+\r
+//N=4\r
+template <class X, class Y, class Param1, class Param2, class Param3, class Param4, class RetType>\r
+FastDelegate4<Param1, Param2, Param3, Param4, FASTDLGT_RETTYPE> MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4)) { \r
+ return FastDelegate4<Param1, Param2, Param3, Param4, FASTDLGT_RETTYPE>(x, func);\r
+}\r
+\r
+template <class X, class Y, class Param1, class Param2, class Param3, class Param4, class RetType>\r
+FastDelegate4<Param1, Param2, Param3, Param4, FASTDLGT_RETTYPE> MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const) { \r
+ return FastDelegate4<Param1, Param2, Param3, Param4, FASTDLGT_RETTYPE>(x, func);\r
+}\r
+\r
+//N=5\r
+template <class X, class Y, class Param1, class Param2, class Param3, class Param4, class Param5, class RetType>\r
+FastDelegate5<Param1, Param2, Param3, Param4, Param5, FASTDLGT_RETTYPE> MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5)) { \r
+ return FastDelegate5<Param1, Param2, Param3, Param4, Param5, FASTDLGT_RETTYPE>(x, func);\r
+}\r
+\r
+template <class X, class Y, class Param1, class Param2, class Param3, class Param4, class Param5, class RetType>\r
+FastDelegate5<Param1, Param2, Param3, Param4, Param5, FASTDLGT_RETTYPE> MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const) { \r
+ return FastDelegate5<Param1, Param2, Param3, Param4, Param5, FASTDLGT_RETTYPE>(x, func);\r
+}\r
+\r
+//N=6\r
+template <class X, class Y, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class RetType>\r
+FastDelegate6<Param1, Param2, Param3, Param4, Param5, Param6, FASTDLGT_RETTYPE> MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6)) { \r
+ return FastDelegate6<Param1, Param2, Param3, Param4, Param5, Param6, FASTDLGT_RETTYPE>(x, func);\r
+}\r
+\r
+template <class X, class Y, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class RetType>\r
+FastDelegate6<Param1, Param2, Param3, Param4, Param5, Param6, FASTDLGT_RETTYPE> MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const) { \r
+ return FastDelegate6<Param1, Param2, Param3, Param4, Param5, Param6, FASTDLGT_RETTYPE>(x, func);\r
+}\r
+\r
+//N=7\r
+template <class X, class Y, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class RetType>\r
+FastDelegate7<Param1, Param2, Param3, Param4, Param5, Param6, Param7, FASTDLGT_RETTYPE> MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7)) { \r
+ return FastDelegate7<Param1, Param2, Param3, Param4, Param5, Param6, Param7, FASTDLGT_RETTYPE>(x, func);\r
+}\r
+\r
+template <class X, class Y, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class RetType>\r
+FastDelegate7<Param1, Param2, Param3, Param4, Param5, Param6, Param7, FASTDLGT_RETTYPE> MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const) { \r
+ return FastDelegate7<Param1, Param2, Param3, Param4, Param5, Param6, Param7, FASTDLGT_RETTYPE>(x, func);\r
+}\r
+\r
+//N=8\r
+template <class X, class Y, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class RetType>\r
+FastDelegate8<Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, FASTDLGT_RETTYPE> MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8)) { \r
+ return FastDelegate8<Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, FASTDLGT_RETTYPE>(x, func);\r
+}\r
+\r
+template <class X, class Y, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class RetType>\r
+FastDelegate8<Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, FASTDLGT_RETTYPE> MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const) { \r
+ return FastDelegate8<Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, FASTDLGT_RETTYPE>(x, func);\r
+}\r
+\r
+\r
+ // clean up after ourselves...\r
+#undef FASTDLGT_RETTYPE\r
+\r
+} // namespace fastdelegate\r
+\r
+#endif // !defined(FASTDELEGATE_H)\r
+\r
--- /dev/null
+// FastDelegateBind.h \r
+// Helper file for FastDelegates. Provides bind() function, enabling\r
+// FastDelegates to be rapidly compared to programs using boost::function and boost::bind.\r
+//\r
+// Documentation is found at http://www.codeproject.com/cpp/FastDelegate.asp\r
+//\r
+// Original author: Jody Hagins.\r
+// Minor changes by Don Clugston.\r
+//\r
+// Warning: The arguments to 'bind' are ignored! No actual binding is performed.\r
+// The behaviour is equivalent to boost::bind only when the basic placeholder \r
+// arguments _1, _2, _3, etc are used in order.\r
+//\r
+// HISTORY:\r
+// 1.4 Dec 2004. Initial release as part of FastDelegate 1.4.\r
+\r
+\r
+#ifndef FASTDELEGATEBIND_H\r
+#define FASTDELEGATEBIND_H\r
+#if _MSC_VER > 1000\r
+#pragma once\r
+#endif // _MSC_VER > 1000\r
+\r
+////////////////////////////////////////////////////////////////////////////////\r
+// FastDelegate bind()\r
+//\r
+// bind() helper function for boost compatibility.\r
+// (Original author: Jody Hagins).\r
+//\r
+// Add another helper, so FastDelegate can be a dropin replacement\r
+// for boost::bind (in a fair number of cases).\r
+// Note the elipses, because boost::bind() takes place holders\r
+// but FastDelegate does not care about them. Getting the place holder\r
+// mechanism to work, and play well with boost is a bit tricky, so\r
+// we do the "easy" thing...\r
+// Assume we have the following code...\r
+// using boost::bind;\r
+// bind(&Foo:func, &foo, _1, _2);\r
+// we should be able to replace the "using" with...\r
+// using fastdelegate::bind;\r
+// and everything should work fine...\r
+////////////////////////////////////////////////////////////////////////////////\r
+\r
+#ifdef FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX\r
+\r
+namespace fastdelegate {\r
+\r
+//N=0\r
+template <class X, class Y, class RetType>\r
+FastDelegate< RetType ( ) >\r
+bind(\r
+ RetType (X::*func)( ),\r
+ Y * y,\r
+ ...)\r
+{ \r
+ return FastDelegate< RetType ( ) >(y, func);\r
+}\r
+\r
+template <class X, class Y, class RetType>\r
+FastDelegate< RetType ( ) >\r
+bind(\r
+ RetType (X::*func)( ) const,\r
+ Y * y,\r
+ ...)\r
+{ \r
+ return FastDelegate< RetType ( ) >(y, func);\r
+}\r
+\r
+//N=1\r
+template <class X, class Y, class RetType, class Param1>\r
+FastDelegate< RetType ( Param1 p1 ) >\r
+bind(\r
+ RetType (X::*func)( Param1 p1 ),\r
+ Y * y,\r
+ ...)\r
+{ \r
+ return FastDelegate< RetType ( Param1 p1 ) >(y, func);\r
+}\r
+\r
+template <class X, class Y, class RetType, class Param1>\r
+FastDelegate< RetType ( Param1 p1 ) >\r
+bind(\r
+ RetType (X::*func)( Param1 p1 ) const,\r
+ Y * y,\r
+ ...)\r
+{ \r
+ return FastDelegate< RetType ( Param1 p1 ) >(y, func);\r
+}\r
+\r
+//N=2\r
+template <class X, class Y, class RetType, class Param1, class Param2>\r
+FastDelegate< RetType ( Param1 p1, Param2 p2 ) >\r
+bind(\r
+ RetType (X::*func)( Param1 p1, Param2 p2 ),\r
+ Y * y,\r
+ ...)\r
+{ \r
+ return FastDelegate< RetType ( Param1 p1, Param2 p2 ) >(y, func);\r
+}\r
+\r
+template <class X, class Y, class RetType, class Param1, class Param2>\r
+FastDelegate< RetType ( Param1 p1, Param2 p2 ) >\r
+bind(\r
+ RetType (X::*func)( Param1 p1, Param2 p2 ) const,\r
+ Y * y,\r
+ ...)\r
+{ \r
+ return FastDelegate< RetType ( Param1 p1, Param2 p2 ) >(y, func);\r
+}\r
+\r
+//N=3\r
+template <class X, class Y, class RetType, class Param1, class Param2, class Param3>\r
+FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3 ) >\r
+bind(\r
+ RetType (X::*func)( Param1 p1, Param2 p2, Param3 p3 ),\r
+ Y * y,\r
+ ...)\r
+{ \r
+ return FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3 ) >(y, func);\r
+}\r
+\r
+template <class X, class Y, class RetType, class Param1, class Param2, class Param3>\r
+FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3 ) >\r
+bind(\r
+ RetType (X::*func)( Param1 p1, Param2 p2, Param3 p3 ) const,\r
+ Y * y,\r
+ ...)\r
+{ \r
+ return FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3 ) >(y, func);\r
+}\r
+\r
+//N=4\r
+template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4>\r
+FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4 ) >\r
+bind(\r
+ RetType (X::*func)( Param1 p1, Param2 p2, Param3 p3, Param4 p4 ),\r
+ Y * y,\r
+ ...)\r
+{ \r
+ return FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4 ) >(y, func);\r
+}\r
+\r
+template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4>\r
+FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4 ) >\r
+bind(\r
+ RetType (X::*func)( Param1 p1, Param2 p2, Param3 p3, Param4 p4 ) const,\r
+ Y * y,\r
+ ...)\r
+{ \r
+ return FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4 ) >(y, func);\r
+}\r
+\r
+//N=5\r
+template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5>\r
+FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5 ) >\r
+bind(\r
+ RetType (X::*func)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5 ),\r
+ Y * y,\r
+ ...)\r
+{ \r
+ return FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5 ) >(y, func);\r
+}\r
+\r
+template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5>\r
+FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5 ) >\r
+bind(\r
+ RetType (X::*func)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5 ) const,\r
+ Y * y,\r
+ ...)\r
+{ \r
+ return FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5 ) >(y, func);\r
+}\r
+\r
+//N=6\r
+template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6>\r
+FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6 ) >\r
+bind(\r
+ RetType (X::*func)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6 ),\r
+ Y * y,\r
+ ...)\r
+{ \r
+ return FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6 ) >(y, func);\r
+}\r
+\r
+template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6>\r
+FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6 ) >\r
+bind(\r
+ RetType (X::*func)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6 ) const,\r
+ Y * y,\r
+ ...)\r
+{ \r
+ return FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6 ) >(y, func);\r
+}\r
+\r
+//N=7\r
+template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7>\r
+FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7 ) >\r
+bind(\r
+ RetType (X::*func)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7 ),\r
+ Y * y,\r
+ ...)\r
+{ \r
+ return FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7 ) >(y, func);\r
+}\r
+\r
+template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7>\r
+FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7 ) >\r
+bind(\r
+ RetType (X::*func)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7 ) const,\r
+ Y * y,\r
+ ...)\r
+{ \r
+ return FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7 ) >(y, func);\r
+}\r
+\r
+//N=8\r
+template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8>\r
+FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8 ) >\r
+bind(\r
+ RetType (X::*func)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8 ),\r
+ Y * y,\r
+ ...)\r
+{ \r
+ return FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8 ) >(y, func);\r
+}\r
+\r
+template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8>\r
+FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8 ) >\r
+bind(\r
+ RetType (X::*func)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8 ) const,\r
+ Y * y,\r
+ ...)\r
+{ \r
+ return FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8 ) >(y, func);\r
+}\r
+\r
+\r
+#endif //FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX\r
+\r
+} // namespace fastdelegate\r
+\r
+#endif // !defined(FASTDELEGATEBIND_H)\r
+\r
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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)
+ };
+
+private:
+ static int app_create(void *data);
+ static int app_terminate(void *data);
+ static int app_pause(void *data);
+ static int app_resume(void *data);
+ static int app_reset(bundle *b, void *data);
+
+protected:
+ int m_argc;
+ char **m_argv;
+ std::string m_applicationName;
+
+ bool m_mainWindowVisible;
+
+ virtual void OnCreate();
+ virtual void OnStart();
+ virtual void OnStop();
+ virtual void OnResume();
+ virtual void OnPause();
+ virtual void OnRelaunch();
+ virtual void OnReset(bundle *b);
+ virtual void OnTerminate();
+ virtual void OnLowMemory();
+ virtual void OnLowBattery();
+ virtual void OnLanguageChanged();
+
+public:
+ Application(int argc, char **argv, const std::string &applicationName, bool showMainWindow = true);
+ virtual ~Application();
+
+ /**
+ * @brief Execute application and start message processing
+ */
+ virtual int Exec();
+
+ /*
+ * @brief Sends quit message to application message loop
+ */
+ virtual void Quit();
+};
+
+class ApplicationExt : public Application
+{
+public:
+ ApplicationExt(int argc, char **argv, const std::string &applicationName, bool showMainWindow = true);
+ virtual ~ApplicationExt();
+
+ /**
+ * @brief Execute application and start message processing
+ */
+ virtual int Exec();
+
+ /*
+ * @brief Sends quit message to application message loop
+ */
+ virtual void Quit();
+private:
+ static DPL::Atomic m_useCount;
+};
+
+} // namespace DPL
+
+#endif // DPL_APPLICATION_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
+
+#include <dpl/noreturn.h>
+
+namespace DPL
+{
+// Assertion handler procedure
+// Do not call directly
+// Always use Assert macro
+DPL_NORETURN void AssertProc(const char *condition, const char *file, int line, const char *function);
+} // namespace DPL
+
+#define Assert(Condition) do { if (!(Condition)) DPL::AssertProc(#Condition, __FILE__, __LINE__, __FUNCTION__); } while (0)
+
+#endif // DPL_ASSERT_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
+ */
+#ifndef DPL_BOOL_OPERATOR_H
+#define DPL_BOOL_OPERATOR_H
+
+#define DPL_IMPLEMENT_BOOL_OPERATOR(Type, ThisType, CheckPtr, ClassPtr) \
+ typedef Type *ThisType::*UnknownBoolType; \
+ \
+ operator UnknownBoolType() const \
+ { \
+ return (CheckPtr == NULL) ? NULL : &ThisType::ClassPtr; \
+ } \
+ \
+ bool operator !() const \
+ { \
+ return CheckPtr == NULL; \
+ }
+
+#endif // DPL_BOOL_OPERATOR_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file fast_delegate.h
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the header file of fast delegate
+ */
+#ifndef DPL_FAST_DELEGATE_H
+#define DPL_FAST_DELEGATE_H
+
+#pragma GCC system_header
+
+#define FASTDELEGATE_USESTATICFUNCTIONHACK
+#define FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX
+
+#include <dpl/3rdparty/fastdelegate/FastDelegate.h>
+#include <dpl/3rdparty/fastdelegate/FastDelegateBind.h>
+
+namespace DPL
+{
+using namespace fastdelegate;
+} // namespace DPL
+
+#endif // DPL_FAST_DELEGATE_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_mapping.h
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the header file of file input mapping
+ */
+#ifndef DPL_FILE_INPUT_MAPPING_H
+#define DPL_FILE_INPUT_MAPPING_H
+
+#include <dpl/exception.h>
+#include <dpl/noncopyable.h>
+
+namespace DPL
+{
+class FileInputMapping
+ : private Noncopyable
+{
+public:
+ class Exception
+ {
+ public:
+ DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+ DECLARE_EXCEPTION_TYPE(Base, OpenFailed)
+ };
+
+private:
+ int m_handle;
+ off64_t m_size;
+ unsigned char *m_address;
+
+public:
+ /**
+ * Constructor
+ */
+ explicit FileInputMapping(const std::string &fileName);
+
+ /**
+ * Destructor
+ */
+ ~FileInputMapping();
+
+ /**
+ * Get file mapping total size
+ *
+ * @return 64-bit size
+ */
+ off64_t GetSize() const;
+
+ /**
+ * Get file mapping base address
+ *
+ * @return Base address of file mapping
+ */
+ const unsigned char *GetAddress() const;
+};
+} // namespace DPL
+
+#endif // DPL_FILE_INPUT_MAPPING_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <appcore-efl.h>
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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>
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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>
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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/noncopyable.h>
+#include <dpl/exception.h>
+#include <dpl/abstract_waitable_input.h>
+#include <dpl/named_base_pipe.h>
+
+namespace DPL
+{
+class NamedInputPipe
+ : private Noncopyable,
+ public NamedBasePipe,
+ 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_fifo;
+
+public:
+ NamedInputPipe();
+ virtual ~NamedInputPipe();
+
+ void Open(const std::string &fileName);
+ void Close();
+
+ // AbstractInput
+ virtual BinaryQueueAutoPtr Read(size_t size);
+
+ // AbstractWaitableInput
+ virtual WaitableHandle WaitableReadHandle() const;
+};
+} // namespace DPL
+
+#endif // DPL_NAMED_PIPE_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file noreturn.h
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of noreturn
+ */
+#ifndef DPL_NORETURN_H
+#define DPL_NORETURN_H
+
+#define DPL_NORETURN __attribute__((__noreturn__))
+
+#endif // DPL_NORETURN_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <dpl/noncopyable.h>
+#include <dpl/fast_delegate.h>
+#include <dpl/atomic.h>
+#include <dpl/mutex.h>
+
+namespace DPL
+{
+class Once
+ : private Noncopyable
+{
+public:
+ typedef FastDelegate<void ()> Delegate;
+
+ void Call(Delegate delegate);
+
+private:
+ Atomic m_atomic;
+ Mutex m_mutex;
+};
+} // namespace DPL
+
+#endif // DPL_ONCE_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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>
+
+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);
+ }
+ }
+};
+
+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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <dpl/string.h>
+#include <dpl/optional.h>
+
+namespace DPL
+{
+
+typedef Optional<String> OptionalString;
+typedef Optional<int> OptionalInt;
+typedef Optional<bool> OptionalBool;
+typedef Optional<float> OptionalFloat;
+
+} //namespace DPL
+
+#endif /* DPL_OPTIONAL_TYPEDEFS_H */
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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)
+
+#endif//DPL_PREPROCESSOR_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
+ */
+#ifndef DPL_SCOPED_ARRAY_H
+#define DPL_SCOPED_ARRAY_H
+
+#include <cstddef>
+
+#include <dpl/assert.h>
+#include <dpl/scoped_resource.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];
+ }
+};
+} // namespace DPL
+
+#endif // DPL_SCOPED_PTR_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
+ */
+
+#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>
+
+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);
+ }
+};
+
+} // namespace DPL
+
+#endif // DPL_SCOPED_GPOINTER_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
+ */
+#ifndef DPL_SCOPED_PTR_H
+#define DPL_SCOPED_PTR_H
+
+#include <cstddef>
+
+#include <dpl/scoped_resource.h>
+#include <dpl/assert.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;
+ }
+};
+} // namespace DPL
+
+#endif // DPL_SCOPED_PTR_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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();
+
+ void Lock() const;
+ void Unlock() const;
+
+public:
+ /**
+ * 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
+ */
+#ifndef DPL_SHARED_PTR_H
+#define DPL_SHARED_PTR_H
+
+#include <dpl/noncopyable.h>
+#include <dpl/atomic.h>
+#include <dpl/bool_operator.h>
+#include <cstddef>
+#include <dpl/assert.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)
+};
+
+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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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;
+ OptionalThreadPtr m_guard;
+
+ static Singleton &InternalInstance();
+
+public:
+ virtual ~Singleton()
+ {
+ }
+
+ static Class &Instance();
+
+ // Thread guarding
+ static void SetThreadGuard(Thread *thread);
+ static void ResetThreadGuard();
+};
+
+//This is needed for backward compatibility
+#ifndef SEPARATED_SINGLETON_IMPLEMENTATION
+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();
+
+ if (!!instance.m_guard)
+ {
+ Assert(Thread::GetCurrentThread() == *instance.m_guard &&
+ "Singleton thread guard failed. A forbidden call from foreign thread was detected!");
+ }
+
+ return instance;
+}
+
+// Thread guarding
+template<typename Class>
+void Singleton<Class>::SetThreadGuard(Thread *thread)
+{
+ Singleton<Class>& instance = Singleton<Class>::InternalInstance();
+ instance.m_guard = OptionalThreadPtr(thread);
+}
+
+template<typename Class>
+void Singleton<Class>::ResetThreadGuard()
+{
+ Singleton<Class>& instance = Singleton<Class>::InternalInstance();
+ instance.m_guard = OptionalThreadPtr::Null;
+}
+
+#endif
+
+} // namespace DPL
+
+#endif // DPL_SINGLETON_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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();
+
+ if (!!instance.m_guard)
+ {
+ Assert(Thread::GetCurrentThread() == *instance.m_guard &&
+ "Singleton thread guard failed. A forbidden call from foreign thread was detected!");
+ }
+
+ return instance;
+}
+
+// Thread guarding
+template<typename Class>
+void Singleton<Class>::SetThreadGuard(Thread *thread)
+{
+ Singleton<Class>& instance = Singleton<Class>::InternalInstance();
+ instance.m_guard = OptionalThreadPtr(thread);
+}
+
+template<typename Class>
+void Singleton<Class>::ResetThreadGuard()
+{
+ Singleton<Class>& instance = Singleton<Class>::InternalInstance();
+ instance.m_guard = OptionalThreadPtr::Null;
+}
+
+} // namespace DPL
+
+#define IMPLEMENT_SINGLETON(Type) \
+template DPL::Singleton<Type>& DPL::Singleton<Type>::InternalInstance(); \
+template Type& DPL::Singleton<Type>::Instance(); \
+template void DPL::Singleton<Type>::SetThreadGuard(DPL::Thread *thread); \
+template void DPL::Singleton<Type>::ResetThreadGuard();
+
+#endif // DPL_SINGLETON_IMPL_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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(); \
+ if (!!instance.m_guard) \
+ { \
+ Assert(Thread::GetCurrentThread() == *instance.m_guard && \
+ "Singleton thread guard failed. A forbidden call from foreign thread was detected!");\
+ } \
+ return instance; \
+} \
+ \
+template<> \
+void Singleton<Class>::SetThreadGuard(Thread *thread) \
+{ \
+ Singleton<Class>& instance = Singleton<Class>::InternalInstance(); \
+ instance.m_guard = OptionalThreadPtr(thread); \
+} \
+ \
+template<> \
+void Singleton<Class>::ResetThreadGuard() \
+{ \
+ Singleton<Class>& instance = Singleton<Class>::InternalInstance(); \
+ instance.m_guard = OptionalThreadPtr::Null; \
+} \
+template Singleton<Class>& Singleton<Class>::InternalInstance(); \
+template Class& Singleton<Class>::Instance(); \
+template void Singleton<Class>::SetThreadGuard(Thread *thread); \
+template void Singleton<Class>::ResetThreadGuard(); \
+} // namespace DPL
+
+
+#endif // DPL_SINGLETON_SAFE_IMPL_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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>
+
+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 DPL
+
+std::ostream& operator<<(std::ostream& aStream, const DPL::String& aString);
+
+#endif // DPL_STRING
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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/scoped_array.h>
+#include <dpl/noncopyable.h>
+#include <dpl/union_cast.h>
+#include <dpl/semaphore.h>
+#include <dpl/foreach.h>
+#include <dpl/mutex.h>
+#include <dpl/assert.h>
+#include <dpl/log/log.h>
+#include <algorithm>
+#include <sstream>
+#include <iomanip>
+#include <list>
+#include <stack>
+#include <cctype>
+
+namespace DPL
+{
+class TaskList;
+
+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());
+ }
+};
+
+template<typename ImplementationType>
+class MultiTaskDecl
+ : public Task
+{
+protected:
+ typedef void (ImplementationType::*Step)();
+ typedef std::list<Step> StepList;
+ typedef std::stack<Step> StepStack;
+
+private:
+ static std::string StepToString(Step step)
+ {
+ std::ostringstream pseudoAddressStream;
+ pseudoAddressStream << std::hex << union_cast<size_t>(step);
+
+ std::string pseudoAddress = pseudoAddressStream.str();
+
+ std::transform(pseudoAddress.begin(), pseudoAddress.end(),
+ pseudoAddress.begin(), ::toupper);
+
+ return std::string("0x") + pseudoAddress;
+ }
+
+ struct ConditionalStep
+ {
+ Step step;
+
+ // Depencency lists
+ StepList unsatisfiedDependencies;
+ StepList satisfiedDependencies;
+
+ ConditionalStep()
+ : step(NULL)
+ {
+ }
+
+ ConditionalStep(Step stepArg,
+ StepList dependenciesArg)
+ : step(stepArg),
+ unsatisfiedDependencies(dependenciesArg)
+ {
+ }
+ };
+
+ typedef std::list<ConditionalStep> ConditionalStepList;
+
+ // Synchronization
+ Semaphore m_activeStepsSemaphore;
+ mutable Mutex m_dependencyListMutex;
+
+ // Those steps that have their dependency lists satified and are ready
+ // to be executed
+ // Current step is defined to be the front of satisfied list
+ ConditionalStepList m_satisfiedSteps;
+
+ // Those steps that are going to be executed but their dependency
+ // lists have not been satified
+ ConditionalStepList m_unsatisfiedSteps;
+
+ // Those steps that have their dependency lists satified and are currently
+ // being executed
+ ConditionalStepList m_executingSteps;
+
+ // Those steps that have been executed with their dependency lists
+ // satisfied
+ ConditionalStepList m_historicSteps;
+
+ ///< Growing list of submitted abort steps
+ StepStack m_abortSteps;
+
+ // Deriving implementation
+ ImplementationType *m_implementation;
+
+ // Max parallel steps
+ size_t m_maxParallelCount;
+
+ ///< Valid in dependency list mutex only
+ void SatisfyDependencies(const ConditionalStep &conditionalStep)
+ {
+ LogPedantic("Satisfying steps with dependecy to step: "
+ << StepToString(conditionalStep.step));
+
+ // Can satisfy conditional steps if and only if there are no more
+ // satisfied, unsatisfied or running same steps
+ // There is at least one historic step - this one
+ if (IsContainingStep(conditionalStep.step, m_unsatisfiedSteps) ||
+ IsContainingStep(conditionalStep.step, m_satisfiedSteps) ||
+ IsContainingStep(conditionalStep.step, m_executingSteps))
+ {
+ LogPedantic("Step " << StepToString(conditionalStep.step)
+ << " cannot satify other steps yet");
+
+ return;
+ }
+
+ LogPedantic("Step " << StepToString(conditionalStep.step)
+ << " can satify other steps");
+
+ // Do satisfy
+ typename ConditionalStepList::iterator unsatisfiedStepIterator =
+ m_unsatisfiedSteps.begin();;
+
+ while (unsatisfiedStepIterator != m_unsatisfiedSteps.end())
+ {
+ typename StepList::iterator iterator =
+ std::find(
+ unsatisfiedStepIterator->unsatisfiedDependencies.begin(),
+ unsatisfiedStepIterator->unsatisfiedDependencies.end(),
+ conditionalStep.step);
+
+ // Does this conditional step need to be satisfied ?
+ if (iterator ==
+ unsatisfiedStepIterator->unsatisfiedDependencies.end())
+ {
+ continue;
+ }
+
+ LogPedantic("Satisfying step "
+ << StepToString(unsatisfiedStepIterator->step)
+ << " dependency to step "
+ << StepToString(conditionalStep.step));
+
+ // Satisfy dependency
+ unsatisfiedStepIterator->unsatisfiedDependencies.erase(
+ iterator);
+
+ unsatisfiedStepIterator->satisfiedDependencies.push_back(
+ conditionalStep.step);
+
+ // If step is fully satisfied, transfer it to the satisfied
+ // steps list
+ if (unsatisfiedStepIterator->unsatisfiedDependencies.empty())
+ {
+ LogPedantic("Step "
+ << StepToString(unsatisfiedStepIterator->step)
+ << " is fully satisfied");
+
+ // Move step
+ m_satisfiedSteps.push_back(*unsatisfiedStepIterator);
+
+ unsatisfiedStepIterator =
+ m_unsatisfiedSteps.erase(unsatisfiedStepIterator);
+
+ continue;
+ }
+
+ // Check next unsatisfied step
+ ++unsatisfiedStepIterator;
+ }
+ }
+
+ ///< Valid in dependency list mutex only
+ bool IsContainingStep(Step step, const ConditionalStepList &dependencies) const
+ {
+ FOREACH (iterator, dependencies)
+ if (iterator->step == step)
+ return true;
+
+ return false;
+ }
+
+ ///< Valid in dependency list mutex only
+ bool IsStepDependecyListSatisfied(
+ const StepList &dependencies) const
+ {
+ // All dependant step must be historic
+ FOREACH (iterator, dependencies)
+ if (!IsContainingStep(*iterator, m_historicSteps))
+ return false;
+
+ // Also, none dependant step can exist in
+ // unsatisfied/satisfied/inProgress lists
+ FOREACH (iterator, dependencies)
+ {
+ if (IsContainingStep(*iterator, m_unsatisfiedSteps) ||
+ IsContainingStep(*iterator, m_satisfiedSteps) ||
+ IsContainingStep(*iterator, m_executingSteps))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ bool AbortInternal()
+ {
+ // Clear all steps and construct
+ // a single-dependency list of abort steps
+ m_unsatisfiedSteps.clear();
+ m_satisfiedSteps.clear();
+ m_executingSteps.clear();
+ m_historicSteps.clear();
+
+ if (m_abortSteps.empty())
+ return false;
+
+ // Register last abort step as satisfied
+ m_satisfiedSteps.push_back(
+ ConditionalStep(
+ m_abortSteps.top(),
+ StepList()));
+
+ Step lastStep = m_abortSteps.top();
+ m_abortSteps.pop();
+
+ // Create abort step list
+ while (!m_abortSteps.empty())
+ {
+ // Add next unsatisfied step
+ StepList dependencies;
+ dependencies.push_back(lastStep);
+
+ m_unsatisfiedSteps.push_back(
+ ConditionalStep(
+ m_abortSteps.top(),
+ dependencies));
+
+ // Remove top abort step
+ lastStep = m_abortSteps.top();
+ m_abortSteps.pop();
+ }
+
+ return true;
+ }
+
+protected:
+ void AddStep(Step step,
+ const StepList &dependencies)
+ {
+ Mutex::ScopedLock lock(&m_dependencyListMutex);
+
+ LogPedantic("Adding step: " << StepToString(step));
+
+ FOREACH (iterator, dependencies)
+ LogPedantic(" Dependency: " << StepToString(*iterator));
+
+ // Add step to proper list
+ if (IsStepDependecyListSatisfied(dependencies))
+ {
+ m_satisfiedSteps.push_back(ConditionalStep(step, dependencies));
+
+ LogPedantic("Step " << StepToString(step) << " is satisfied");
+ }
+ else
+ {
+ m_unsatisfiedSteps.push_back(ConditionalStep(step, dependencies));
+
+ LogPedantic("Step " << StepToString(step) << " is unsatisfied");
+ }
+
+ LogPedantic("Satisfied step count: " << m_satisfiedSteps.size());
+ LogPedantic("Unsatisfied step count: " << m_unsatisfiedSteps.size());
+ }
+
+ void AddAbortStep(Step step)
+ {
+ Mutex::ScopedLock lock(&m_dependencyListMutex);
+
+ m_abortSteps.push_front(step);
+
+ LogPedantic("Abort step count: " << m_abortSteps.size());
+ }
+
+public:
+ MultiTaskDecl(ImplementationType *implementation,
+ size_t maxParallelCount)
+ : m_activeStepsSemaphore(maxParallelCount),
+ m_implementation(implementation),
+ m_maxParallelCount(maxParallelCount)
+ {
+ }
+
+ bool NextStep()
+ {
+ ConditionalStep stepToExecute;
+ typename ConditionalStepList::iterator executingStepIterator;
+
+ // Take the main semaphore lock
+ Semaphore::ScopedLock semaphoreLock(&m_activeStepsSemaphore);
+
+ // Take the dependency list lock
+ {
+ Mutex::ScopedLock listLock(&m_dependencyListMutex);
+
+ // Get next step to execute
+ if (m_satisfiedSteps.empty())
+ {
+ LogPedantic("No more satisfied steps to execute");
+ return false;
+ }
+
+ // Get next satisfied step to execute
+ stepToExecute = m_satisfiedSteps.front();
+ m_satisfiedSteps.pop_front();
+
+ // Register it in executing step list
+ m_executingSteps.push_back(stepToExecute);
+ executingStepIterator = --m_executingSteps.end();
+
+ // Leave the dependency list lock
+ }
+
+ // Execute step
+ (*m_implementation.*stepToExecute.step)();
+
+ // Take a lock again
+ {
+ Mutex::ScopedLock listLock(&m_dependencyListMutex);
+
+ // Unregister executing step
+ m_executingSteps.erase(executingStepIterator);
+
+ // Add historic step
+ m_historicSteps.push_back(stepToExecute);
+
+ // Satisfy dependencies
+ SatisfyDependencies(stepToExecute);
+
+ // Leave lock
+ }
+
+ // Done
+ return true;
+ }
+
+ bool Abort()
+ {
+ // Wait until all active steps are done
+ // This is achieved by taking all semaphore slots
+ ScopedArray<Semaphore::ScopedLock *> semaphoreLocks(
+ new Semaphore::ScopedLock *[m_maxParallelCount]);
+
+ for (size_t i = 0; i < m_maxParallelCount; ++i)
+ semaphoreLocks[i] = new Semaphore::ScopedLock(
+ &m_activeStepsSemaphore);
+
+ // Result
+ bool result;
+
+ // Take step lists lock
+ {
+ Mutex::ScopedLock mutexLock(&m_dependencyListMutex);
+
+ // Do internal abort
+ result = AbortInternal();
+
+ // Leave steps list lock
+ }
+
+ // Leave semaphore locks
+ for (size_t i = 0; i < m_maxParallelCount; ++i)
+ delete semaphoreLocks[i];
+
+ // Return result
+ return result;
+ }
+
+ size_t GetStepCount() const
+ {
+ // Return sum of sizes of all lists
+ Mutex::ScopedLock lock(&m_dependencyListMutex);
+
+ return static_cast<size_t>(
+ m_unsatisfiedSteps.size() +
+ m_satisfiedSteps.size() +
+ m_executingSteps.size() +
+ m_historicSteps.size());
+ }
+};
+} // namespace DPL
+
+#endif // DPL_TASK_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.h
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @author Radoslaw Wicik (r.wicik@samsung.com)
+ * @version 1.0
+ * @brief Header file for task list
+ */
+#ifndef DPL_TASK_LIST_H
+#define DPL_TASK_LIST_H
+
+#include <dpl/task.h>
+#include <list>
+
+namespace DPL
+{
+class TaskList
+ : public Task
+{
+private:
+ typedef std::list<Task *> Tasks;
+
+ Tasks m_tasks;
+ Tasks::iterator m_currentTask;
+ bool m_switched;
+
+ bool m_running;
+
+protected:
+ void AddTask(Task *task);
+ void SwitchToTask(Task *task);
+
+public:
+ TaskList();
+ virtual ~TaskList();
+
+ bool NextStep();
+ bool Abort();
+ size_t GetTaskCount() const;
+ size_t GetStepCount() const;
+};
+} // namespace DPL
+
+#endif // DPL_TASK_LIST_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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/waitable_event.h>
+//#include <dpl/waitable_handle.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();
+
+ /**
+ * 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)
+ };
+
+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::GetCurrentThread() == NULL)
+ {
+ 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);
+
+ Assert(result == 0 &&
+ "Failed to allocate thread local variable");
+ }
+
+ ~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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file unused.h
+ * @author Lukasz Wrzosek (l.wrzosek@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of unused attribute from gcc
+ */
+#ifndef DPL_UNUSED_H
+#define DPL_UNUSED_H
+
+#define DPL_UNUSED __attribute__((unused))
+
+#endif // DPL_UNUSED_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 FileDateTime
+ {
+ unsigned int second; //< seconds after the minute - [0,59]
+ unsigned int minute; //< minutes after the hour - [0,59]
+ unsigned int hour; //< hours since midnight - [0,23]
+ unsigned int day; //< day of the month - [1,31]
+ unsigned int month; //< months since January - [0,11]
+ unsigned int year; //< years - [1980..2044]
+
+ FileDateTime()
+ : second(0),
+ minute(0),
+ hour(0),
+ day(0),
+ month(0),
+ year(0)
+ {
+ }
+
+ FileDateTime(unsigned int secondArg,
+ unsigned int minuteArg,
+ unsigned int hourArg,
+ unsigned int dayArg,
+ unsigned int monthArg,
+ unsigned int yearArg)
+ : second(secondArg),
+ minute(minuteArg),
+ hour(hourArg),
+ day(dayArg),
+ month(monthArg),
+ year(yearArg)
+ {
+ }
+ };
+
+ struct FileInfo
+ {
+ // File handle
+ FileHandle handle;
+
+ // File name and comment
+ std::string name;
+ std::string comment;
+
+ // File information
+ unsigned long version; //< version made by
+ unsigned long versionNeeded; //< version needed to extract
+ unsigned long flag; //< general purpose bit flag
+ unsigned long compressionMethod; //< compression method
+ unsigned long dosDate; //< last mod file date in Dos fmt
+ unsigned long crc; //< crc-32
+ off64_t compressedSize; //< compressed size
+ off64_t uncompressedSize; //< uncompressed size
+ unsigned long diskNumberStart; //< disk number start
+ unsigned long internalFileAttributes; //< internal file attributes
+ unsigned long externalFileAttributes; //< external file attributes
+
+ FileDateTime dateTime;
+
+ FileInfo()
+ : handle(),
+ name(),
+ comment(),
+ version(0),
+ versionNeeded(0),
+ flag(0),
+ compressionMethod(0),
+ dosDate(0),
+ crc(0),
+ compressedSize(0),
+ uncompressedSize(0),
+ diskNumberStart(0),
+ internalFileAttributes(0),
+ externalFileAttributes(0),
+ dateTime()
+ {
+ }
+
+ FileInfo(const FileHandle &handleArg,
+ const std::string &nameArg,
+ const std::string &commentArg,
+ unsigned long versionArg,
+ unsigned long versionNeededArg,
+ unsigned long flagArg,
+ unsigned long compressionMethodArg,
+ unsigned long dosDateArg,
+ unsigned long crcArg,
+ const off64_t &compressedSizeArg,
+ const off64_t &uncompressedSizeArg,
+ unsigned long diskNumberStartArg,
+ unsigned long internalFileAttributesArg,
+ unsigned long externalFileAttributesArg,
+ const FileDateTime &dateTimeArg)
+ : handle(handleArg),
+ name(nameArg),
+ comment(commentArg),
+ version(versionArg),
+ versionNeeded(versionNeededArg),
+ flag(flagArg),
+ compressionMethod(compressionMethodArg),
+ dosDate(dosDateArg),
+ crc(crcArg),
+ compressedSize(compressedSizeArg),
+ uncompressedSize(uncompressedSizeArg),
+ diskNumberStart(diskNumberStartArg),
+ internalFileAttributes(internalFileAttributesArg),
+ externalFileAttributes(externalFileAttributesArg),
+ dateTime(dateTimeArg)
+ {
+ }
+ };
+
+ 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;
+
+ // 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 handle
+ *
+ * @return file object
+ * @param[in] handle Zip file handle 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(FileHandle handle);
+
+ /**
+ * 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;
+};
+} // namespace DPL
+
+#endif // DPL_ZIP_INPUT_H
--- /dev/null
+Source files
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <dpl/abstract_waitable_input_output_adapter.h>
+
+namespace DPL
+{
+
+AbstractWaitableInputOutputAdapter::AbstractWaitableInputOutputAdapter(AbstractInputOutput *inputOutput)
+ : AbstractWaitableInputAdapter(inputOutput),
+ AbstractWaitableOutputAdapter(inputOutput)
+{
+}
+
+} // namespace DPL
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <dpl/application.h>
+#include <dpl/log/log.h>
+
+namespace // anonymous
+{
+static DPL::Application *g_application = NULL;
+} // namespace anonymous
+
+namespace DPL
+{
+int Application::app_create(void *data)
+{
+ Application *This=static_cast<Application *>(data);
+ This->OnCreate();
+ return 0;
+}
+
+int Application::app_terminate(void *data)
+{
+ Application *This=static_cast<Application *>(data);
+ This->OnTerminate();
+ return 0;
+}
+
+int Application::app_pause(void *data)
+{
+ Application *This=static_cast<Application *>(data);
+ This->OnPause();
+ return 0;
+}
+
+int Application::app_resume(void *data)
+{
+ Application *This=static_cast<Application *>(data);
+ This->OnResume();
+ return 0;
+}
+
+int Application::app_reset(bundle *b, void *data)
+{
+ Application *This=static_cast<Application *>(data);
+ This->OnReset(b);
+ return 0;
+}
+
+Application::Application(int argc, char** argv,
+ const std::string& applicationName,
+ bool showMainWindow)
+ : m_argc(argc),
+ m_argv(argv),
+ m_applicationName(applicationName),
+ m_mainWindowVisible(showMainWindow)
+{
+ if (g_application != NULL)
+ ThrowMsg(Exception::TooManyInstances, "Only single instance of Application allowed at one time!");
+
+ g_application = this;
+}
+
+Application::~Application()
+{
+ g_application = NULL;
+}
+
+int Application::Exec()
+{
+ LogPedantic("Starting application framework...");
+
+ struct appcore_ops ops;
+ ops.create = app_create;
+ ops.terminate = app_terminate;
+ ops.pause = app_pause;
+ ops.resume = app_resume;
+ ops.reset = app_reset;
+ ops.data=this;
+
+ int result = appcore_efl_main(m_applicationName.c_str(), &m_argc, &m_argv, &ops);
+
+ LogPedantic("Exited application framework");
+
+ return result;
+}
+
+void Application::OnCreate()
+{
+ LogPedantic("On application create");
+}
+
+void Application::OnStart()
+{
+ LogPedantic("On application start");
+}
+
+void Application::OnStop()
+{
+ LogPedantic("On application stop");
+}
+
+void Application::OnResume()
+{
+ LogPedantic("On application resume");
+}
+
+void Application::OnPause()
+{
+ LogPedantic("On application pause");
+}
+
+void Application::OnRelaunch()
+{
+ LogPedantic("On application relaunch");
+}
+
+void Application::OnReset(bundle *b)
+{
+ (void)b;
+ LogPedantic("On application reset");
+}
+
+void Application::OnTerminate()
+{
+ LogPedantic("On application terminate");
+}
+
+void Application::OnLowMemory()
+{
+ LogPedantic("On application low memory");
+}
+
+void Application::OnLowBattery()
+{
+ LogPedantic("On application low battery");
+}
+
+void Application::OnLanguageChanged()
+{
+ LogPedantic("On application language changed");
+}
+
+void Application::Quit()
+{
+ elm_exit();
+}
+
+DPL::Atomic ApplicationExt::m_useCount(0);
+
+ApplicationExt::ApplicationExt(int argc, char** argv, const std::string& applicationName, bool showMainWindow) :
+ Application(argc, argv, applicationName, showMainWindow)
+{
+}
+
+ApplicationExt::~ApplicationExt()
+{
+}
+
+int ApplicationExt::Exec()
+{
+ if (0 == m_useCount.CompareAndExchange(0, 1))
+ {
+ return Application::Exec();
+ }
+ else
+ {
+ elm_run();
+ }
+ return 0;
+}
+
+void ApplicationExt::Quit()
+{
+ elm_exit();
+}
+} // namespace DPL
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <dpl/apply.h>
+
+//
+// Note:
+//
+// The file here is left blank to enable precompilation
+// of templates in corresponding header file.
+// Do not remove this file.
+//
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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
+ }
+
+ // Fail with c-library abort
+ abort();
+}
+} // namespace DPL
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <dpl/atomic.h>
+
+namespace DPL
+{
+Atomic::Atomic(ValueType value)
+ : m_value(value)
+{
+}
+
+Atomic::ValueType Atomic::ExchangeAndAdd(ValueType value)
+{
+ return g_atomic_int_exchange_and_add(&m_value, value);
+}
+
+bool Atomic::CompareAndExchange(ValueType oldValue, ValueType newValue)
+{
+ return g_atomic_int_compare_and_exchange(&m_value, oldValue, newValue);
+}
+
+bool Atomic::operator--()
+{
+ return g_atomic_int_dec_and_test(&m_value) != TRUE;
+}
+
+void Atomic::operator++()
+{
+ g_atomic_int_inc(&m_value);
+}
+
+Atomic::operator ValueType() const
+{
+ return g_atomic_int_get(&m_value);
+}
+} // namespace DPL
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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.
+//
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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:
+ Assert(0 && "Invalid errno value after call to strerror_r!");
+ }
+ }
+}
+} // namespace DPL
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file fast_delegate.cpp
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of fast delegate
+ */
+#include <dpl/fast_delegate.h>
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.cpp
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of named input pipe
+ */
+#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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_mapping.cpp
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of file input mapping
+ */
+#include <dpl/file_input_mapping.h>
+#include <dpl/scoped_close.h>
+#include <dpl/log/log.h>
+#include <iomanip>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <errno.h>
+
+namespace DPL
+{
+FileInputMapping::FileInputMapping(const std::string &fileName)
+ : m_handle(-1),
+ m_size(0),
+ m_address(NULL)
+{
+ // 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(FileInputMapping::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(FileInputMapping::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(FileInputMapping::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));
+}
+
+FileInputMapping::~FileInputMapping()
+{
+ // 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 (TEMP_FAILURE_RETRY(close(m_handle)) == -1)
+ {
+ int error = errno;
+ LogPedantic("Failed to close file. errno = " << error);
+ }
+}
+
+off64_t FileInputMapping::GetSize() const
+{
+ return m_size;
+}
+
+const unsigned char *FileInputMapping::GetAddress() const
+{
+ return m_address;
+}
+} // namespace DPL
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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.
+//
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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.
+//
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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;
+
+ // 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)
+{
+#if 0
+ // 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);
+ }
+ }
+ }
+ }
+
+ // Find out new maximum
+ int newNfds = 0;
+
+ for (int i = 0; i < nfds; i++)
+ {
+ if (FD_ISSET(i, readfds) || FD_ISSET(i, writefds) || FD_ISSET(i, exceptfds))
+ newNfds = i;
+ }
+
+ return MainSingleton::Instance().m_oldEcoreSelect(newNfds + 1, readfds, writefds, exceptfds, timeout);
+
+#else
+
+ // 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
+}
+#endif // DPL_ENABLE_GLIB_LOOP_INTEGRATION_WORKAROUND
+} // namespace DPL
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.cpp
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of named input pipe
+ */
+#include <dpl/named_input_pipe.h>
+#include <dpl/binary_queue.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+namespace DPL
+{
+namespace // anonymous
+{
+const size_t DEFAULT_READ_BUFFER_SIZE = 1024;
+} // namespace anonymous
+
+NamedInputPipe::NamedInputPipe()
+ : m_fifo(-1)
+{
+}
+
+NamedInputPipe::~NamedInputPipe()
+{
+ Close();
+}
+
+void NamedInputPipe::Open(const std::string& pipeName)
+{
+ // Open pipe for reading
+ int fifo = TEMP_FAILURE_RETRY(open(pipeName.c_str(), O_RDONLY | O_NONBLOCK));
+
+ if (fifo == -1)
+ ThrowMsg(Exception::OpenFailed, pipeName);
+
+ m_fifo = fifo;
+}
+
+void NamedInputPipe::Close()
+{
+ if (m_fifo == -1)
+ return;
+
+ if (TEMP_FAILURE_RETRY(close(m_fifo)) == -1)
+ Throw(Exception::CloseFailed);
+
+ m_fifo = -1;
+}
+
+BinaryQueueAutoPtr NamedInputPipe::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();
+
+ ssize_t result = TEMP_FAILURE_RETRY(read(m_fifo, buffer, bytesToRead));
+
+ 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);
+ }
+}
+
+int NamedInputPipe::WaitableReadHandle() const
+{
+ return m_fifo;
+}
+} // namespace DPL
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <dpl/noncopyable.h>
+
+namespace DPL
+{
+Noncopyable::Noncopyable()
+{
+}
+
+Noncopyable::~Noncopyable()
+{
+}
+} // namespace DPL
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <dpl/serialization.h>
+
+//
+// Note:
+//
+// The file here is left blank to enable precompilation
+// of templates in corresponding header file.
+// Do not remove this file.
+//
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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()
+{
+ Assert(!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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <dpl/singleton.h>
+
+//
+// Note:
+//
+// The file here is left blank to enable precompilation
+// of templates in corresponding header file.
+// Do not remove this file.
+//
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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());
+ return String();
+ }
+
+ // 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());
+ return std::string();
+ }
+
+ 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 std::string();
+ }
+
+ 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);
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <dpl/task.h>
+
+//
+// Note:
+//
+// The file here is left blank to enable precompilation
+// of templates in corresponding header file.
+// Do not remove this file.
+//
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @author Radoslaw Wicik (r.wicik@samsung.com)
+ * @version 1.0
+ * @brief Implementation file for task list
+ */
+#include <dpl/task_list.h>
+#include <dpl/assert.h>
+
+namespace DPL
+{
+TaskList::TaskList()
+ : m_switched(false),
+ m_running(false)
+{
+ m_currentTask = m_tasks.end();
+}
+
+TaskList::~TaskList()
+{
+ for (Tasks::iterator i = m_tasks.begin(); i != m_tasks.end(); ++i)
+ delete *i;
+}
+
+void TaskList::AddTask(Task *task)
+{
+ Assert(!m_running && "AddTask is not allowed after calling NextStep");
+ m_tasks.push_back(task);
+ m_currentTask = m_tasks.begin();
+}
+
+bool TaskList::NextStep()
+{
+ m_running = true;
+
+ Assert(m_currentTask != m_tasks.end() && "Task list is empty or all tasks done");
+
+ m_switched = false;
+
+ bool result = (*m_currentTask)->NextStep();
+
+ if (result || m_switched)
+ return true;
+
+ return ++m_currentTask != m_tasks.end();
+}
+
+bool TaskList::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;
+}
+
+void TaskList::SwitchToTask(Task *task)
+{
+ Tasks::iterator i = std::find(m_tasks.begin(), m_tasks.end(), task);
+ Assert(i != m_tasks.end());
+ m_currentTask = i;
+ m_switched = true;
+}
+
+size_t TaskList::GetTaskCount() const
+{
+ return static_cast<size_t>(m_tasks.size());
+}
+
+size_t TaskList::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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <dpl/thread.h>
+#include <dpl/log/log.h>
+#include <sys/time.h>
+#include <algorithm>
+#include <dpl/assert.h>
+#include <errno.h>
+#include <time.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();
+}
+
+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
+ pthread_setspecific(g_threadSpecific.threadSpecific, This);
+
+ // 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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.
+//
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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.
+//
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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)
+ Assert(0 && "CheckWaitableHandle: Invalid WaitableHandle! (EBADF)");
+
+ Assert(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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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())
+ {
+ LogPedantic("### Leaked watchers map dump ###");
+
+ for (WaitableHandleWatchersMap::const_iterator iterator = m_watchersMap.begin();
+ iterator != m_watchersMap.end();
+ ++iterator)
+ {
+ LogPedantic("### Waitable handle: " << iterator->first);
+
+ LogPedantic("### Read listeners: " << iterator->second.readListenersCount);
+ LogPedantic("### Write listeners: " << iterator->second.writeListenersCount);
+
+ for (WaitableHandleListenerList::const_iterator listenersIterator = iterator->second.listeners.begin();
+ listenersIterator != iterator->second.listeners.end();
+ ++listenersIterator)
+ {
+ LogPedantic("### Mode: " << listenersIterator->mode << ". Listener: 0x" << std::hex << listenersIterator->listener);
+ }
+ }
+ }
+
+ Assert(m_watchersMap.empty() == true);
+}
+
+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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <dpl/zip_input.h>
+#include <dpl/file_input_mapping.h>
+#include <dpl/binary_queue.h>
+#include <dpl/scoped_free.h>
+#include <dpl/scoped_ptr.h>
+#include <dpl/scoped_array.h>
+#include <dpl/foreach.h>
+#include <dpl/log/log.h>
+#include <minizip/framework_minizip.h>
+#include <new>
+
+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:
+ DPL::ScopedPtr<FileInputMapping> m_fileMapping;
+
+ struct File
+ {
+ off64_t offset;
+ Device *device;
+
+ File(Device *d)
+ : offset(0),
+ device(d)
+ {
+ }
+ };
+
+public:
+ Device(const std::string &fileName)
+ {
+ Try
+ {
+ LogPedantic("Creating file mapping");
+ m_fileMapping.Reset(new FileInputMapping(fileName));
+ }
+ Catch (FileInputMapping::Exception::Base)
+ {
+ LogPedantic("Failed to create file mapping");
+
+ ReThrowMsg(ZipInput::Exception::OpenFailed,
+ "Failed to open zip file mapping");
+ }
+
+ LogPedantic("File mapping created");
+ }
+
+ // zlib_filefunc64_def interface: files
+ static voidpf ZCALLBACK open64_file(voidpf opaque,
+ const void* filename,
+ int mode)
+ {
+ (void)filename;
+ (void)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_fileMapping->GetSize())
+ {
+ LogPedantic("Device: read offset out of bounds");
+ return -1;
+ }
+
+ off64_t bytesLeft = device->m_fileMapping->GetSize() -
+ 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_fileMapping->GetAddress() + 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)
+ {
+ (void)opaque;
+ (void)stream;
+ (void)buf;
+ (void)size;
+
+ // Not supported by device
+ LogPedantic("Unsupported function called!");
+ return -1;
+ }
+
+ static int ZCALLBACK close_file(voidpf opaque,
+ voidpf stream)
+ {
+ (void)opaque;
+ File *deviceFile = static_cast<File *>(stream);
+
+ // Delete file
+ delete deviceFile;
+
+ // Always OK
+ return 0;
+ }
+
+ static int ZCALLBACK testerror_file(voidpf opaque,
+ voidpf stream)
+ {
+ (void)opaque;
+ (void)stream;
+
+ // No errors
+ return 0;
+ }
+
+ static ZPOS64_T ZCALLBACK tell64_file(voidpf opaque,
+ voidpf stream)
+ {
+ (void)opaque;
+ 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_fileMapping->GetSize() -
+ 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_fileInfos()
+{
+ LogPedantic("Zip input file: " << fileName);
+
+ // Create master device
+ LogPedantic("Creating master device");
+ ScopedPtr<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<unsigned long>(fileInfo.version),
+ static_cast<unsigned long>(fileInfo.version_needed),
+ static_cast<unsigned long>(fileInfo.flag),
+ static_cast<unsigned long>(fileInfo.compression_method),
+ static_cast<unsigned long>(fileInfo.dosDate),
+ static_cast<unsigned long>(fileInfo.crc),
+ static_cast<off64_t>(fileInfo.compressed_size),
+ static_cast<off64_t>(fileInfo.uncompressed_size),
+ static_cast<unsigned long>(fileInfo.disk_num_start),
+ static_cast<unsigned long>(fileInfo.internal_fa),
+ static_cast<unsigned long>(fileInfo.external_fa),
+ FileDateTime(
+ fileInfo.tmu_date.tm_sec,
+ fileInfo.tmu_date.tm_min,
+ fileInfo.tmu_date.tm_hour,
+ fileInfo.tmu_date.tm_mday,
+ fileInfo.tmu_date.tm_mon,
+ fileInfo.tmu_date.tm_year
+ )
+ )
+ );
+
+ // 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(FileHandle handle)
+{
+ return new File(m_device, handle);
+}
+
+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 open 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();
+}
+} // namespace DPL
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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
+)
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <dpl/db/sql_connection.h>
+#include <dpl/db/orm_interface.h>
+#include <dpl/string.h>
+#include <dpl/optional.h>
+#include <dpl/shared_ptr.h>
+#include <dpl/type_list.h>
+#include <dpl/assert.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_; \
+ }
+
+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[];
+ //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 Expression {
+public:
+ virtual ~Expression() {}
+ virtual std::string GetString() const = 0;
+ virtual ArgumentIndex BindTo(DataCommand *command, ArgumentIndex index) = 0;
+};
+
+typedef DPL::SharedPtr<Expression> ExpressionPtr;
+
+template<const char* Operator, typename LeftExpression, typename RightExpression>
+class 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 ArgumentType>
+class 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 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::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 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)
+
+template<typename ColumnType>
+ColumnType GetColumnFromCommand(ColumnIndex columnIndex, DataCommand *command);
+
+template<typename ColumnList, typename Row>
+class FillRowUtil {
+public:
+ 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 Row>
+class FillRowUtil<DPL::TypeListGuard, Row> {
+public:
+ static void FillRow(Row&, ColumnIndex, DataCommand *)
+ { /* do nothing, we're past the last element of column list */ }
+};
+
+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 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 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 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();
+ }
+};
+
+template<typename TableDefinition>
+class 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);
+ }
+ }
+
+ class BindVisitor {
+ private:
+ DataCommand *m_command;
+ ArgumentIndex m_bindArgumentIndex;
+ public:
+ 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++;
+ }
+ }
+ };
+
+ 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 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;
+ 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();
+
+ 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, 0, this->m_command);
+ return row;
+ }
+
+public:
+
+ explicit Select(IOrmInterface *interface = NULL) :
+ QueryWithWhereClause<TableDefinition>(interface),
+ m_distinctResults(false)
+ {
+ }
+
+ void Distinct()
+ {
+ m_distinctResults = true;
+ }
+
+ void OrderBy(const std::string& orderBy)
+ {
+ m_orderBy = orderBy;
+ }
+
+ 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 TableDefinition>
+class 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);
+ }
+ }
+
+ 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++;
+ }
+ }
+ };
+
+ 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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* 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(args...)
+#define TABLE_CONSTRAINTS(args...)
+#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, args...)
+#define COLUMN(name, type, args...)
+#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, args...) \
+ 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, args...) \
+ 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, args...) ostr << " '" << row.name << "'" ;
+#define COLUMN(name, type, args...) 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, args...) && (this->name == row.name)
+#define COLUMN(name, type, args...) && (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, args...) if (this->name < row.name) { return true; } if (this->name > row.name) { return false; }
+#define COLUMN(name, type, args...) 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, args...) && (this->m_##name##_set == row.m_##name##_set)
+#define COLUMN(name, type, args...) && (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, args...) m_##name##_set = false;
+#define COLUMN(name, type, args...) 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, args...) visitor.Visit(STRINGIFY(name), this->name, this->m_##name##_set);
+#define COLUMN(name, type, args...) 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 {
+#define COLUMN_NOT_NULL(name, type, args...) DECLARE_COLUMN(name, type)
+#define COLUMN(name, type, args...) 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, args...) name,
+#define COLUMN(name, type, args...) 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, args...)
+#define COLUMN(name, type, args...)
+#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, args...)
+#define COLUMN(name, type, args...)
+#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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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, args...) name type args ,
+#define COLUMN_NOT_NULL(name, type, args...) name type args not null,
+#define SQL(args...) args
+#define TABLE_CONSTRAINTS(args...) args ,
+#define CREATE_TABLE_END() CHECK(1) );
+#define DATABASE_START(db_name)
+#define DATABASE_END()
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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/scoped_ptr.h>
+#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
+ };
+ };
+
+ // 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
+ ScopedPtr<SynchronizationObject> m_synchronizationObject;
+
+ virtual void Connect(const std::string &address, Flag::Type = Flag::None);
+ 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,
+ SynchronizationObject *synchronizationObject =
+ AllocDefaultSynchronizationObject());
+
+ /**
+ * Destructor
+ */
+ virtual ~SqlConnection();
+
+ /**
+ * Execute SQL command without result
+ *
+ * @param format
+ * @param ...
+ */
+ void ExecCommand(const char *format, ...);
+
+ /**
+ * 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
+ LogInfo("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())->ExecCommand("ROLLBACK;");
+ } else {
+ LogPedantic("Transaction will be commited");
+ (*Connection())->ExecCommand("COMMIT;");
+ }
+ }
+ }
+
+ public:
+ ThreadDatabaseSupport(const std::string &address,
+ DPL::DB::SqlConnection::Flag::Type flags) :
+ m_address(address),
+ m_flags(flags)
+ {
+ }
+
+ virtual ~ThreadDatabaseSupport()
+ {
+ }
+
+ void AttachToThread()
+ {
+ Linger() = false;
+
+ if (!Connection().IsNull()) {
+ // Add reference
+ ++*AttachCount();
+ return;
+ }
+
+ // Initialize SQL connection described in traits
+ LogInfo("Attaching thread database connection: " << m_address);
+
+ Connection() = new DPL::DB::SqlConnection(m_address.c_str(), m_flags);
+
+ 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);
+
+ LogInfo("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())->ExecCommand("BEGIN;");
+ }
+ }
+
+ 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <dpl/db/naive_synchronization_object.h>
+#include <dpl/thread.h>
+
+namespace DPL
+{
+namespace DB
+{
+
+void NaiveSynchronizationObject::Synchronize()
+{
+ // Sleep for about 10ms - 30ms
+ Thread::MiliSleep(10 + rand() % 20);
+}
+
+void NaiveSynchronizationObject::NotifyAll()
+{
+ // No need to inform about anything
+}
+
+} // namespace DB
+} // namespace DPL
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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";
+}
+
+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);
+}
+
+}
+}
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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 flag)
+{
+ if (m_connection != NULL)
+ {
+ LogPedantic("Already connected.");
+ return;
+ }
+
+ LogPedantic("Connecting to DB: " << address << "...");
+
+ // Connect to database
+ int result;
+
+ if (flag & Flag::UseLucene)
+ {
+ result = db_util_open_with_options(
+ address.c_str(),
+ &m_connection,
+ SQLITE_OPEN_NOMUTEX | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
+ NULL);
+
+ m_usingLucene = true;
+ LogPedantic("Lucene index enabled");
+ }
+ else
+ {
+ result = sqlite3_open_v2(
+ address.c_str(),
+ &m_connection,
+ SQLITE_OPEN_NOMUTEX | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
+ NULL);
+
+ m_usingLucene = false;
+ LogPedantic("Lucene index disabled");
+ }
+
+ if (result == SQLITE_OK)
+ {
+ LogPedantic("Connected to DB");
+ }
+ else
+ {
+ LogPedantic("Failed to connect to DB!");
+ 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
+ Assert(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,
+ 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);
+
+ 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;
+ }
+
+ 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;");
+}
+
+SqlConnection::SynchronizationObject *
+ SqlConnection::AllocDefaultSynchronizationObject()
+{
+ return new NaiveSynchronizationObject();
+}
+
+} // namespace DB
+} // namespace DPL
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <dpl/db/thread_database_support.h>
\ No newline at end of file
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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/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
+)
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <gio/gio.h>
+#include <dpl/generic_event.h>
+#include <dpl/event/event_support.h>
+#include <dpl/dbus/object.h>
+#include <dpl/dbus/object_proxy.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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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)
+ {
+ LogInfo("InterfaceDispatcher onPropertyGet: " << propertyName);
+ return NULL;
+ }
+
+ virtual gboolean onPropertySet(GDBusConnection* /*connection*/,
+ const gchar* /*sender*/,
+ const gchar* /*objectPath*/,
+ const gchar* /*interfaceName*/,
+ const gchar* propertyName,
+ GVariant* /*value*/)
+ {
+ LogInfo("InterfaceDispatcher onPropertySet: " << propertyName);
+ return false;
+ }
+private:
+ std::string m_interfaceName, m_xml;
+};
+
+} // namespace DBus
+} // namespace DPL
+
+#endif // DPL_DBUS_DBUS_INTERFACE_DISPATCHER_H_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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(),
+ [m_connection] (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)
+{
+ Assert(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)
+{
+ Assert(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)
+{
+ Assert(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);
+ }
+ }
+}
+
+}
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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;
+}
+
+}
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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)
+{
+ Assert(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)
+{
+ Assert(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)
+{
+ Assert(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;
+}
+
+}
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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()
+{
+ Assert(!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);
+
+ LogInfo("Server started at: "
+ << g_dbus_server_get_client_address(m_server));
+}
+
+void Server::stop()
+{
+ Assert(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)
+{
+ Assert(NULL != data && "User data cannot be NULL.");
+
+ Server* self = static_cast<Server*>(data);
+
+ ServerEvents::NewConnectionEvent event(
+ ConnectionPtr(new Connection(connection)));
+
+ LogInfo("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;
+}
+
+}
+}
\ No newline at end of file
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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_delivery.cpp
+ ${PROJECT_SOURCE_DIR}/modules/event/src/event_delivery_detail.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/nested_loop.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_delivery_detail.h
+ ${PROJECT_SOURCE_DIR}/modules/event/include/dpl/event/event_delivery.h
+ ${PROJECT_SOURCE_DIR}/modules/event/include/dpl/event/event_delivery_injector.h
+ ${PROJECT_SOURCE_DIR}/modules/event/include/dpl/event/event_delivery_messages.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/nested_loop.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
+)
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_delivery.h
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the header file of event delivery class
+ */
+#ifndef DPL_EVENT_DELIVERY_H
+#define DPL_EVENT_DELIVERY_H
+
+#include <dpl/event/event_delivery_detail.h>
+#include <dpl/event/event_delivery_messages.h>
+#include <dpl/event/event_support.h>
+#include <dpl/noncopyable.h>
+#include <dpl/shared_ptr.h>
+#include <dpl/exception.h>
+#include <dpl/assert.h>
+#include <dpl/foreach.h>
+#include <list>
+#include <map>
+#include <typeinfo>
+#include <string>
+
+/*
+ * Event delivery system
+ *
+ * Sample usages:
+ *
+ * I. Listening for standard predefined notifications
+ *
+ * class MyClass
+ * : public EventListener<EventMessages::RoamingChanged>
+ * {
+ * void OnEventReceived(const EventMessages::RoamingChanged& event)
+ * {
+ * std::cout << "Roaming is now " << event.GetRoamingEnabled() ? "ENABLED" : "DISABLED" << std::endl;
+ * }
+ *
+ * public:
+ * MyClass()
+ * {
+ * EventDeliverySystem::AddListener<EventMessages::RoamingChanged>(this);
+ * }
+ *
+ * virtual ~MyClass()
+ * {
+ * EventDeliverySystem::RemoveListener<EventMessages::RoamingChanged>(this);
+ * }
+ *
+ * void SendSampleSignal()
+ * {
+ * EventMessages::RoamingChanged roamingMessage(true);
+ * EventDeliverySystem::Publish(roamingMessage);
+ * }
+ * }
+ *
+ * II. Creation of custom generic events, and listening for them
+ *
+ * EVENT_DELIVERY_DECLARE_EVENT_MESSAGE_2(MyEvent, int, float);
+ *
+ * class MyClass
+ * : public EventListener<MyEvent>
+ * {
+ * void OnEventReceived(const MyEvent &event)
+ * {
+ * std::cout << "Event contents: " << event.GetArg0() << ", " << event.GetArg1() << std::endl;
+ * }
+ *
+ * public:
+ * MyClass()
+ * {
+ * EventDeliverySystem::AddListener<MyEvent>(this);
+ * }
+ *
+ * virtual ~MyClass()
+ * {
+ * EventDeliverySystem::RemoveListener<MyEvent>(this);
+ * }
+ *
+ * void SendSampleSignal()
+ * {
+ * MyEvent myEvent(5, 3.14f);
+ * EventDeliverySystem::Publish(myEvent);
+ * }
+ * }
+ *
+ * In source file, one must add implementation of event delivery message:
+ *
+ * EVENT_DELIVERY_IMPLEMENT_EVENT_MESSAGE(MyEvent)
+ *
+ */
+namespace DPL
+{
+namespace Event
+{
+
+class AbstractEventDeliverySystemPublisher
+{
+public:
+ virtual ~AbstractEventDeliverySystemPublisher() = 0;
+};
+
+template<typename EventType>
+class EventDeliverySystemPublisher
+ : private EventSupport<EventType>
+ , public AbstractEventDeliverySystemPublisher
+{
+public:
+ typedef typename EventSupport<EventType>::EventListenerType EventListenerType;
+
+private:
+ friend class EventDeliverySystem;
+
+ EventDeliverySystemPublisher(EventListenerType *eventListener)
+ : m_eventListener(eventListener)
+ {
+ EventSupport<EventType>::AddListener(m_eventListener);
+ }
+
+ EventListenerType *m_eventListener;
+
+public:
+ ~EventDeliverySystemPublisher()
+ {
+ EventSupport<EventType>::RemoveListener(m_eventListener);
+ }
+
+ void PublishEvent(const EventType &event)
+ {
+ EmitEvent(event, EmitMode::Queued);
+ }
+
+ EventListenerType *GetListener() const
+ {
+ return m_eventListener;
+ }
+};
+
+template<typename Type>
+class EventDeliverySystemTraits
+{
+public:
+ typedef Type EventType;
+ typedef EventDeliverySystemPublisher<EventType> PublisherType;
+ typedef typename PublisherType::EventListenerType EventListenerType;
+ typedef SharedPtr<PublisherType> PublisherPtrType;
+ typedef std::list<PublisherPtrType> PublisherPtrContainerType;
+};
+
+class EventDeliverySystem
+ : private Noncopyable
+{
+private:
+ typedef SharedPtr<AbstractEventDeliverySystemPublisher> AbstractPublisherPtrType;
+ typedef std::list<AbstractPublisherPtrType> AbstractPublisherPtrContainerType;
+ typedef AbstractPublisherPtrContainerType::const_iterator AbstractPublisherPtrContainerTypeConstIterator;
+ typedef AbstractPublisherPtrContainerType::iterator AbstractPublisherPtrContainerTypeIterator;
+ typedef std::map<std::string, AbstractPublisherPtrContainerType> AbstractPublisherPtrContainerMapType;
+
+ template<class EventType>
+ class CrtDeleteCheck
+ {
+ private:
+ const AbstractPublisherPtrContainerType &m_publisherContainer;
+
+ public:
+ CrtDeleteCheck(const AbstractPublisherPtrContainerType &publisherContainer)
+ : m_publisherContainer(publisherContainer)
+ {
+ }
+
+ virtual ~CrtDeleteCheck()
+ {
+ Assert(m_publisherContainer.empty() && "All event delivery listeners must be removed before exit!");
+ }
+ };
+
+ // Map containing publishers for all registered events
+ static AbstractPublisherPtrContainerMapType m_publishers;
+
+ // Detail implementation: lazy initialized
+ static EventDeliverySystemDetail m_detailSystem;
+
+ EventDeliverySystem()
+ {
+ }
+
+ template<typename EventType>
+ static AbstractPublisherPtrContainerType &GetPublisherContainerRef()
+ {
+ std::string typeId = typeid(EventType).name();
+
+ //FIXME: problem with linking per compilation unit won't hurt this check?
+ static CrtDeleteCheck<EventType> crtDeleteCheck(m_publishers[typeId]);
+ (void)crtDeleteCheck;
+
+ return m_publishers[typeId];
+ }
+
+ template<typename EventType>
+ static typename EventDeliverySystemTraits<EventType>::PublisherPtrContainerType GetPublisherContainer()
+ {
+ std::string typeId = typeid(EventType).name();
+ typedef typename EventDeliverySystemTraits<EventType>::PublisherPtrContainerType PublisherContainerType;
+ typedef typename EventDeliverySystemTraits<EventType>::PublisherType PublisherType;
+ typedef typename EventDeliverySystemTraits<EventType>::PublisherPtrType PublisherPtrType;
+
+ AbstractPublisherPtrContainerType eventPublishers = m_publishers[typeId];
+ PublisherContainerType publisherContainer;
+
+ FOREACH(iterator, eventPublishers)
+ {
+ PublisherPtrType publisher =
+ StaticPointerCast<PublisherType>(*iterator);
+ publisherContainer.push_back(publisher);
+ }
+
+ return publisherContainer;
+ }
+
+ // Detail access
+ template<typename EventType>
+ static void Inject(const EventType &event)
+ {
+ typedef typename EventDeliverySystemTraits<EventType>::PublisherPtrContainerType PublisherContainerType;
+ typedef typename EventDeliverySystemTraits<EventType>::PublisherPtrType PublisherPtrType;
+
+ PublisherContainerType publisherContainer = GetPublisherContainer<EventType>();
+ typename PublisherContainerType::iterator iterator;
+
+ for (iterator = publisherContainer.begin(); iterator != publisherContainer.end(); ++iterator)
+ {
+ PublisherPtrType &publisher = *iterator;
+ publisher->PublishEvent(event);
+ }
+ }
+
+ template<typename EventType>
+ class PublisherPtrContainerListenerPredicate
+ {
+ public:
+ typedef EventListener<EventType> EventListenerType;
+
+ private:
+ EventListenerType *m_listener;
+
+ public:
+ PublisherPtrContainerListenerPredicate(EventListenerType *listener)
+ : m_listener(listener)
+ {
+ }
+
+ bool operator()(const AbstractPublisherPtrType &publisher) const
+ {
+ return StaticPointerCast<typename EventDeliverySystemTraits<EventType>::PublisherType>(publisher)->GetListener() == m_listener;
+ }
+ };
+
+ friend class EventDeliverySystemInjector;
+
+public:
+ virtual ~EventDeliverySystem()
+ {
+ }
+
+ template<typename EventType>
+ static void AddListener(EventListener<EventType> *listener)
+ {
+ typedef typename EventDeliverySystemTraits<EventType>::PublisherType PublisherType;
+ typedef typename EventDeliverySystemTraits<EventType>::PublisherPtrType PublisherPtrType;
+ typedef typename EventDeliverySystemTraits<EventType>::PublisherPtrContainerType PublisherPtrContainerType;
+
+ typedef PublisherPtrContainerListenerPredicate<EventType> PublisherPtrContainerListenerPredicateType;
+
+ AbstractPublisherPtrContainerType &publisherContainer = GetPublisherContainerRef<EventType>();
+ AbstractPublisherPtrContainerTypeConstIterator iterator =
+ std::find_if(publisherContainer.begin(), publisherContainer.end(), PublisherPtrContainerListenerPredicateType(listener));
+
+ Assert(iterator == publisherContainer.end() && "Listener already exists");
+
+ // Add new publisher
+ publisherContainer.push_back(AbstractPublisherPtrType(new PublisherType(listener)));
+
+ // When first listener is inserted, start to listen for events
+ if (publisherContainer.size() == 1) {
+ m_detailSystem.Listen(EventType());
+ }
+ }
+
+ template<typename EventType>
+ static void RemoveListener(EventListener<EventType> *listener)
+ {
+ typedef typename EventDeliverySystemTraits<EventType>::PublisherType PublisherType;
+ typedef typename EventDeliverySystemTraits<EventType>::PublisherPtrType PublisherPtrType;
+ typedef typename EventDeliverySystemTraits<EventType>::PublisherPtrContainerType PublisherPtrContainerType;
+
+ typedef PublisherPtrContainerListenerPredicate<EventType> PublisherPtrContainerListenerPredicateType;
+
+ AbstractPublisherPtrContainerType &publisherContainer = GetPublisherContainerRef<EventType>();
+
+ AbstractPublisherPtrContainerTypeIterator iterator =
+ std::find_if(publisherContainer.begin(), publisherContainer.end(), PublisherPtrContainerListenerPredicateType(listener));
+
+ Assert(iterator != publisherContainer.end() && "Listener does not exist");
+
+ // Remove publisher
+ publisherContainer.erase(iterator);
+
+ // When last listener was removed, stop to listen for events
+ if (publisherContainer.empty())
+ m_detailSystem.Unlisten(EventType());
+ }
+
+ template<typename EventType>
+ static void Publish(const EventType &event)
+ {
+ m_detailSystem.Publish(event);
+ }
+};
+
+}
+} // namespace DPL
+
+#endif // DPL_EVENT_DELIVERY_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_delivery_detail.h
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the header file of event delivery EFL detail class
+ */
+#ifndef DPL_EVENT_DELIVERY_DETAIL_EFL_H
+#define DPL_EVENT_DELIVERY_DETAIL_EFL_H
+
+#include <dpl/event/event_delivery_messages.h>
+#include <dpl/framework_vconf.h>
+#include <dpl/noncopyable.h>
+#include <dpl/assert.h>
+#include <string>
+#include <list>
+
+namespace DPL
+{
+namespace Event
+{
+
+class EventDeliverySystemDetail
+ : private Noncopyable
+{
+private:
+ // Generic noti event prefixes
+ static const char *NOTI_EVENT_ID_GENERIC_0;
+ static const char *NOTI_EVENT_ID_GENERIC_1;
+ static const char *NOTI_EVENT_ID_GENERIC_2;
+ static const char *NOTI_EVENT_ID_GENERIC_3;
+ static const char *NOTI_EVENT_ID_GENERIC_4;
+
+ // Other noti events
+ static const char *NOTI_EVENT_ID_NULL;
+
+ // Main noti handle
+ int m_notiHandle;
+
+ // Noti signaling class
+ class NotiSignal
+ {
+ private:
+ EventDeliverySystemDetail *m_receiver;
+ const char *m_gcid;
+ int m_sysnoti;
+ std::string m_eventName;
+
+ public:
+ NotiSignal(EventDeliverySystemDetail *receiver, const char *gcid, const std::string &eventName)
+ : m_receiver(receiver),
+ m_gcid(gcid),
+ m_sysnoti(-1),
+ m_eventName(eventName)
+ {
+ Assert(receiver != NULL);
+ }
+
+ NotiSignal(EventDeliverySystemDetail *receiver, int sysnoti)
+ : m_receiver(receiver),
+ m_gcid(NULL),
+ m_sysnoti(sysnoti)
+ {
+ Assert(receiver != NULL);
+ }
+
+ const char *GetGcid() const
+ {
+ return m_gcid;
+ }
+
+ int GetSysNoti() const
+ {
+ return m_sysnoti;
+ }
+
+ std::string GetEventName() const
+ {
+ return m_eventName;
+ }
+
+ EventDeliverySystemDetail *GetReceiver() const
+ {
+ return m_receiver;
+ }
+ };
+
+ // Registered noti singal list
+ typedef std::list<NotiSignal> NotiSignalList;
+ NotiSignalList m_notiSignalList;
+
+ // setting library callbacks
+ class SettingSignal
+ {
+ private:
+ EventDeliverySystemDetail *m_receiver;
+ std::string m_key;
+
+ public:
+ SettingSignal(EventDeliverySystemDetail *receiver, const std::string &key)
+ : m_receiver(receiver),
+ m_key(key)
+ {
+ }
+
+ std::string GetKey() const
+ {
+ return m_key;
+ }
+
+ EventDeliverySystemDetail *GetReceiver() const
+ {
+ return m_receiver;
+ }
+ };
+
+ typedef std::list<SettingSignal> SettingSignalList;
+ SettingSignalList m_settingSignalList;
+
+ // Global noti callbacks
+ class GlobalNotiSignal
+ {
+ private:
+ EventDeliverySystemDetail *m_receiver;
+ std::string m_key;
+
+ public:
+ GlobalNotiSignal(EventDeliverySystemDetail *receiver, const std::string &key)
+ : m_receiver(receiver),
+ m_key(key)
+ {
+ }
+
+ std::string GetKey() const
+ {
+ return m_key;
+ }
+
+ EventDeliverySystemDetail *GetReceiver() const
+ {
+ return m_receiver;
+ }
+ };
+
+ typedef std::list<GlobalNotiSignal> GlobalNotiSignalList;
+ GlobalNotiSignalList m_globalNotiSignalList;
+
+ // Utilities
+ std::string ReadFile(const std::string &fileName) const;
+ std::string GetGenericNotiFilePath(const std::string &eventName) const;
+
+ // Noti callback registration/unregistration
+ void RegisterFileNotiCallback(const char *gcid, const std::string &eventName);
+ void UnregisterFileNotiCallback(const std::string &eventName);
+
+ void RegisterSettingCallback(const std::string &key);
+ void UnregisterSettingCallback(const std::string &key);
+
+ void RegisterGlobalNotiCallback(const std::string &key);
+ void UnregisterGlobalNotiCallback(const std::string &key);
+
+ // Emit noti signal
+ void SignalGenericNoti(const std::string &eventName, const std::string &contents) const;
+
+ // Signals
+ static void OnNotiGlobalSignal(void *notiData);
+ static void OnSettingSignal(keynode_t *keyNode, void *userParam);
+ static void OnGlobalNotiSignal(void *globalNotiData);
+
+ void OnNotiSignal(NotiSignal *notiSignal);
+
+public:
+ EventDeliverySystemDetail();
+ virtual ~EventDeliverySystemDetail();
+
+ void Listen(const EventMessages::RoamingChanged &event);
+ void Listen(const EventMessages::NetworkTypeChanged &event);
+ void Listen(const EventMessages::HibernationEnter &event);
+ void Listen(const EventMessages::HibernationLeave &event);
+
+ void Unlisten(const EventMessages::RoamingChanged &event);
+ void Unlisten(const EventMessages::NetworkTypeChanged &event);
+ void Unlisten(const EventMessages::HibernationEnter &event);
+ void Unlisten(const EventMessages::HibernationLeave &event);
+
+ void Publish(const EventMessages::Generic0 &event)
+ {
+ std::string eventName = std::string(NOTI_EVENT_ID_GENERIC_0) + event.GetGcid();
+ SignalGenericNoti(eventName, event.SerializeType());
+ }
+
+ template<typename Arg0Type>
+ void Publish(const EventMessages::Generic1<Arg0Type> &event)
+ {
+ std::string eventName = std::string(NOTI_EVENT_ID_GENERIC_1) + event.GetGcid();
+ SignalGenericNoti(eventName, event.SerializeType());
+ }
+
+ template<typename Arg0Type, typename Arg1Type>
+ void Publish(const EventMessages::Generic2<Arg0Type, Arg1Type> &event)
+ {
+ std::string eventName = std::string(NOTI_EVENT_ID_GENERIC_2) + event.GetGcid();
+ SignalGenericNoti(eventName, event.SerializeType());
+ }
+
+ template<typename Arg0Type, typename Arg1Type, typename Arg2Type>
+ void Publish(const EventMessages::Generic3<Arg0Type, Arg1Type, Arg2Type> &event)
+ {
+ std::string eventName = std::string(NOTI_EVENT_ID_GENERIC_3) + event.GetGcid();
+ SignalGenericNoti(eventName, event.SerializeType());
+ }
+
+ template<typename Arg0Type, typename Arg1Type, typename Arg2Type, typename Arg3Type>
+ void Publish(const EventMessages::Generic4<Arg0Type, Arg1Type, Arg2Type, Arg3Type> &event)
+ {
+ std::string eventName = std::string(NOTI_EVENT_ID_GENERIC_4) + event.GetGcid();
+ SignalGenericNoti(eventName, event.SerializeType());
+ }
+
+ void Listen(const EventMessages::Generic0 &event)
+ {
+ std::string eventName = std::string(NOTI_EVENT_ID_GENERIC_0) + event.GetGcid();
+ RegisterFileNotiCallback(event.GetGcid(), eventName);
+ }
+
+ template<typename Arg0Type>
+ void Listen(const EventMessages::Generic1<Arg0Type> &event)
+ {
+ std::string eventName = std::string(NOTI_EVENT_ID_GENERIC_1) + event.GetGcid();
+ RegisterFileNotiCallback(event.GetGcid(), eventName);
+ }
+
+ template<typename Arg0Type, typename Arg1Type>
+ void Listen(const EventMessages::Generic2<Arg0Type, Arg1Type> &event)
+ {
+ std::string eventName = std::string(NOTI_EVENT_ID_GENERIC_2) + event.GetGcid();
+ RegisterFileNotiCallback(event.GetGcid(), eventName);
+ }
+
+ template<typename Arg0Type, typename Arg1Type, typename Arg2Type>
+ void Listen(const EventMessages::Generic3<Arg0Type, Arg1Type, Arg2Type> &event)
+ {
+ std::string eventName = std::string(NOTI_EVENT_ID_GENERIC_3) + event.GetGcid();
+ RegisterFileNotiCallback(event.GetGcid(), eventName);
+ }
+
+ template<typename Arg0Type, typename Arg1Type, typename Arg2Type, typename Arg3Type>
+ void Listen(const EventMessages::Generic4<Arg0Type, Arg1Type, Arg2Type, Arg3Type> &event)
+ {
+ std::string eventName = std::string(NOTI_EVENT_ID_GENERIC_4) + event.GetGcid();
+ RegisterFileNotiCallback(event.GetGcid(), eventName);
+ }
+
+ void Unlisten(const EventMessages::Generic0 &event)
+ {
+ std::string eventName = std::string(NOTI_EVENT_ID_GENERIC_0) + event.GetGcid();
+ UnregisterFileNotiCallback(eventName);
+ }
+
+ template<typename Arg0Type>
+ void Unlisten(const EventMessages::Generic1<Arg0Type> &event)
+ {
+ std::string eventName = std::string(NOTI_EVENT_ID_GENERIC_1) + event.GetGcid();
+ UnregisterFileNotiCallback(eventName);
+ }
+
+ template<typename Arg0Type, typename Arg1Type>
+ void Unlisten(const EventMessages::Generic2<Arg0Type, Arg1Type> &event)
+ {
+ std::string eventName = std::string(NOTI_EVENT_ID_GENERIC_2) + event.GetGcid();
+ UnregisterFileNotiCallback(eventName);
+ }
+
+ template<typename Arg0Type, typename Arg1Type, typename Arg2Type>
+ void Unlisten(const EventMessages::Generic3<Arg0Type, Arg1Type, Arg2Type> &event)
+ {
+ std::string eventName = std::string(NOTI_EVENT_ID_GENERIC_3) + event.GetGcid();
+ UnregisterFileNotiCallback(eventName);
+ }
+
+ template<typename Arg0Type, typename Arg1Type, typename Arg2Type, typename Arg3Type>
+ void Unlisten(const EventMessages::Generic4<Arg0Type, Arg1Type, Arg2Type, Arg3Type> &event)
+ {
+ std::string eventName = std::string(NOTI_EVENT_ID_GENERIC_4) + event.GetGcid();
+ UnregisterFileNotiCallback(eventName);
+ }
+};
+
+}
+} // namespace DPL
+
+#endif // DPL_EVENT_DELIVERY_DETAIL_EFL_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_delivery_injector.h
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the header file of event delivery injector
+ */
+#ifndef DPL_EVENT_DELIVERY_INJECTOR_H
+#define DPL_EVENT_DELIVERY_INJECTOR_H
+
+#include <dpl/event/event_delivery.h>
+#include <dpl/noncopyable.h>
+#include <dpl/log/log.h>
+#include <utility>
+#include <string>
+#include <map>
+
+namespace DPL
+{
+namespace Event
+{
+
+class EventDeliverySystemInjector
+ : private Noncopyable
+{
+private:
+ EventDeliverySystemInjector()
+ {
+ }
+
+ typedef void (*MetaCall)(const std::string &metaData);
+ typedef std::map<const char *, MetaCall> MetaCallContainer;
+ MetaCallContainer m_metaCalls;
+
+public:
+ virtual ~EventDeliverySystemInjector()
+ {
+ }
+
+ static EventDeliverySystemInjector &Instance()
+ {
+ static EventDeliverySystemInjector instance;
+ return instance;
+ }
+
+ void PublishMetaType(const char *metaType, const std::string &metaData)
+ {
+ // Unwrap meta type (indirect Publish meta call)
+ m_metaCalls[metaType](metaData);
+ }
+
+ template<typename EventMessageType>
+ void Publish(const EventMessageType &message)
+ {
+ EventDeliverySystem::Inject(message);
+ }
+
+ void RegisterMetaCall(const char *metaType, MetaCall metaCall)
+ {
+ m_metaCalls.insert(std::make_pair(metaType, metaCall));
+ }
+};
+
+}
+} // namespace DPL
+
+#endif // DPL_EVENT_DELIVERY_INJECTOR_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_delivery_messages.h
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the header file of event delivery messages
+ */
+#ifndef DPL_EVENT_DELIVERY_MESSAGES_H
+#define DPL_EVENT_DELIVERY_MESSAGES_H
+
+#include <cstring>
+#include <sstream>
+#include <string>
+#include <vector>
+
+namespace DPL
+{
+namespace Event
+{
+
+namespace EventMessages
+{
+/**
+ * Generic event message base
+ *
+ * Custom events are derived from these templates
+ * Only template GenericN members are serialized
+ *
+ * Assumptions:
+ *
+ * 1. Arg* must be default constructible
+ * 2. For Arg* there must be defined << and >> operators
+ */
+class GenericBase
+{
+private:
+ const char *m_gcid; ///< Global class ID
+ static const char SEPARATOR = '\254'; ///< Unique serialized data separator
+ static const size_t DESERIALIZE_STRING_FIELD_CHUNK_SIZE = 128; ///< Chunk size while parsing serialized event data
+
+protected:
+ template<class Type>
+ void SerializeField(std::ostream &stream, const Type &type) const
+ {
+ stream << type;
+ }
+
+ void SerializeSeparator(std::ostream &stream) const
+ {
+ stream << SEPARATOR;
+ }
+
+ std::vector<std::string> SplitStream(const std::string &stream) const
+ {
+ char separator[2] = {};
+ separator[0] = SEPARATOR;
+ std::vector<std::string> splitVector;
+
+ char *splitTab = new char[stream.size() + 1];
+ strcpy(splitTab, stream.c_str());
+
+ // Split serialized stream
+ char *savePtr;
+ char *splitPtr = strtok_r(splitTab, separator, &savePtr);
+
+ while (splitPtr != NULL)
+ {
+ splitVector.push_back(std::string(splitPtr));
+ splitPtr = strtok_r(NULL, separator, &savePtr);
+ }
+
+ delete [] splitTab;
+
+ return splitVector;
+ }
+
+ template<class Type>
+ Type DeserializeField(std::istream &stream, const Type &) const
+ {
+ Type type;
+ stream >> type;
+ return type;
+ }
+
+ std::string DeserializeField(std::istream &stream, const std::string &) const
+ {
+ std::string result;
+ char buffer[DESERIALIZE_STRING_FIELD_CHUNK_SIZE];
+
+ for (;;)
+ {
+ stream.get(buffer, DESERIALIZE_STRING_FIELD_CHUNK_SIZE);
+
+ if (stream.gcount() < 1)
+ break;
+
+ result += std::string(buffer, buffer + stream.gcount());
+ }
+
+ return result;
+ }
+
+public:
+ /**
+ * Init constructor
+ */
+ explicit GenericBase(const char *gcid)
+ : m_gcid(gcid)
+ {
+ }
+
+ /**
+ * Destructor
+ */
+ virtual ~GenericBase()
+ {
+ }
+
+ const char *GetGcid() const { return m_gcid; }
+
+ /**
+ * Serialize event n-tuple
+ *
+ * @return Ouput serialized stream
+ * @warning Internal use only
+ */
+ virtual std::string SerializeType() const = 0;
+
+ /**
+ * Deserialize event n-tuple
+ *
+ * @param[in] stream Input stream to deserialize from
+ * @warning Internal use only
+ */
+ virtual void DeserializeType(const std::string &stream) = 0;
+};
+
+class Generic0
+ : public GenericBase
+{
+public:
+ /**
+ * Init constructor
+ */
+ explicit Generic0(const char *Gcid)
+ : GenericBase(Gcid)
+ {
+ }
+
+ /**
+ * Destructor
+ */
+ virtual ~Generic0()
+ {
+ }
+
+ /**
+ * Serialize event 0-tuple
+ *
+ * @return Ouput serialized stream
+ * @warning Internal use only
+ */
+ virtual std::string SerializeType() const
+ {
+ return std::string();
+ }
+
+ /**
+ * Deserialize event 0-tuple
+ *
+ * @param[in] stream Input stream to deserialize from
+ * @warning Internal use only
+ */
+ virtual void DeserializeType(const std::string &stream)
+ {
+ (void)stream;
+ }
+};
+
+template<typename Arg0Type>
+class Generic1
+ : public GenericBase
+{
+public:
+ typedef Arg0Type Arg0;
+
+private:
+ Arg0 m_arg0;
+
+public:
+ /**
+ * Init constructor
+ */
+ explicit Generic1(const char *Gcid)
+ : GenericBase(Gcid),
+ m_arg0()
+ {
+ }
+
+ /**
+ * Full init constructor
+ */
+ explicit Generic1(const char *Gcid, const Arg0 &arg0)
+ : GenericBase(Gcid),
+ m_arg0(arg0)
+ {
+ }
+
+ /**
+ * Destructor
+ */
+ virtual ~Generic1()
+ {
+ }
+
+ /**
+ * Retrieve value of argument 0 from tuple
+ *
+ * @return Argument value
+ */
+ const Arg0 &GetArg0() const
+ {
+ return m_arg0;
+ }
+
+ /**
+ * Set value of argument 0 in tuple
+ *
+ * @param[in] value Argument value
+ */
+ void SetArg0(const Arg0 &value)
+ {
+ m_arg0 = value;
+ }
+
+ /**
+ * Serialize event 1-tuple
+ *
+ * @return Ouput serialized stream
+ * @warning Internal use only
+ */
+ virtual std::string SerializeType() const
+ {
+ std::ostringstream s;
+ SerializeField(s, m_arg0);
+ return s.str();
+ }
+
+ /**
+ * Deserialize event 1-tuple
+ *
+ * @param[in] stream Input stream to deserialize from
+ * @warning Internal use only
+ */
+ virtual void DeserializeType(const std::string &stream)
+ {
+ std::vector<std::string> splitVector = SplitStream(stream);
+ if (splitVector.size() != 1)
+ return;
+ std::istringstream s0(splitVector[0]);
+ m_arg0 = DeserializeField(s0, Arg0());
+ }
+};
+
+template<typename Arg0Type, typename Arg1Type>
+class Generic2
+ : public GenericBase
+{
+public:
+ typedef Arg0Type Arg0;
+ typedef Arg1Type Arg1;
+
+private:
+ Arg0 m_arg0;
+ Arg1 m_arg1;
+
+public:
+ /**
+ * Init constructor
+ */
+ explicit Generic2(const char *Gcid)
+ : GenericBase(Gcid),
+ m_arg0(),
+ m_arg1()
+ {
+ }
+
+ /**
+ * Full init constructor
+ */
+ explicit Generic2(const char *Gcid, const Arg0 &arg0, const Arg1 &arg1)
+ : GenericBase(Gcid),
+ m_arg0(arg0),
+ m_arg1(arg1)
+ {
+ }
+
+ /**
+ * Destructor
+ */
+ virtual ~Generic2()
+ {
+ }
+
+ /**
+ * Retrieve value of argument 0 from tuple
+ *
+ * @return Argument value
+ */
+ const Arg0 &GetArg0() const
+ {
+ return m_arg0;
+ }
+
+ /**
+ * Set value of argument 0 in tuple
+ *
+ * @param[in] value Argument value
+ */
+ void SetArg0(const Arg0 &value)
+ {
+ m_arg0 = value;
+ }
+
+ /**
+ * Retrieve value of argument 1 from tuple
+ *
+ * @return Argument value
+ */
+ const Arg1 &GetArg1() const
+ {
+ return m_arg1;
+ }
+
+ /**
+ * Set value of argument 1 in tuple
+ *
+ * @param[in] value Argument value
+ */
+ void SetArg1(const Arg1 &value)
+ {
+ m_arg1 = value;
+ }
+
+ /**
+ * Serialize event 2-tuple
+ *
+ * @return Ouput serialized stream
+ * @warning Internal use only
+ */
+ virtual std::string SerializeType() const
+ {
+ std::ostringstream s;
+ SerializeField(s, m_arg0);
+ SerializeSeparator(s);
+ SerializeField(s, m_arg1);
+ return s.str();
+ }
+
+ /**
+ * Deserialize event 2-tuple
+ *
+ * @param[in] stream Input stream to deserialize from
+ * @warning Internal use only
+ */
+ virtual void DeserializeType(const std::string &stream)
+ {
+ std::vector<std::string> splitVector = SplitStream(stream);
+ if (splitVector.size() != 2)
+ return;
+ std::istringstream s0(splitVector[0]);
+ std::istringstream s1(splitVector[1]);
+ m_arg0 = DeserializeField(s0, Arg0());
+ m_arg1 = DeserializeField(s1, Arg1());
+ }
+};
+
+template<typename Arg0Type, typename Arg1Type, typename Arg2Type>
+class Generic3
+ : public GenericBase
+{
+public:
+ typedef Arg0Type Arg0;
+ typedef Arg1Type Arg1;
+ typedef Arg2Type Arg2;
+
+private:
+ Arg0 m_arg0;
+ Arg1 m_arg1;
+ Arg2 m_arg2;
+
+public:
+ /**
+ * Init constructor
+ */
+ explicit Generic3(const char *Gcid)
+ : GenericBase(Gcid),
+ m_arg0(),
+ m_arg1(),
+ m_arg2()
+ {
+ }
+
+ /**
+ * Full init constructor
+ */
+ explicit Generic3(const char *Gcid, const Arg0 &arg0, const Arg1 &arg1, const Arg2 &arg2)
+ : GenericBase(Gcid),
+ m_arg0(arg0),
+ m_arg1(arg1),
+ m_arg2(arg2)
+ {
+ }
+
+ /**
+ * Destructor
+ */
+ virtual ~Generic3()
+ {
+ }
+
+ /**
+ * Retrieve value of argument 0 from tuple
+ *
+ * @return Argument value
+ */
+ const Arg0 &GetArg0() const
+ {
+ return m_arg0;
+ }
+
+ /**
+ * Set value of argument 0 in tuple
+ *
+ * @param[in] value Argument value
+ */
+ void SetArg0(const Arg0 &value)
+ {
+ m_arg0 = value;
+ }
+
+ /**
+ * Retrieve value of argument 1 from tuple
+ *
+ * @return Argument value
+ */
+ const Arg1 &GetArg1() const
+ {
+ return m_arg1;
+ }
+
+ /**
+ * Set value of argument 1 in tuple
+ *
+ * @param[in] value Argument value
+ */
+ void SetArg1(const Arg1 &value)
+ {
+ m_arg1 = value;
+ }
+
+ /**
+ * Retrieve value of argument 2 from tuple
+ *
+ * @return Argument value
+ */
+ const Arg2 &GetArg2() const
+ {
+ return m_arg2;
+ }
+
+ /**
+ * Set value of argument 2 in tuple
+ *
+ * @param[in] value Argument value
+ */
+ void SetArg2(const Arg2 &value)
+ {
+ m_arg2 = value;
+ }
+
+ /**
+ * Serialize event 3-tuple
+ *
+ * @return Ouput serialized stream
+ * @warning Internal use only
+ */
+ virtual std::string SerializeType() const
+ {
+ std::ostringstream s;
+ SerializeField(s, m_arg0);
+ SerializeSeparator(s);
+ SerializeField(s, m_arg1);
+ SerializeSeparator(s);
+ SerializeField(s, m_arg2);
+ return s.str();
+ }
+
+ /**
+ * Deserialize event 3-tuple
+ *
+ * @param[in] stream Input stream to deserialize from
+ * @warning Internal use only
+ */
+ virtual void DeserializeType(const std::string &stream)
+ {
+ std::vector<std::string> splitVector = SplitStream(stream);
+ if (splitVector.size() != 3)
+ return;
+ std::istringstream s0(splitVector[0]);
+ std::istringstream s1(splitVector[1]);
+ std::istringstream s2(splitVector[2]);
+ m_arg0 = DeserializeField(s0, Arg0());
+ m_arg1 = DeserializeField(s1, Arg1());
+ m_arg2 = DeserializeField(s2, Arg2());
+ }
+};
+
+template<typename Arg0Type, typename Arg1Type, typename Arg2Type, typename Arg3Type>
+class Generic4
+ : public GenericBase
+{
+public:
+ typedef Arg0Type Arg0;
+ typedef Arg1Type Arg1;
+ typedef Arg2Type Arg2;
+ typedef Arg3Type Arg3;
+
+private:
+ Arg0 m_arg0;
+ Arg1 m_arg1;
+ Arg2 m_arg2;
+ Arg3 m_arg3;
+
+public:
+ /**
+ * Init constructor
+ */
+ explicit Generic4(const char *Gcid)
+ : GenericBase(Gcid),
+ m_arg0(),
+ m_arg1(),
+ m_arg2(),
+ m_arg3()
+ {
+ }
+
+ /**
+ * Full init constructor
+ */
+ explicit Generic4(const char *Gcid, const Arg0 &arg0, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3)
+ : GenericBase(Gcid),
+ m_arg0(arg0),
+ m_arg1(arg1),
+ m_arg2(arg2),
+ m_arg3(arg3)
+ {
+ }
+
+ /**
+ * Destructor
+ */
+ virtual ~Generic4()
+ {
+ }
+
+ /**
+ * Retrieve value of argument 0 from tuple
+ *
+ * @return Argument value
+ */
+ const Arg0 &GetArg0() const
+ {
+ return m_arg0;
+ }
+
+ /**
+ * Set value of argument 0 in tuple
+ *
+ * @param[in] value Argument value
+ */
+ void SetArg0(const Arg0 &value)
+ {
+ m_arg0 = value;
+ }
+
+ /**
+ * Retrieve value of argument 1 from tuple
+ *
+ * @return Argument value
+ */
+ const Arg1 &GetArg1() const
+ {
+ return m_arg1;
+ }
+
+ /**
+ * Set value of argument 1 in tuple
+ *
+ * @param[in] value Argument value
+ */
+ void SetArg1(const Arg1 &value)
+ {
+ m_arg1 = value;
+ }
+
+ /**
+ * Retrieve value of argument 2 from tuple
+ *
+ * @return Argument value
+ */
+ const Arg2 &GetArg2() const
+ {
+ return m_arg2;
+ }
+
+ /**
+ * Set value of argument 2 in tuple
+ *
+ * @param[in] value Argument value
+ */
+ void SetArg2(const Arg2 &value)
+ {
+ m_arg2 = value;
+ }
+
+ /**
+ * Retrieve value of argument 3 from tuple
+ *
+ * @return Argument value
+ */
+ const Arg3 &GetArg3() const
+ {
+ return m_arg3;
+ }
+
+ /**
+ * Set value of argument 3 in tuple
+ *
+ * @param[in] value Argument value
+ */
+ void SetArg3(const Arg3 &value)
+ {
+ m_arg3 = value;
+ }
+
+ /**
+ * Serialize event 4-tuple
+ *
+ * @return Ouput serialized stream
+ * @warning Internal use only
+ */
+ virtual std::string SerializeType() const
+ {
+ std::ostringstream s;
+ SerializeField(s, m_arg0);
+ SerializeSeparator(s);
+ SerializeField(s, m_arg1);
+ SerializeSeparator(s);
+ SerializeField(s, m_arg2);
+ SerializeSeparator(s);
+ SerializeField(s, m_arg3);
+ return s.str();
+ }
+
+ /**
+ * Deserialize event 4-tuple
+ *
+ * @param[in] stream Input stream to deserialize from
+ * @warning Internal use only
+ */
+ virtual void DeserializeType(const std::string &stream)
+ {
+ std::vector<std::string> splitVector = SplitStream(stream);
+ if (splitVector.size() != 4)
+ return;
+ std::istringstream s0(splitVector[0]);
+ std::istringstream s1(splitVector[1]);
+ std::istringstream s2(splitVector[2]);
+ std::istringstream s3(splitVector[3]);
+ m_arg0 = DeserializeField(s0, Arg0());
+ m_arg1 = DeserializeField(s1, Arg1());
+ m_arg2 = DeserializeField(s2, Arg2());
+ m_arg3 = DeserializeField(s3, Arg3());
+ }
+};
+
+// Event declarators
+#define EVENT_DELIVERY_DECLARE_EVENT_MESSAGE_0(EventType) \
+ void EventType##_Inject(const std::string &metaData); \
+ struct EventType##_StaticDeclarator \
+ { \
+ static char Name[0xFF]; \
+ EventType##_StaticDeclarator(); \
+ }; \
+ class EventType : public DPL::Event::EventMessages::Generic0 \
+ { \
+ public: \
+ EventType() : DPL::Event::EventMessages::Generic0(EventType##_StaticDeclarator::Name) {} \
+ };
+
+#define EVENT_DELIVERY_DECLARE_EVENT_MESSAGE_1(EventType, EventArg0Type) \
+ void EventType##_Inject(const std::string &metaData); \
+ struct EventType##_StaticDeclarator \
+ { \
+ static char Name[0xFF]; \
+ EventType##_StaticDeclarator(); \
+ }; \
+ class EventType : public DPL::Event::EventMessages::Generic1<EventArg0Type> \
+ { \
+ public: \
+ EventType() : DPL::Event::EventMessages::Generic1<EventArg0Type>(EventType##_StaticDeclarator::Name) {} \
+ EventType(const Arg0 &arg0) : DPL::Event::EventMessages::Generic1<EventArg0Type>(EventType##_StaticDeclarator::Name, arg0) {} \
+ };
+
+#define EVENT_DELIVERY_DECLARE_EVENT_MESSAGE_2(EventType, EventArg0Type, EventArg1Type) \
+ void EventType##_Inject(const std::string &metaData); \
+ struct EventType##_StaticDeclarator \
+ { \
+ static char Name[0xFF]; \
+ EventType##_StaticDeclarator(); \
+ }; \
+ class EventType : public DPL::Event::EventMessages::Generic2<EventArg0Type, EventArg1Type> \
+ { \
+ public: \
+ EventType() : DPL::Event::EventMessages::Generic2<EventArg0Type, EventArg1Type>(EventType##_StaticDeclarator::Name) {} \
+ EventType(const Arg0 &arg0, const Arg1 &arg1) : DPL::Event::EventMessages::Generic2<EventArg0Type, EventArg1Type>(EventType##_StaticDeclarator::Name, arg0, arg1) {} \
+ };
+
+#define EVENT_DELIVERY_DECLARE_EVENT_MESSAGE_3(EventType, EventArg0Type, EventArg1Type, EventArg2Type) \
+ void EventType##_Inject(const std::string &metaData); \
+ struct EventType##_StaticDeclarator \
+ { \
+ static char Name[0xFF]; \
+ EventType##_StaticDeclarator(); \
+ }; \
+ class EventType : public DPL::Event::EventMessages::Generic3<EventArg0Type, EventArg1Type, EventArg2Type> \
+ { \
+ public: \
+ EventType() : DPL::Event::EventMessages::Generic3<EventArg0Type, EventArg1Type, EventArg2Type>(EventType##_StaticDeclarator::Name) {} \
+ EventType(const Arg0 &arg0, const Arg1 &arg1, const Arg2 &arg2) : DPL::Event::EventMessages::Generic3<EventArg0Type, EventArg1Type, EventArg2Type>(EventType##_StaticDeclarator::Name, arg0, arg1, arg2) {} \
+ };
+
+#define EVENT_DELIVERY_DECLARE_EVENT_MESSAGE_4(EventType, EventArg0Type, EventArg1Type, EventArg2Type, EventArg3Type) \
+ void EventType##_Inject(const std::string &metaData); \
+ struct EventType##_StaticDeclarator \
+ { \
+ static char Name[0xFF]; \
+ EventType##_StaticDeclarator(); \
+ }; \
+ class EventType : public DPL::Event::EventMessages::Generic4<EventArg0Type, EventArg1Type, EventArg2Type, EventArg3Type> \
+ { \
+ public: \
+ EventType() : DPL::Event::EventMessages::Generic4<EventArg0Type, EventArg1Type, EventArg2Type, EventArg3Type>(EventType##_StaticDeclarator::Name) {} \
+ EventType(const Arg0 &arg0, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3) : DPL::Event::EventMessages::Generic4<EventArg0Type, EventArg1Type, EventArg2Type, EventArg3Type>(EventType##_StaticDeclarator::Name, arg0, arg1, arg2, arg3) {} \
+ };
+
+#define EVENT_DELIVERY_IMPLEMENT_EVENT_MESSAGE(EventType) \
+ char EventType##_StaticDeclarator::Name[0xFF] = {}; \
+ void EventType##_Inject(const std::string &metaData) \
+ { \
+ EventType newType; \
+ newType.DeserializeType(metaData); \
+ DPL::Event::EventDeliverySystemInjector::Instance().Publish(newType); \
+ } \
+ EventType##_StaticDeclarator::EventType##_StaticDeclarator() \
+ { \
+ strcpy(Name, #EventType); \
+ DPL::Event::EventDeliverySystemInjector::Instance().RegisterMetaCall(EventType##_StaticDeclarator::Name, EventType##_Inject); \
+ } \
+ namespace { EventType##_StaticDeclarator dummyInitializer_##EventType##_StaticDeclarator; }
+
+// BUILT-IN EVENTS
+class RoamingChanged
+{
+protected:
+ bool m_enabled; ///< Status whether roaming is enabled during call
+
+public:
+ /**
+ * Constructor
+ */
+ RoamingChanged()
+ : m_enabled(false)
+ {
+ }
+
+ /**
+ * Init constructor
+ */
+ RoamingChanged(bool enabled)
+ : m_enabled(enabled)
+ {
+ }
+
+ /**
+ * Destructor
+ */
+ virtual ~RoamingChanged()
+ {
+ }
+
+ /**
+ * Retrieve status whether roaming is enabled
+ *
+ * @return Current roaming status
+ */
+ bool GetEnabled() const
+ {
+ return m_enabled;
+ }
+};
+
+class NetworkTypeChanged
+{
+protected:
+ /**
+ * Status whether phone is working in:
+ * home network (true)
+ * roaming (false)
+ */
+ bool m_homeNetwork;
+
+public:
+ /**
+ * Constructor
+ */
+ NetworkTypeChanged()
+ : m_homeNetwork(true)
+ {
+ }
+
+ /**
+ * Init constructor
+ */
+ NetworkTypeChanged(bool homeNetwork)
+ : m_homeNetwork(homeNetwork)
+ {
+ }
+
+ /**
+ * Destructor
+ */
+ virtual ~NetworkTypeChanged()
+ {
+ }
+
+ /**
+ * Retrieve status whether home network is active
+ *
+ * @return Current network status
+ */
+ bool IsHomeNetwork() const
+ {
+ return m_homeNetwork;
+ }
+
+ /**
+ * Retrieve status whether home network is active
+ *
+ * @return Current network status
+ */
+ bool IsRoaming() const
+ {
+ return !m_homeNetwork;
+ }
+};
+
+class HibernationEnter
+{
+public:
+ /**
+ * Constructor
+ */
+ HibernationEnter()
+ {
+ }
+
+ /**
+ * Destructor
+ */
+ virtual ~HibernationEnter()
+ {
+ }
+};
+
+class HibernationLeave
+{
+public:
+ /**
+ * Constructor
+ */
+ HibernationLeave()
+ {
+ }
+
+ /**
+ * Destructor
+ */
+ virtual ~HibernationLeave()
+ {
+ }
+};
+
+} // namespace EventMessages
+}
+} // namespace DPL
+
+#endif // DPL_EVENT_DELIVERY_MESSAGES_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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/fast_delegate.h>
+#include <dpl/scoped_ptr.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>
+#include <vector>
+#include <map>
+#include <list>
+
+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 FastDelegate1<const EventType &> 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;
+
+ // Delegate list
+ typedef std::map<DelegateType, Thread *> 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()
+ {
+ LogPedantic("Reseting my EventSupport");
+
+ Mutex::ScopedLock lock(&m_dataMutex);
+ m_eventSupport = NULL;
+ }
+ };
+
+private:
+ GenericEventCallType *RegisterEventCall(const EventType &event,
+ EventListenerType *eventListener,
+ DelegateType delegate,
+ WaitableEvent *waitableEvent)
+ {
+ LogPedantic("Create and Register EventCall in EventSupport");
+
+ Mutex::ScopedLock lock(&m_eventListMutex);
+
+ EventSupportDataPtr supportData =
+ new EventSupportData(
+ this,
+ &EventSupportType::ReceiveAbstractEventCall,
+ waitableEvent);
+
+ GenericEventCallType *eventCall =
+ new GenericEventCallType(supportData, eventListener,
+ delegate, event);
+
+ typename EventCallList::iterator eventCallIter =
+ m_eventsList.insert(m_eventsList.end(), eventCall);
+
+ supportData->SetIterator(eventCallIter);
+
+ return eventCall;
+ }
+
+ void RemoveEventCall(typename EventCallList::iterator eventIterator)
+ {
+ Mutex::ScopedLock lock(&m_eventListMutex);
+
+ LogPedantic("Removing event call from EventSupport");
+
+ m_eventsList.erase(eventIterator);
+ }
+
+ // Note: Reentrant metod
+ void GuardedEventCall(const EventType &event,
+ EventListenerType *eventListener)
+ {
+ LogPedantic("Guarded event listener call...");
+
+ ++m_guardedCallInProgress;
+
+ UNHANDLED_EXCEPTION_HANDLER_BEGIN
+ {
+ eventListener->OnEventReceived(event);
+ }
+ UNHANDLED_EXCEPTION_HANDLER_END
+
+ --m_guardedCallInProgress;
+
+ LogPedantic("Guarded event listener finished");
+ }
+
+ // Note: Reentrant metod
+ void GuardedEventCall(const EventType &event,
+ DelegateType delegate)
+ {
+ LogPedantic("Guarded delegate call...");
+
+ ++m_guardedCallInProgress;
+
+ UNHANDLED_EXCEPTION_HANDLER_BEGIN
+ {
+ delegate(event);
+ }
+ UNHANDLED_EXCEPTION_HANDLER_END
+
+ --m_guardedCallInProgress;
+
+ LogPedantic("Guarded delegate call finished");
+ }
+
+ void ReceiveAbstractEventCall(const EventType &event,
+ EventListenerType *eventListener,
+ DelegateType delegate,
+ WaitableEvent *synchronization)
+ {
+ LogPedantic("Received abstract event call method");
+
+ Thread *targetThread;
+
+ // Listener might have been removed, ensure that it still exits
+ if (eventListener != NULL)
+ {
+ Mutex::ScopedLock lock(&m_listenerDelegateMutex);
+
+ typename EventListenerList::iterator iterator =
+ m_eventListenerList.find(eventListener);
+
+ if (iterator == m_eventListenerList.end())
+ {
+ LogPedantic("Abstract event call listener disappeared."
+ "Event ignored.");
+
+ // Even though, synchronize caller if needed
+ if (synchronization != NULL)
+ synchronization->Signal();
+
+ return;
+ }
+
+ // Get target thread id
+ targetThread = iterator->second;
+ }
+ else
+ {
+ // Delegate might have been removed, ensure that it still exits
+ Mutex::ScopedLock lock(&m_listenerDelegateMutex);
+
+ typename DelegateList::iterator iterator =
+ m_delegateList.find(delegate);
+
+ if (iterator == m_delegateList.end())
+ {
+ LogPedantic("Abstract event call delegate disappeared."
+ "Event ignored.");
+
+ // Even though, synchronize caller if needed
+ if (synchronization != NULL)
+ synchronization->Signal();
+
+ return;
+ }
+
+ // Get target thread id
+ targetThread = iterator->second;
+ }
+
+ // Ensure that we are now in proper thread now
+ if (targetThread != Thread::GetCurrentThread())
+ {
+ LogPedantic("Detected event dispatching ping-pong scenario");
+
+ // Retry if it was not synchronized
+ if (synchronization == NULL)
+ {
+ // Cheat with event delivery
+ EmitEvent(event, EmitMode::Queued);
+
+ LogPedantic("Ping-Pong: Resent as queued event");
+ }
+ else
+ {
+ // There is a problem
+ // Developer did something nasty, and we will not clean up his mess
+ synchronization->Signal();
+
+ LogPedantic("### Ping-Pong: Failed to deliver synchronized"
+ "event in ping-pong scenario!");
+ }
+
+ return;
+ }
+
+ // Guard listener code for exceptions
+ if (eventListener != NULL)
+ GuardedEventCall(event, eventListener);
+ else
+ GuardedEventCall(event, delegate);
+
+ // Release caller if synchronizing
+ if (synchronization != NULL)
+ synchronization->Signal();
+ }
+
+protected:
+ void EmitEvent(const EventType &event,
+ EmitMode::Type mode = EmitMode::Queued,
+ double dueTime = 0.0)
+ {
+ // Emit event, and retrieve later in current context to dispatch
+ ScopedPtr<Mutex::ScopedLock> lock(
+ new Mutex::ScopedLock(&m_listenerDelegateMutex));
+
+ // Show some info
+ switch (mode)
+ {
+ case EmitMode::Auto:
+ LogPedantic("Emitting AUTO event...");
+ break;
+
+ case EmitMode::Queued:
+ LogPedantic("Emitting QUEUED event...");
+ break;
+
+ case EmitMode::Blocking:
+ LogPedantic("Emitting BLOCKING event...");
+ break;
+
+ case EmitMode::Deffered:
+ LogPedantic("Emitting DEFFERED event...");
+ break;
+
+ default:
+ break;
+ }
+
+ // In some configurations there is a barrier
+ std::vector<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
+ LogPedantic("Sending event to main dispatcher");
+ dispatcher = &GetMainEventDispatcherInstance();
+ }
+ else
+ {
+ // Setup thread dispatcher, and send to proper thread
+ LogPedantic("Sending event to thread dispatcher");
+ m_threadEventDispatcher.SetThread(iterator->second);
+ dispatcher = &m_threadEventDispatcher;
+ }
+
+ // Dispatch event to abstract dispatcher
+ WaitableEvent *synchronization;
+
+ // TODO: Pool synchronization objects
+ switch (mode)
+ {
+ case EmitMode::Auto:
+ // Check thread
+ if (iterator->second == Thread::GetCurrentThread())
+ {
+ // Guard listener code for exceptions
+ GuardedEventCall(event, iterator->first);
+ }
+ else
+ {
+ // Handle non-synchronized event
+ dispatcher->AddEventCall(
+ RegisterEventCall(event, iterator->first,
+ DelegateType(), NULL));
+ }
+ break;
+
+ case EmitMode::Queued:
+ // Handle non-synchronized event
+ dispatcher->AddEventCall(
+ RegisterEventCall(event, iterator->first,
+ DelegateType(), NULL));
+
+ break;
+
+ case EmitMode::Blocking:
+ // Check thread
+ if (iterator->second == Thread::GetCurrentThread())
+ {
+ // Guard listener code for exceptions
+ GuardedEventCall(event, iterator->first);
+ }
+ else
+ {
+ // New synchronization object is needed
+ synchronization = new WaitableEvent();
+
+ // Handle synchronized event
+ dispatcher->AddEventCall(
+ RegisterEventCall(event, iterator->first,
+ DelegateType(), synchronization));
+
+ // Add to barrier
+ synchronizationBarrier.push_back(synchronization);
+ }
+ break;
+
+ case EmitMode::Deffered:
+ // Handle deffered events
+ Assert(dueTime >= 0.0 && "Due time must be non-negative");
+
+ dispatcher->AddTimedEventCall(
+ RegisterEventCall(event, iterator->first,
+ DelegateType(), NULL), dueTime);
+
+ break;
+
+ default:
+ Assert("Invalid emit mode");
+ }
+ }
+
+ LogPedantic("Added event to dispatchers");
+
+ // Emit to all delegates
+ FOREACH(iterator, m_delegateList)
+ {
+ // Switch to proper dispatcher and emit event
+ AbstractEventDispatcher *dispatcher = NULL;
+
+ if (iterator->second == NULL)
+ {
+ // Send to main thread
+ LogPedantic("Sending event to main dispatcher");
+ dispatcher = &GetMainEventDispatcherInstance();
+ }
+ else
+ {
+ // Setup thread dispatcher, and send to proper thread
+ LogPedantic("Sending event to thread dispatcher");
+ m_threadEventDispatcher.SetThread(iterator->second);
+ dispatcher = &m_threadEventDispatcher;
+ }
+
+ // Dispatch event to abstract dispatcher
+ WaitableEvent *synchronization;
+
+ // TODO: Pool synchronization objects
+ switch (mode)
+ {
+ case EmitMode::Auto:
+ // Check thread
+ if (iterator->second == Thread::GetCurrentThread())
+ {
+ // Guard listener code for exceptions
+ GuardedEventCall(event, iterator->first);
+ }
+ else
+ {
+ // Handle non-synchronized event
+ dispatcher->AddEventCall(
+ RegisterEventCall(event,
+ NULL,
+ iterator->first,
+ NULL));
+ }
+ break;
+
+ case EmitMode::Queued:
+ // Handle non-synchronized event
+ dispatcher->AddEventCall(
+ RegisterEventCall(event,
+ NULL,
+ iterator->first,
+ NULL));
+
+ break;
+
+ case EmitMode::Blocking:
+ // Check thread
+ if (iterator->second == Thread::GetCurrentThread())
+ {
+ // Guard listener code for exceptions
+ GuardedEventCall(event, iterator->first);
+ }
+ else
+ {
+ // New synchronization object is needed
+ synchronization = new WaitableEvent();
+
+ // Handle synchronized event
+ dispatcher->AddEventCall(
+ RegisterEventCall(event,
+ NULL,
+ iterator->first,
+ synchronization));
+
+ // Add to barrier
+ synchronizationBarrier.push_back(synchronization);
+ }
+ break;
+
+ case EmitMode::Deffered:
+ // Handle deffered events
+ Assert(dueTime >= 0.0 && "Due time must be non-negative");
+
+ dispatcher->AddTimedEventCall(
+ RegisterEventCall(event,
+ NULL,
+ iterator->first,
+ NULL), dueTime);
+
+ break;
+
+ default:
+ Assert("Invalid emit mode");
+ }
+ }
+
+ LogPedantic("Added event to dispatchers");
+
+ // Leave listeners lock in case of blocking call
+ if (!synchronizationBarrier.empty())
+ {
+ LogPedantic("Leaving lock due to existing barrier");
+ lock.Reset();
+ }
+
+ LogPedantic("Size of barrier: " << synchronizationBarrier.size());
+
+ // Synchronize with barrier
+ // TODO: Implement generic WaitForAllMultipleHandles call
+ while (!synchronizationBarrier.empty())
+ {
+ // Get barrier waitable handles
+ WaitableHandleList barrierHandles;
+
+ FOREACH(iterator, synchronizationBarrier)
+ barrierHandles.push_back((*iterator)->GetHandle());
+
+ // Await more events
+ WaitableHandleIndexList indexList =
+ WaitForMultipleHandles(barrierHandles);
+
+ // Remove all awaited handles
+ // TODO: Return handles to pool
+ FOREACH(iterator, indexList)
+ {
+ // Delete object
+ delete synchronizationBarrier[*iterator];
+
+ // Zero out place
+ synchronizationBarrier[*iterator] = NULL;
+ }
+
+ // Now clean up
+ std::vector<WaitableEvent *> clearedSynchronizationBarrier;
+
+ FOREACH(iterator, synchronizationBarrier)
+ {
+ if (*iterator == NULL)
+ continue;
+
+ clearedSynchronizationBarrier.push_back(*iterator);
+ }
+
+ synchronizationBarrier.swap(clearedSynchronizationBarrier);
+
+ LogPedantic("Reduced size of barrier: "
+ << synchronizationBarrier.size());
+ }
+
+ LogPedantic("Event emitted");
+ }
+
+public:
+ EventSupport()
+ : m_guardedCallInProgress(false)
+ {
+ }
+
+ virtual ~EventSupport()
+ {
+ Assert(m_guardedCallInProgress == false);
+
+ m_eventListenerList.clear();
+ m_delegateList.clear();
+
+ Mutex::ScopedLock lock(&m_eventListMutex);
+
+ LogPedantic("Disabling events for EventSupport");
+
+ FOREACH(iterator, m_eventsList)
+ (*iterator)->DisableEvent();
+ }
+
+ void AddListener(EventListenerType *eventListener)
+ {
+ Mutex::ScopedLock lock(&m_listenerDelegateMutex);
+
+ // Listener must not be NULL
+ Assert(eventListener != NULL);
+
+ // Listener must not already exists
+ Assert(m_eventListenerList.find(eventListener)
+ == m_eventListenerList.end());
+
+ // Add new listener, inherit dispatcher from current context
+ m_eventListenerList.insert(
+ std::make_pair(eventListener, Thread::GetCurrentThread()));
+
+ // Done
+ LogPedantic("Listener registered");
+ }
+
+ void AddListener(DelegateType delegate)
+ {
+ Mutex::ScopedLock lock(&m_listenerDelegateMutex);
+
+ // Delegate must not be empty
+ Assert(!delegate.empty());
+
+ // Delegate must not already exists
+ Assert(m_delegateList.find(delegate) == m_delegateList.end());
+
+ // Add new delegate, inherit dispatcher from current context
+ m_delegateList.insert(
+ std::make_pair(delegate, Thread::GetCurrentThread()));
+
+ // Done
+ LogPedantic("Delegate registered");
+ }
+
+ void RemoveListener(EventListenerType *eventListener)
+ {
+ Mutex::ScopedLock lock(&m_listenerDelegateMutex);
+
+ // Listener must not be NULL
+ Assert(eventListener != NULL);
+
+ // Listener must exist
+ typename EventListenerList::iterator iterator =
+ m_eventListenerList.find(eventListener);
+
+ Assert(iterator != m_eventListenerList.end());
+
+ // Remove listener from list
+ m_eventListenerList.erase(iterator);
+ LogPedantic("Listener unregistered");
+ }
+
+ void RemoveListener(DelegateType delegate)
+ {
+ Mutex::ScopedLock lock(&m_listenerDelegateMutex);
+
+ // Delegate must not be empty
+ Assert(!delegate.empty());
+
+ // Delegate must exist
+ typename DelegateList::iterator iterator =
+ m_delegateList.find(delegate);
+
+ Assert(iterator != m_delegateList.end());
+
+ // Remove delegate from list
+ m_delegateList.erase(iterator);
+ LogPedantic("Delegate unregistered");
+ }
+
+ void SwitchListenerToThread(EventListenerType *eventListener,
+ Thread *thread)
+ {
+ Mutex::ScopedLock lock(&m_listenerDelegateMutex);
+
+ // Listener must not be NULL
+ Assert(eventListener != NULL);
+
+ // Listener must exist
+ typename EventListenerList::iterator iterator =
+ m_eventListenerList.find(eventListener);
+
+ Assert(iterator != m_eventListenerList.end());
+
+ // Set listener thread
+ iterator->second = thread;
+
+ LogPedantic("Listener switched");
+ }
+
+ void SwitchListenerToThread(DelegateType delegate,
+ Thread *thread)
+ {
+ Mutex::ScopedLock lock(&m_listenerDelegateMutex);
+
+ // Delegate must not be empty
+ Assert(!delegate.empty());
+
+ // Delegate must exist
+ typename EventListenerList::iterator iterator =
+ m_delegateList.find(delegate);
+
+ Assert(iterator != m_delegateList.end());
+
+ // Set delegate thread
+ iterator->second = thread;
+
+ LogPedantic("Delegate switched");
+ }
+
+ void SwitchAllListenersToThread(Thread *thread)
+ {
+ Mutex::ScopedLock lock(&m_listenerDelegateMutex);
+
+ // Switch all listeners and delegates
+ FOREACH(iterator, m_eventListenerList)
+ iterator->second = thread;
+
+ FOREACH(iterator, m_delegateList)
+ iterator->second = thread;
+
+ LogPedantic("All listeners and delegates switched");
+ }
+};
+
+}
+} // namespace DPL
+
+#endif // DPL_EVENT_SUPPORT_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <dpl/event/abstract_event_call.h>
+#include <dpl/event/event_listener.h>
+#include <dpl/noncopyable.h>
+#include <dpl/fast_delegate.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 FastDelegate1<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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <dpl/event/event_support.h>
+#include <dpl/event/thread_event_dispatcher.h>
+#include <dpl/event/main_event_dispatcher.h>
+#include <dpl/fast_delegate.h>
+#include <dpl/shared_ptr.h>
+#include <dpl/enable_shared_from_this.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 <tuple>
+#include <list>
+
+/*
+ * - 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 DPL::SharedPtr<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
+
+// Better makeDelegate then DPL::MakeDelegate
+template<typename ThisType, typename ... ArgTypesList>
+FastDelegate<void (ArgTypesList ...)>
+makeDelegate(ThisType* This,
+ void (ThisType::*Func)(ArgTypesList ...))
+{
+ return FastDelegate<void (ArgTypesList ...)>(This, Func);
+}
+
+// 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,
+ DPL::FastDelegate<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(
+ DPL::StaticPointerCast<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(
+ DPL::StaticPointerCast<ICDPrivate::ICDSharedDataBase>(m_helper));
+ m_helper->disable();
+ }
+
+ protected:
+ ICDPrivate::ICDSharedDataBase::ICDSharedDataBasePtr
+ getRelatedICDSharedData() const
+ {
+ return DPL::StaticPointerCast<ICDPrivate::ICDSharedDataBase>(m_helper);
+ }
+
+ private:
+ template<typename ThisType>
+ friend class ICDelegateSupport;
+ class ICDSharedData;
+ typedef DPL::SharedPtr<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 DPL::FastDelegate<void (const PrivateEvent&)>
+ ICDSharedDataDelegateType;
+ class ICDSharedData : private DPL::Event::EventSupport<PrivateEvent>,
+ private DPL::EnableSharedFromThis<ICDSharedData>,
+ public ICDPrivate::ICDSharedDataBase
+ {
+ public:
+ ICDSharedData(
+ ICDPrivate::ICDelegateSupportInterface *base,
+ DPL::FastDelegate<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(
+ DPL::StaticPointerCast<ICDPrivate::ICDSharedDataBase>(
+ this->SharedFromThis()));
+ if (!isDisabled()) {
+ EmitEvent(PrivateEvent(this->SharedFromThis(),
+ args ...));
+ }
+ }
+
+ virtual void disable()
+ {
+ ICDPrivate::ICDSharedDataBase::ICDSharedDataBasePtr ptr(
+ DPL::StaticPointerCast<ICDSharedDataBase>(
+ this->SharedFromThis()));
+ ICDPrivate::ICDSharedDataBase::ScopedLock lock(ptr);
+ if (!isDisabled()) {
+ ICDPrivate::ICDSharedDataBase::disable();
+ EventSupport<PrivateEvent>::RemoveListener(m_subDelegate);
+ m_base->unregisterICDSharedData(ptr);
+ }
+ }
+
+ private:
+ friend class DPL::SharedPtr<ICDSharedData>;
+ ICDSharedDataDelegateType m_subDelegate;
+ ICDPrivate::ICDelegateSupportInterface* m_base;
+ DPL::FastDelegate<void (ArgTypesList ...)> m_outerDelegate;
+ ICD::Reuse m_reuse;
+
+ void delegateForwarder(const PrivateEvent& event)
+ {
+ ICDPrivate::ICDSharedDataBase::ICDSharedDataBasePtr ptr(
+ DPL::StaticPointerCast<ICDSharedDataBase>(event.helper));
+ ICDPrivate::ICDSharedDataBase::ScopedLock lock(ptr);
+
+ Assert(!m_outerDelegate.empty());
+ 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(
+ DPL::StaticPointerCast<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_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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);
+};
+
+MainEventDispatcher& GetMainEventDispatcherInstance();
+
+}
+} // namespace DPL
+
+#endif // DPL_MAIN_EVENT_DISPATCHER_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 the NestedLoopManager class.
+ *
+ * @file nested_loop.h
+ * @author Lukasz Marek (l.marek@samsung.com)
+ * @version 0.1
+ * @brief This file contains the declaration of the NestedLoopManager class.
+ */
+
+#ifndef DPL_NESTED_LOOP_H_
+#define DPL_NESTED_LOOP_H_
+
+#include <vector>
+#include <list>
+#include <map>
+#include <dpl/event/controller.h>
+#include <dpl/singleton.h>
+
+namespace DPL
+{
+namespace Event
+{
+
+class LoopExitEvent
+{
+};
+
+typedef unsigned LoopHandle;
+typedef std::list<LoopHandle> LoopHandleList;
+
+const LoopHandle UNDEFINED_LOOP_HANDLE = 0;
+
+class NestedLoopManager :
+ protected Controller<TypeListDecl<LoopExitEvent>::Type>
+{
+ public:
+ void* begin(LoopHandle loopHandle);
+ void exit(LoopHandle loopHandle,
+ void *userParam = NULL);
+ size_t getLevel() const;
+ LoopHandle getNewHandle();
+
+ protected:
+ void OnEventReceived(const LoopExitEvent& event);
+
+ private:
+ struct LoopInformation
+ {
+ LoopInformation(LoopHandle handle) :
+ loopHandle(handle),
+ exitFlag(false),
+ userParam(NULL)
+ {
+ }
+
+ LoopHandle loopHandle;
+ bool exitFlag;
+ void *userParam;
+ };
+
+ class RunningLoopsHandlePredicate
+ {
+ public:
+ RunningLoopsHandlePredicate(LoopHandle handle) :
+ m_handle(handle)
+ {
+ }
+
+ bool operator()(const LoopInformation &loopInformation) const
+ {
+ return loopInformation.loopHandle == m_handle;
+ }
+
+ private:
+ LoopHandle m_handle;
+ };
+
+ NestedLoopManager();
+ ~NestedLoopManager();
+
+ typedef std::vector<LoopInformation> RunningLoopsList;
+ typedef RunningLoopsList::iterator RunningLoopsListIterator;
+
+ bool m_eventGuard; // only one event is allowed
+ LoopHandle m_handle;
+ RunningLoopsList m_runningLoops;
+
+ friend class Singleton<NestedLoopManager>;
+};
+
+typedef Singleton<NestedLoopManager> NestedLoopManagerSingleton;
+
+}
+} // namespace DPL
+
+#endif // WRT_ENGINE_SRC_COMMON_NESTED_LOOP_H_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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/fast_delegate.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,
+ * DPL::MakeDelegate(this, &WriteCustomValue)
+ * {
+ * }
+ * };
+ *
+ * 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(
+ * DPL::MakeDelegate(&receiver, &Receiver::OnValueChanged));
+ * [...]
+ * model.RemoveListener(
+ * DPL::MakeDelegate(&receiver, &Receiver::OnValueChanged));
+ * }
+ */
+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.empty());
+ return this->m_readValue(m_model);
+ }
+
+ void Set(const Type &value)
+ {
+ Assert(!this->m_writeValue.empty());
+ 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.empty());
+ m_once.Call(Once::Delegate(this, &ThisType::OnceEnsure));
+ return this->m_value;
+ }
+
+ void Set(const Type &value)
+ {
+ Assert(!this->m_writeValue.empty());
+
+ this->m_writeValue(value, m_model);
+ this->m_value = value;
+ m_once.Call(Once::Delegate(this, &ThisType::OnceDisable));
+ }
+};
+
+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 FastDelegate<Type (Model *)>
+ ReadDelegateType;
+
+ typedef FastDelegate<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);
+
+ EmitEvent(PropertyEvent<Type>(value, this->m_model),
+ EmitMode::Auto);
+ }
+};
+
+}
+} // namespace DPL
+
+#endif // DPL_PROPERTY_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <dpl/event/abstract_event_call.h>
+
+namespace DPL
+{
+namespace Event
+{
+
+AbstractEventCall::AbstractEventCall()
+{
+}
+
+AbstractEventCall::~AbstractEventCall()
+{
+}
+
+}
+} // namespace DPL
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <dpl/event/abstract_event_dispatcher.h>
+
+namespace DPL
+{
+namespace Event
+{
+
+AbstractEventDispatcher::AbstractEventDispatcher()
+{
+}
+
+AbstractEventDispatcher::~AbstractEventDispatcher()
+{
+}
+
+}
+} // namespace DPL
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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.
+//
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_event_delivery.cpp
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of event delivery class
+ */
+#include <dpl/event/event_delivery.h>
+#include <dpl/main.h>
+
+namespace DPL
+{
+namespace Event
+{
+
+EventDeliverySystemDetail EventDeliverySystem::m_detailSystem;
+EventDeliverySystem::AbstractPublisherPtrContainerMapType EventDeliverySystem::m_publishers;
+
+namespace // anonymous
+{
+int InitializeMainSingleton();
+
+int g_dummyInitializer = InitializeMainSingleton();
+
+int InitializeMainSingleton()
+{
+ (void)g_dummyInitializer;
+ MainSingleton::Instance();
+ return 0;
+}
+} // namespace anonymous
+
+AbstractEventDeliverySystemPublisher::~AbstractEventDeliverySystemPublisher() { }
+
+}
+} // namespace DPL
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_event_delivery_detail.cpp
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of event delivery EFL detail class
+ */
+#include <dpl/event/event_delivery_detail.h>
+#include <dpl/event/event_delivery_injector.h>
+#include <dpl/framework_appcore.h>
+#include <dpl/framework_vconf.h>
+#include <dpl/scoped_array.h>
+#include <dpl/assert.h>
+#include <dpl/log/log.h>
+#include <heynoti.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <fstream>
+#include <string>
+#include <cstdio>
+
+namespace // anonymous
+{
+const char *GENERIC_NOTI_ROOT_PATH = "/tmp/noti/generic";
+} // namespace anonymous
+
+namespace DPL
+{
+namespace Event
+{
+
+const char *EventDeliverySystemDetail::NOTI_EVENT_ID_GENERIC_0 = "GenericEvent0_";
+const char *EventDeliverySystemDetail::NOTI_EVENT_ID_GENERIC_1 = "GenericEvent1_";
+const char *EventDeliverySystemDetail::NOTI_EVENT_ID_GENERIC_2 = "GenericEvent2_";
+const char *EventDeliverySystemDetail::NOTI_EVENT_ID_GENERIC_3 = "GenericEvent3_";
+const char *EventDeliverySystemDetail::NOTI_EVENT_ID_GENERIC_4 = "GenericEvent4_";
+
+// Global noti signal names
+const char *GlobalNotiHibernationEnterSignal = "HIBERNATION_ENTER";
+const char *GlobalNotiHibernationLeaveSignal = "HIBERNATION_LEAVE";
+
+EventDeliverySystemDetail::EventDeliverySystemDetail()
+{
+ // Open noti subsystem
+ LogInfo("Initializing core_util_noti subsystem...");
+
+ m_notiHandle = heynoti_init();
+ Assert(m_notiHandle != -1);
+
+ // Assume that there is ECORE environment running, attach noti library to it
+ LogPedantic("Attaching core_util_noti subsystem to ECORE...");
+
+ int ret = heynoti_attach_handler(m_notiHandle);
+ Assert(ret != -1);
+
+ (void)ret;
+
+ LogInfo("core_util_noti subsystem successfuly initialized.");
+}
+
+EventDeliverySystemDetail::~EventDeliverySystemDetail()
+{
+ // All signal handlers should be deattached
+ Assert(m_notiSignalList.empty());
+ Assert(m_settingSignalList.empty());
+ Assert(m_globalNotiSignalList.empty());
+
+ // Detach noti library from ECORE environment
+ LogPedantic("Detaching core_util_noti subsystem from ECORE...");
+
+ int ret = heynoti_detach_handler(m_notiHandle);
+ Assert(ret != -1);
+
+ (void)ret;
+
+ // Close noti sybsystem
+ LogInfo("Deinitializing core_util_noti subsystem...");
+
+ Assert(m_notiHandle != -1);
+ heynoti_close(m_notiHandle);
+
+ LogInfo("core_util_noti subsystem successfuly deinitialized.");
+}
+
+std::string EventDeliverySystemDetail::ReadFile(const std::string &fileName) const
+{
+ LogPedantic("Reading event file: " << fileName << "...");
+
+ std::ifstream fileStream(fileName.c_str(), std::ios::binary);
+
+ if (fileStream.fail())
+ return std::string("");
+
+ fileStream.seekg (0, std::ios::end);
+ std::streamoff length = fileStream.tellg();
+ fileStream.seekg (0, std::ios::beg);
+
+ ScopedArray<char> buffer(new char[length]);
+ fileStream.read(buffer.Get(), static_cast<size_t>(length));
+
+ if (fileStream.fail())
+ return std::string();
+
+ LogPedantic("Successfuly read: " << fileName << ".");
+
+ return std::string(buffer.Get(), buffer.Get() + length);
+}
+
+void EventDeliverySystemDetail::OnNotiGlobalSignal(void *notiData)
+{
+ Assert(notiData);
+ NotiSignal *notiSignal = static_cast<NotiSignal *>(notiData);
+ notiSignal->GetReceiver()->OnNotiSignal(notiSignal);
+}
+
+void EventDeliverySystemDetail::OnSettingSignal(keynode_t *keyNode, void *userParam)
+{
+ SettingSignal *settingSignal = static_cast<SettingSignal *>(userParam);
+ (void)settingSignal;
+
+ LogPedantic("Got setting signal for key: " << settingSignal->GetKey());
+
+ std::string key = vconf_keynode_get_name(keyNode);
+
+ if (key == VCONFKEY_SETAPPL_STATE_DATA_ROAMING_BOOL)
+ {
+ int value = vconf_keynode_get_bool(keyNode);
+ EventMessages::RoamingChanged message(value > 0);
+ EventDeliverySystemInjector::Instance().Publish(message);
+ }
+ else if (key == VCONFKEY_TELEPHONY_SVC_ROAM)
+ {
+ int result = 0;
+ if(vconf_get_int(VCONFKEY_TELEPHONY_SVC_ROAM, &result) != 0)
+ {
+ LogPedantic("Cannot get current roaming status");
+ return;
+ }
+ else
+ {
+ bool homeNetwork = (result != VCONFKEY_TELEPHONY_SVC_ROAM_ON);
+ EventMessages::NetworkTypeChanged message1(homeNetwork);
+ EventDeliverySystemInjector::Instance().Publish(message1);
+ }
+ }
+ else
+ {
+ LogPedantic("Unexpected setting signal key: " << key << "!");
+ return;
+ }
+}
+
+void EventDeliverySystemDetail::OnGlobalNotiSignal(void *globalNotiData)
+{
+ GlobalNotiSignal *globalNotiSignal = static_cast<GlobalNotiSignal *>(globalNotiData);
+
+ LogPedantic("Got global noti signal for key: " << globalNotiSignal->GetKey());
+
+ std::string key = globalNotiSignal->GetKey();
+
+ if (key == GlobalNotiHibernationEnterSignal)
+ {
+ // We need to disconnect from VCONF
+ for (SettingSignalList::iterator iterator = globalNotiSignal->GetReceiver()->m_settingSignalList.begin();
+ iterator != globalNotiSignal->GetReceiver()->m_settingSignalList.end(); ++iterator)
+ {
+ // Unegister from VCONF signals
+ int ret = vconf_ignore_key_changed(iterator->GetKey().c_str(), OnSettingSignal);
+
+ if (ret == -1)
+ LogPedantic("Failed to unlisten setting: " << key << ", errno = " << errno << ".");
+ }
+
+ // Publish
+ EventMessages::HibernationEnter message;
+ EventDeliverySystemInjector::Instance().Publish(message);
+ }
+ else if (key == GlobalNotiHibernationLeaveSignal)
+ {
+ // We need to reconnect to VCONF
+ for (SettingSignalList::iterator iterator = globalNotiSignal->GetReceiver()->m_settingSignalList.begin();
+ iterator != globalNotiSignal->GetReceiver()->m_settingSignalList.end(); ++iterator)
+ {
+ // Register for VCONF signals
+ int ret = vconf_notify_key_changed(iterator->GetKey().c_str(), OnSettingSignal, &*iterator);
+
+ if (ret == -1)
+ LogPedantic("Failed to listen setting: key = " << key << ", errno = " << errno << ".");
+ }
+
+ // Publish
+ EventMessages::HibernationLeave message;
+ EventDeliverySystemInjector::Instance().Publish(message);
+ }
+ else
+ {
+ LogPedantic("Unexpected global noti signal key: " << key << "!");
+ return;
+ }
+}
+
+void EventDeliverySystemDetail::OnNotiSignal(NotiSignal *notiSignal)
+{
+ LogPedantic("Got core_util_noti signal.");
+
+ if (notiSignal->GetEventName().substr(0, strlen(NOTI_EVENT_ID_GENERIC_0)) == NOTI_EVENT_ID_GENERIC_0)
+ {
+ LogPedantic("GeneticEvent0 message signal.");
+
+ EventDeliverySystemInjector::Instance().PublishMetaType(notiSignal->GetGcid(), ReadFile(GetGenericNotiFilePath(notiSignal->GetEventName())));
+ }
+ else if (notiSignal->GetEventName().substr(0, strlen(NOTI_EVENT_ID_GENERIC_1)) == NOTI_EVENT_ID_GENERIC_1)
+ {
+ LogPedantic("GeneticEvent1 message signal.");
+
+ EventDeliverySystemInjector::Instance().PublishMetaType(notiSignal->GetGcid(), ReadFile(GetGenericNotiFilePath(notiSignal->GetEventName())));
+ }
+ else if (notiSignal->GetEventName().substr(0, strlen(NOTI_EVENT_ID_GENERIC_2)) == NOTI_EVENT_ID_GENERIC_2)
+ {
+ LogPedantic("GeneticEvent2 message signal.");
+
+ EventDeliverySystemInjector::Instance().PublishMetaType(notiSignal->GetGcid(), ReadFile(GetGenericNotiFilePath(notiSignal->GetEventName())));
+ }
+ else if (notiSignal->GetEventName().substr(0, strlen(NOTI_EVENT_ID_GENERIC_3)) == NOTI_EVENT_ID_GENERIC_3)
+ {
+ LogPedantic("GeneticEvent3 message signal.");
+
+ EventDeliverySystemInjector::Instance().PublishMetaType(notiSignal->GetGcid(), ReadFile(GetGenericNotiFilePath(notiSignal->GetEventName())));
+ }
+ else if (notiSignal->GetEventName().substr(0, strlen(NOTI_EVENT_ID_GENERIC_4)) == NOTI_EVENT_ID_GENERIC_4)
+ {
+ LogPedantic("GeneticEvent4 message signal.");
+
+ EventDeliverySystemInjector::Instance().PublishMetaType(notiSignal->GetGcid(), ReadFile(GetGenericNotiFilePath(notiSignal->GetEventName())));
+ }
+}
+
+void EventDeliverySystemDetail::RegisterFileNotiCallback(const char *gcid, const std::string &eventName)
+{
+ LogPedantic("Registering core_util_noti callback: gcid = " << (gcid ? gcid : "<NULL>") << ", eventName = " << eventName << ".");
+ Assert(m_notiHandle != -1);
+
+ // Check if already registered for signal
+ NotiSignalList::const_iterator iterator;
+
+ for (iterator = m_notiSignalList.begin(); iterator != m_notiSignalList.end(); ++iterator)
+ {
+ if (iterator->GetEventName() == eventName)
+ return;
+ }
+
+ // Make real noti path
+ std::string filePath = GetGenericNotiFilePath(eventName);
+
+ LogPedantic("Listening file: " << filePath << ".");
+
+ // New noti signal
+ m_notiSignalList.push_back(NotiSignal(this, gcid, eventName));
+ NotiSignal *notiSignal = &m_notiSignalList.back();
+
+ // Register for noti signals
+ int ret = heynoti_subscribe_file(m_notiHandle, filePath.c_str(), OnNotiGlobalSignal, notiSignal, IN_CLOSE_WRITE);
+
+ if (ret == -1)
+ {
+ LogPedantic("Failed to listen file: " << filePath << ".");
+ return;
+ }
+
+ LogPedantic("Successfuly registered listening file: " << filePath << ".");
+}
+
+void EventDeliverySystemDetail::UnregisterFileNotiCallback(const std::string &eventName)
+{
+ LogPedantic("Unegistering core_util_noti callback: eventName = " << eventName << ".");
+
+ Assert(m_notiHandle != -1);
+
+ NotiSignalList::iterator iterator;
+
+ for (iterator = m_notiSignalList.begin(); iterator != m_notiSignalList.end(); ++iterator)
+ {
+ if (iterator->GetEventName() == eventName)
+ break;
+ }
+
+ if (iterator == m_notiSignalList.end())
+ return;
+
+ // Remove registered slot
+ m_notiSignalList.erase(iterator);
+
+ // Make real noti path
+ std::string filePath = GetGenericNotiFilePath(eventName);
+
+ LogPedantic("Unlistening file: " << filePath << ".");
+
+ // Register for noti signals
+ int ret = heynoti_unsubscribe_file(m_notiHandle, filePath.c_str(), OnNotiGlobalSignal);
+
+ if (ret == -1)
+ {
+ LogPedantic("Failed to unlisten file: " << filePath << ".");
+ return;
+ }
+}
+
+void EventDeliverySystemDetail::RegisterSettingCallback(const std::string &key)
+{
+ LogPedantic("Registering setting: key = " << key << ".");
+
+ // Check if already registered for signal
+ SettingSignalList::const_iterator iterator;
+
+ for (iterator = m_settingSignalList.begin(); iterator != m_settingSignalList.end(); ++iterator)
+ {
+ if (iterator->GetKey() == key)
+ return;
+ }
+
+ // New noti signal
+ m_settingSignalList.push_back(SettingSignal(this, key));
+ SettingSignal *settingSignal = &m_settingSignalList.back();
+
+ // Register for setting signals
+ int ret = vconf_notify_key_changed(key.c_str(), OnSettingSignal, settingSignal);
+
+ if (ret == -1)
+ {
+ LogPedantic("Failed to listen setting: key = " << key << ", errno = " << errno << ".");
+ return;
+ }
+
+ LogPedantic("Successfuly registered setting: key = " << key << ".");
+}
+
+void EventDeliverySystemDetail::UnregisterSettingCallback(const std::string &key)
+{
+ LogPedantic("Unegistering setting: key = " << key << ".");
+
+ SettingSignalList::iterator iterator;
+
+ for (iterator = m_settingSignalList.begin(); iterator != m_settingSignalList.end(); ++iterator)
+ {
+ if (iterator->GetKey() == key)
+ break;
+ }
+
+ if (iterator == m_settingSignalList.end())
+ return;
+
+ // Remove registered slot
+ m_settingSignalList.erase(iterator);
+
+ // Register for noti signals
+ int ret = vconf_ignore_key_changed(key.c_str(), OnSettingSignal);
+
+ if (ret == -1)
+ {
+ LogPedantic("Failed to unlisten setting: " << key << ", errno = " << errno << ".");
+ return;
+ }
+}
+
+void EventDeliverySystemDetail::RegisterGlobalNotiCallback(const std::string &key)
+{
+ LogPedantic("Registering global noti: key = " << key << ".");
+
+ // Check if already registered for signal
+ GlobalNotiSignalList::const_iterator iterator;
+
+ for (iterator = m_globalNotiSignalList.begin(); iterator != m_globalNotiSignalList.end(); ++iterator)
+ {
+ if (iterator->GetKey() == key)
+ return;
+ }
+
+ // New noti signal
+ m_globalNotiSignalList.push_back(GlobalNotiSignal(this, key));
+ GlobalNotiSignal *globalNotiSignal = &m_globalNotiSignalList.back();
+
+ // Register for global noti signals
+ int ret = heynoti_subscribe(m_notiHandle, key.c_str(), OnGlobalNotiSignal, globalNotiSignal);
+
+ if (ret == -1)
+ {
+ LogPedantic("Failed to listen global noti: key = " << key << ", errno = " << errno << ".");
+ return;
+ }
+
+ LogPedantic("Successfuly registered global noti: key = " << key << ".");
+}
+
+void EventDeliverySystemDetail::UnregisterGlobalNotiCallback(const std::string &key)
+{
+ LogPedantic("Unegistering global noti: key = " << key << ".");
+
+ GlobalNotiSignalList::iterator iterator;
+
+ for (iterator = m_globalNotiSignalList.begin(); iterator != m_globalNotiSignalList.end(); ++iterator)
+ {
+ if (iterator->GetKey() == key)
+ break;
+ }
+
+ if (iterator == m_globalNotiSignalList.end())
+ return;
+
+ // Remove registered slot
+ m_globalNotiSignalList.erase(iterator);
+
+ // Register for noti signals
+ int ret = heynoti_unsubscribe(m_notiHandle, key.c_str(), OnGlobalNotiSignal);
+
+ if (ret == -1)
+ {
+ LogPedantic("Failed to unlisten global noti: " << key << ", errno = " << errno << ".");
+ return;
+ }
+}
+
+void EventDeliverySystemDetail::SignalGenericNoti(const std::string &eventName, const std::string &contents) const
+{
+ LogPedantic("Signaling core_util_noti with: eventName = " << eventName << ", buffer = " << contents << ".");
+
+ Assert(m_notiHandle != -1);
+
+ // Make real noto path
+ std::string filePath = GetGenericNotiFilePath(eventName);
+
+ LogPedantic("Signaling file: " << filePath << ".");
+
+ // Emit noti signal with user data
+ int fd = open(filePath.c_str(), O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR);
+
+ if (fd == -1)
+ {
+ LogPedantic("Failed to signal file: " << filePath << ".");
+ return;
+ }
+
+ // Write contents of signal to file
+ std::string::size_type written = 0;
+
+ while (written < contents.size())
+ {
+ int done = TEMP_FAILURE_RETRY(write(fd, static_cast<const void *>(&contents[written]), contents.size() - written));
+
+ if (done <= 0)
+ {
+ LogPedantic("File stream broken: " << filePath << ".");
+ break;
+ }
+
+ written += done;
+ }
+
+ // Close signal file
+ int ret = close(fd);
+
+ if (ret == -1)
+ {
+ LogPedantic("Failed to close signal file: " << filePath << ".");
+ return;
+ }
+}
+
+std::string EventDeliverySystemDetail::GetGenericNotiFilePath(const std::string &eventName) const
+{
+ // Make sure that the path exists
+ if (access(GENERIC_NOTI_ROOT_PATH, F_OK) == -1)
+ {
+ LogPedantic("No root path found. Creating root path...");
+
+ // Create path
+ if (mkdir(GENERIC_NOTI_ROOT_PATH, 0755) == -1)
+ {
+ LogPedantic("Failed to create root path!");
+ return std::string("~") + eventName;
+ }
+
+ LogPedantic("Root path created.");
+ }
+
+ return std::string(GENERIC_NOTI_ROOT_PATH) + "/" + eventName;
+}
+
+void EventDeliverySystemDetail::Listen(const EventMessages::RoamingChanged &event)
+{
+ LogPedantic("RoamingChanged message listen.");
+
+ (void)event;
+ RegisterSettingCallback(VCONFKEY_SETAPPL_STATE_DATA_ROAMING_BOOL);
+}
+
+void EventDeliverySystemDetail::Listen(const EventMessages::NetworkTypeChanged &event)
+{
+ LogPedantic("NetworkTypeChanged message listen.");
+
+ (void)event;
+ RegisterSettingCallback(VCONFKEY_TELEPHONY_SVC_ROAM);
+}
+
+void EventDeliverySystemDetail::Listen(const EventMessages::HibernationEnter &event)
+{
+ LogPedantic("HibernationEnter message listen.");
+
+ (void)event;
+ RegisterGlobalNotiCallback(GlobalNotiHibernationEnterSignal);
+}
+
+void EventDeliverySystemDetail::Listen(const EventMessages::HibernationLeave &event)
+{
+ LogPedantic("HibernationLeave message listen.");
+
+ (void)event;
+ RegisterGlobalNotiCallback(GlobalNotiHibernationLeaveSignal);
+}
+
+void EventDeliverySystemDetail::Unlisten(const EventMessages::RoamingChanged &event)
+{
+ LogPedantic("RoamingChanged message unlisten.");
+
+ (void)event;
+ UnregisterSettingCallback(VCONFKEY_SETAPPL_STATE_DATA_ROAMING_BOOL);
+}
+
+void EventDeliverySystemDetail::Unlisten(const EventMessages::NetworkTypeChanged &event)
+{
+ LogPedantic("NetworkTypeChanged message unlisten.");
+
+ (void)event;
+ UnregisterSettingCallback(VCONFKEY_TELEPHONY_SVC_ROAM);
+}
+
+void EventDeliverySystemDetail::Unlisten(const EventMessages::HibernationEnter &event)
+{
+ LogPedantic("HibernationEnter message unlisten.");
+
+ (void)event;
+ UnregisterGlobalNotiCallback(GlobalNotiHibernationEnterSignal);
+}
+
+void EventDeliverySystemDetail::Unlisten(const EventMessages::HibernationLeave &event)
+{
+ LogPedantic("HibernationLeave message unlisten.");
+
+ (void)event;
+ UnregisterGlobalNotiCallback(GlobalNotiHibernationLeaveSignal);
+}
+
+}
+} // namespace DPL
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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.
+//
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <dpl/event/event_support.h>
+
+namespace DPL
+{
+namespace Event
+{
+
+namespace // anonymous
+{
+int dummyInitializerProc()
+{
+ GetMainEventDispatcherInstance();
+ return 0;
+}
+
+int g_dummyInitializer = dummyInitializerProc();
+
+} // namespace anonymous
+
+}
+} // namespace DPL
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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.
+//
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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.
+//
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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!");
+
+ // 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 event class handler
+ ecore_event_handler_del(m_eventCallHandler);
+ m_eventCallHandler = NULL;
+
+ // Remove cross event handler
+ ecore_main_fd_handler_del(m_crossEventCallHandler);
+ m_crossEventCallHandler = NULL;
+
+ LogPedantic("ECORE cross-event handler unregistered");
+
+ // 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::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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <dpl/event/model.h>
+
+namespace DPL
+{
+namespace Event
+{
+Model::~Model()
+{
+}
+}
+} // namespace DPL
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 the NestedLoopManager class.
+ *
+ * @file nested_loop.cpp
+ * @author Lukasz Marek (l.marek@samsung.com)
+ * @version 0.1
+ * @brief This file contains the definition of the NestedLoopManager class.
+ */
+
+#include <dpl/event/nested_loop.h>
+#include <algorithm>
+#include <Ecore.h>
+#include <dpl/log/log.h>
+#include <dpl/assert.h>
+#include <dpl/singleton_impl.h>
+
+IMPLEMENT_SINGLETON(DPL::Event::NestedLoopManager)
+
+namespace DPL
+{
+namespace Event
+{
+
+NestedLoopManager::NestedLoopManager() : m_eventGuard(false),
+ m_handle(0)
+{
+ Touch();
+}
+
+NestedLoopManager::~NestedLoopManager()
+{
+}
+
+void* NestedLoopManager::begin(LoopHandle loopHandle)
+{
+ LoopInformation info(loopHandle);
+ m_runningLoops.push_back(info);
+ LogPedantic("Nested loop begin. Nested loop level: " << getLevel());
+
+ ecore_main_loop_begin();
+
+ Assert(m_runningLoops.size() && "No loop on the stack");
+
+ info = m_runningLoops.back();
+ m_runningLoops.pop_back();
+
+ Assert(info.loopHandle == loopHandle && "You exit from wrong loop");
+ Assert(info.exitFlag == true && "Exit flag not set");
+
+ LogPedantic("Nested loop quit. Nested loop level: " << getLevel());
+
+ if (!m_runningLoops.empty() && m_runningLoops.back().exitFlag &&
+ !m_eventGuard) {
+ m_eventGuard = true;
+ LoopExitEvent event;
+ PostEvent(event);
+ }
+ return info.userParam;
+}
+
+void NestedLoopManager::exit(LoopHandle loopHandle,
+ void *userParam)
+{
+ RunningLoopsListIterator iterator = std::find_if(
+ m_runningLoops.begin(),
+ m_runningLoops.end(),
+ RunningLoopsHandlePredicate(loopHandle));
+
+ Assert(iterator != m_runningLoops.end() && "Unknown loopHandle");
+ Assert(iterator->exitFlag == false && "You cannot close a loop twice.");
+
+ iterator->exitFlag = true;
+ iterator->userParam = userParam;
+
+ if (m_runningLoops.back().exitFlag && !m_eventGuard) {
+ m_eventGuard = true;
+ LoopExitEvent event;
+ PostEvent(event);
+ }
+}
+
+size_t NestedLoopManager::getLevel() const
+{
+ return m_runningLoops.size();
+}
+
+LoopHandle NestedLoopManager::getNewHandle()
+{
+ return m_handle++;
+}
+
+void NestedLoopManager::OnEventReceived(const LoopExitEvent& event)
+{
+ (void)event;
+ Assert(!m_runningLoops.empty());
+ m_eventGuard = false; // no event in queue
+ if (m_runningLoops.back().exitFlag) {
+ //exit loop when last started one is readu to finish
+ //this will post event if next loop is ready to exit
+ ecore_main_loop_quit();
+ }
+}
+
+}
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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/localization_utils.cpp
+ ${PROJECT_SOURCE_DIR}/modules/localization/src/w3c_file_localization.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
+ PARENT_SCOPE
+)
+
+SET(DPL_LOCALIZATION_INCLUDE_DIR
+ ${PROJECT_SOURCE_DIR}/modules/localization/include
+ PARENT_SCOPE
+)
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 std::list<DPL::String> LanguageTagsList;
+typedef DPL::Optional<WidgetStartFileInfo> OptionalWidgetStartFileInfo;
+
+namespace LocalizationUtils {
+DPL::String BCP47LanguageTagToLocale(const DPL::String&);
+DPL::String LocaleToBCP47LanguageTag(const DPL::String&);
+
+void SetUserLanguageTags(const LanguageTagsList& tags);
+void SetSystemLanguageTags(const LanguageTagsList& tags);
+LanguageTagsList GetUserAgentLanguageTags();
+
+void Initialize();
+}
+
+#endif //LOCALIZATION_UTILS_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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-rw/widget_dao.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(
+ WrtDB::DbWidgetHandle widgetHandle,
+ const LanguageTagsList &languageTags,
+ const DPL::String &url);
+
+DPL::Optional<DPL::String> getFilePathInWidgetPackage(
+ WrtDB::DbWidgetHandle widgetHandle,
+ const LanguageTagsList &languageTags,
+ const DPL::String& file);
+
+DPL::OptionalString getStartFile(WrtDB::DbWidgetHandle widgetHandle);
+OptionalWidgetIcon getIcon(WrtDB::DbWidgetHandle widgetHandle);
+WidgetIconList getValidIconsList(
+ WrtDB::DbWidgetHandle widgetHandle,
+ const LanguageTagsList &languageTags);
+
+OptionalWidgetStartFileInfo getStartFileInfo(
+ WrtDB::DbWidgetHandle widgetHandle,
+ const LanguageTagsList &tagsList);
+WrtDB::WidgetLocalizedInfo getLocalizedInfo(WrtDB::DbWidgetHandle widgetHandle);
+}
+
+#endif //W3C_FILE_LOCALIZATION_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.cpp
+ * @author Bartosz Janiak (b.janiak@samsung.com)
+ * @version 1.0
+ */
+
+#include <dpl/localization/localization_utils.h>
+
+#include <appcore-efl.h>
+#include <vconf.h>
+#include <dpl/framework_efl.h>
+
+#include <dpl/foreach.h>
+#include <dpl/mutex.h>
+#include <dpl/wrt-dao-rw/widget_dao.h>
+
+namespace {
+
+static int LanguageChanged(void *)
+{
+ char* lang = vconf_get_str(VCONFKEY_LANGSET);
+ if (!lang) {
+ LogError("Cannot get locale settings from vconf");
+ return 0;
+ }
+ LogDebug("Language set to: " << lang);
+
+ using namespace LocalizationUtils;
+
+ LanguageTagsList list;
+ list.push_back(DPL::FromUTF8String(lang));
+ SetSystemLanguageTags(list);
+
+ LogDebug("LanguageChanged to " << lang);
+
+ return 0;
+}
+}
+
+namespace LocalizationUtils {
+static LanguageTagsList m_systemLanguageTags;
+static LanguageTagsList m_userLanguageTags;
+static LanguageTagsList m_languageTags;
+static DPL::ReadWriteMutex m_readWriteMutex;
+
+template<typename StringType>
+void FindAndReplace(StringType& source,
+ const StringType& find,
+ const StringType& replace)
+{
+ size_t pos = 0;
+ while ((pos = source.find(find, pos)) != StringType::npos) {
+ source.replace(pos, find.length(), replace);
+ pos += replace.length();
+ }
+}
+
+DPL::String BCP47LanguageTagToLocale(const DPL::String& inLanguageTag)
+{
+ DPL::String languageTag(inLanguageTag);
+ FindAndReplace(languageTag, DPL::String(L"-"), DPL::String(L"_"));
+ return languageTag;
+}
+
+DPL::String LocaleToBCP47LanguageTag(const DPL::String& inLocaleString)
+{
+ DPL::String localeString = inLocaleString.substr(
+ 0,
+ inLocaleString.
+ find_first_of(L"."));
+ FindAndReplace(localeString, DPL::String(L"_"), DPL::String(L"-"));
+ return localeString;
+}
+
+void UpdateUserAgentLanguageTags()
+{
+ // WARNING!!!!! This function shall be called
+ // only when mutex is locked in readWriteMode!
+
+ LanguageTagsList list = m_userLanguageTags;
+ list.insert(list.begin(),
+ m_systemLanguageTags.begin(),
+ m_systemLanguageTags.end());
+ m_languageTags.clear();
+
+ FOREACH(i, list) {
+ DPL::String tag = LocaleToBCP47LanguageTag(*i);
+ while (true) { //W3C Packaging 9. Step 5. 2. D
+ if (tag.empty()) { continue; }
+
+ LogDebug("Adding user locale '" << tag << "'");
+ m_languageTags.push_back(tag);
+
+ size_t subtagPos = tag.find_last_of(L"-");
+ if (subtagPos == DPL::String::npos) {
+ break;
+ }
+ tag = tag.substr(0, subtagPos);
+ }
+ }
+
+ m_languageTags.push_back(L"en");
+ m_languageTags.push_back(L"");
+}
+
+void SetUserLanguageTags(const LanguageTagsList& tags)
+{
+ DPL::ReadWriteMutex::ScopedWriteLock lock(&m_readWriteMutex);
+ if (m_userLanguageTags != tags) {
+ m_userLanguageTags = tags;
+ UpdateUserAgentLanguageTags();
+ }
+}
+
+void SetSystemLanguageTags(const LanguageTagsList& tags)
+{
+ DPL::ReadWriteMutex::ScopedWriteLock lock(&m_readWriteMutex);
+ if (m_systemLanguageTags != tags) {
+ m_systemLanguageTags = tags;
+ UpdateUserAgentLanguageTags();
+ }
+}
+
+LanguageTagsList GetUserAgentLanguageTags()
+{
+ DPL::ReadWriteMutex::ScopedReadLock lock(&m_readWriteMutex);
+ return m_languageTags;
+}
+
+void Initialize()
+{
+ appcore_set_event_callback(
+ APPCORE_EVENT_LANG_CHANGE,
+ &LanguageChanged,
+ NULL);
+
+ LanguageChanged(NULL); // updating language for the first time
+}
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <dpl/localization/w3c_file_localization.h>
+
+#include <dpl/wrt-dao-rw/widget_dao.h>
+#include <dpl/localization/localization_utils.h>
+
+#include <dpl/log/log.h>
+#include <dpl/string.h>
+#include <dpl/optional.h>
+#include <dpl/foreach.h>
+
+using namespace WrtDB;
+
+namespace {
+const DPL::String FILE_URI_BEGIN = L"file://";
+const DPL::String WIDGET_URI_BEGIN = L"widget://";
+
+DPL::Optional<std::string> GetFilePathInWidgetPackageInternal(
+ const LanguageTagsList &tags,
+ const std::string& basePath,
+ std::string filePath)
+{
+ LogDebug("Looking for file: " << filePath << " in: " << basePath);
+ using namespace LocalizationUtils;
+
+ //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); }
+ //Check if string isn't empty
+ if (filePath.size() == 0) { return DPL::Optional<std::string>::Null; }
+
+ LogDebug("locales size = " << tags.size());
+ for (LanguageTagsList::const_iterator it = tags.begin();
+ it != tags.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 LanguageTagsList &languageTags,
+ const DPL::String& basePath,
+ const DPL::String& filePath)
+{
+ DPL::Optional<std::string> path =
+ GetFilePathInWidgetPackageInternal(languageTags,
+ DPL::ToUTF8String(basePath),
+ DPL::ToUTF8String(filePath));
+ DPL::Optional<DPL::String> dplPath;
+ if (!!path) {
+ dplPath = DPL::FromUTF8String(*path);
+ }
+ return dplPath;
+}
+}
+
+namespace W3CFileLocalization {
+DPL::Optional<DPL::String> getFilePathInWidgetPackageFromUrl(
+ DbWidgetHandle widgetHandle,
+ const LanguageTagsList &languageTags,
+ const DPL::String &url)
+{
+ DPL::String req = url;
+ WidgetDAO dao(widgetHandle);
+
+ 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());
+ }
+ } else {
+ LogDebug("Unknown path format, ignoring");
+ return DPL::Optional<DPL::String>::Null;
+ }
+
+ auto widgetPath = dao.getPath();
+
+ DPL::Optional<DPL::String> found =
+ GetFilePathInWidgetPackageInternal(languageTags, widgetPath, req);
+
+ if (!found) {
+ LogError("Path not found within current locale in current widget");
+ return DPL::Optional<DPL::String>::Null;
+ }
+
+ found = widgetPath + *found;
+
+ return found;
+}
+
+DPL::Optional<DPL::String> getFilePathInWidgetPackage(
+ WrtDB::DbWidgetHandle widgetHandle,
+ const LanguageTagsList &languageTags,
+ const DPL::String& file)
+{
+ WidgetDAO dao(widgetHandle);
+ return GetFilePathInWidgetPackageInternal(languageTags, dao.getPath(), file);
+}
+
+DPL::OptionalString getStartFile(const WrtDB::DbWidgetHandle widgetHandle)
+{
+ using namespace LocalizationUtils;
+
+ WidgetDAO dao(widgetHandle);
+
+ WidgetDAO::LocalizedStartFileList locList = dao.getLocalizedStartFileList();
+ WidgetDAO::WidgetStartFileList list = dao.getStartFileList();
+ LanguageTagsList tagsList = LocalizationUtils::GetUserAgentLanguageTags();
+
+ 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::DbWidgetHandle widgetHandle)
+{
+ using namespace LocalizationUtils;
+ WidgetDAO dao(widgetHandle);
+
+ WidgetDAO::WidgetLocalizedIconList locList = dao.getLocalizedIconList();
+ WidgetDAO::WidgetIconList list = dao.getIconList();
+ LanguageTagsList tagsList = LocalizationUtils::GetUserAgentLanguageTags();
+
+ 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(
+ WrtDB::DbWidgetHandle widgetHandle,
+ const LanguageTagsList &languageTags)
+{
+ using namespace LocalizationUtils;
+ WidgetDAO dao(widgetHandle);
+ WidgetDAO::WidgetIconList list = dao.getIconList();
+
+ WidgetIconList outlist;
+
+ FOREACH(it, list)
+ {
+ LogDebug(":" << it->iconSrc);
+ if (!!getFilePathInWidgetPackage(widgetHandle,
+ languageTags,
+ it->iconSrc))
+ {
+ WidgetIcon ret;
+ ret.src = it->iconSrc;
+ ret.width = it->iconWidth;
+ ret.height = it->iconHeight;
+ outlist.push_back(ret);
+ }
+ }
+ return outlist;
+}
+
+OptionalWidgetStartFileInfo getStartFileInfo(
+ WrtDB::DbWidgetHandle widgetHandle,
+ const LanguageTagList &tagsList)
+{
+ using namespace LocalizationUtils;
+
+ WidgetStartFileInfo info;
+
+ WidgetDAO dao(widgetHandle);
+ WidgetDAO::LocalizedStartFileList locList =
+ dao.getLocalizedStartFileList();
+ WidgetDAO::WidgetStartFileList list = dao.getStartFileList();
+
+ 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;
+ info.localizedPath += it->src;
+ }
+ return info;
+ }
+ }
+ }
+ }
+ }
+
+ return OptionalWidgetStartFileInfo::Null;
+}
+
+WidgetLocalizedInfo getLocalizedInfo(const WrtDB::DbWidgetHandle handle)
+{
+ LanguageTagList languages =
+ LocalizationUtils::GetUserAgentLanguageTags();
+ WidgetDAO dao(handle);
+ 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;
+}
+}
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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
+ PARENT_SCOPE
+)
+
+SET(DPL_LOG_INCLUDE_DIR
+ ${PROJECT_SOURCE_DIR}/modules/log/include/
+ PARENT_SCOPE
+)
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <dpl/read_write_mutex.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:
+ ReadWriteMutex m_spinLock;
+
+ 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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;
+
+ 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);
+ 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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;
+}
+}
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <dpl/log/dlog_log_provider.h>
+#include <cstring>
+#include <sstream>
+#include <dlog.h>
+
+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)
+{
+ 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)
+{
+ 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)
+{
+ 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)
+{
+ 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)
+{
+ LOG(LOG_DEBUG, "DPL", "%s", FormatMessage(message, filename, line, function).c_str());
+}
+
+}
+} // namespace DPL
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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)
+{
+ ReadWriteMutex::ScopedWriteLock lock(&m_spinLock);
+ m_providers.push_back(provider);
+}
+
+void LogSystem::RemoveProvider(AbstractLogProvider *provider)
+{
+ ReadWriteMutex::ScopedWriteLock lock(&m_spinLock);
+ m_providers.remove(provider);
+}
+
+void LogSystem::Debug(const char *message, const char *filename, int line, const char *function)
+{
+ ReadWriteMutex::ScopedReadLock lock(&m_spinLock);
+
+ 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)
+{
+ ReadWriteMutex::ScopedReadLock lock(&m_spinLock);
+
+ 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)
+{
+ ReadWriteMutex::ScopedReadLock lock(&m_spinLock);
+
+ 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)
+{
+ ReadWriteMutex::ScopedReadLock lock(&m_spinLock);
+
+ 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)
+{
+ ReadWriteMutex::ScopedReadLock lock(&m_spinLock);
+
+ for (AbstractLogProviderPtrList::iterator iterator = m_providers.begin(); iterator != m_providers.end(); ++iterator)
+ (*iterator)->Pedantic(message, filename, line, function);
+}
+
+}
+} // namespace DPL
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <dpl/log/old_style_log_provider.h>
+#include <dpl/colors.h>
+#include <cstdio>
+#include <cstring>
+#include <sstream>
+#include <sys/time.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)
+{
+}
+
+void OldStyleLogProvider::Debug(const char *message, const char *filename, int line, const char *function)
+{
+ if (m_showDebug)
+ 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)
+ 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)
+ 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)
+ 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)
+ fprintf(stdout, "%s%s%s\n", PEDANTIC_BEGIN, FormatMessage(message, filename, line, function).c_str(), PEDANTIC_END);
+}
+
+}
+} // namespace DPL
--- /dev/null
+!!!options!!! stop
+UI module for displaying all kinds of pop-up dialogs
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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
+#
+
+SET(DPL_POPUP_SOURCES
+ ${PROJECT_SOURCE_DIR}/modules/popup/src/popup_manager.cpp
+ ${PROJECT_SOURCE_DIR}/modules/popup/src/evas_object.cpp
+ ${PROJECT_SOURCE_DIR}/modules/popup/src/popup_renderer.cpp
+ ${PROJECT_SOURCE_DIR}/modules/popup/src/popup_controller.cpp
+ PARENT_SCOPE
+ )
+
+SET(DPL_POPUP_HEADERS
+ ${PROJECT_SOURCE_DIR}/modules/popup/include/dpl/popup/popup.h
+ ${PROJECT_SOURCE_DIR}/modules/popup/include/dpl/popup/evas_object.h
+ ${PROJECT_SOURCE_DIR}/modules/popup/include/dpl/popup/popup_controller.h
+ ${PROJECT_SOURCE_DIR}/modules/popup/include/dpl/popup/popup_manager.h
+ ${PROJECT_SOURCE_DIR}/modules/popup/include/dpl/popup/popup_object.h
+ ${PROJECT_SOURCE_DIR}/modules/popup/include/dpl/popup/popup_renderer.h
+ PARENT_SCOPE
+ )
+
+SET(DPL_POPUP_INCLUDE_DIR
+ ${PROJECT_SOURCE_DIR}/modules/popup/include
+ PARENT_SCOPE
+)
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file evas_object.h
+ * @author Lukasz Wrzosek (l.wrzosel@samsung.com)
+ * @version 1.0
+ * @brief This file is the header for Evas_Object wrapper from Efl.
+ */
+#ifndef WRT_SRC_DOMAIN_EFL_EVAS_OBJECT_H
+#define WRT_SRC_DOMAIN_EFL_EVAS_OBJECT_H
+
+#include <dpl/framework_efl.h>
+#include <dpl/assert.h>
+#include <dpl/shared_ptr.h>
+#include <dpl/foreach.h>
+#include <dpl/apply.h>
+#include <set>
+#include <string>
+#include <tuple>
+#include <utility>
+
+namespace DPL {
+namespace Popup {
+
+class EvasObject
+{
+ class EvasObjectShared;
+ typedef DPL::SharedPtr<EvasObjectShared> EvasObjectSharedPtr;
+
+ public:
+ class IConnection
+ {
+ public:
+ Evas_Object* GetEvasObject();
+ void Disconnect();
+
+ private:
+ IConnection(EvasObjectShared* object);
+ virtual ~IConnection()
+ {
+ }
+ virtual void Call(void* /*event_info*/) = 0;
+
+ static void SmartCallbackWrapper(void* data,
+ Evas_Object* /*object*/,
+ void* event_info);
+ static void EvasCallbackWrapper(void* data,
+ Evas* /*evas*/,
+ Evas_Object* /*object*/,
+ void* event_info);
+
+ virtual void ConnectPrv() = 0;
+ virtual void DisconnectPrv() = 0;
+
+ friend class EvasObjectShared;
+
+ EvasObjectShared* m_object;
+ };
+
+ private:
+ class EvasObjectShared : DPL::Noncopyable
+ {
+ public:
+ friend class IConnection;
+ Evas_Object* GetObject();
+
+ typedef std::set<IConnection*> IConnectionsSet;
+
+ class SmartConnectionBase : public IConnection
+ {
+ public:
+ SmartConnectionBase(const std::string& name,
+ EvasObjectShared* object);
+
+ virtual void ConnectPrv();
+ virtual void DisconnectPrv();
+ std::string m_callbackName;
+ };
+
+ template<typename ... Args>
+ class SmartConnection : public SmartConnectionBase
+ {
+ public:
+ typedef void (*CbType)(IConnection* connection,
+ void* event_info,
+ Args ... args);
+
+ SmartConnection(const std::string& name,
+ CbType callback,
+ EvasObjectShared* object,
+ Args ... args) :
+ SmartConnectionBase(name, object),
+ m_callback(callback),
+ m_args(args ...)
+ {
+ }
+
+ virtual ~SmartConnection()
+ {
+ }
+
+ virtual void Call(void* event_info)
+ {
+ DPL::Apply<void,
+ DPL::ExtraArgsInsertPolicy::Prepend>(m_callback,
+ m_args,
+ this,
+ event_info);
+ }
+
+ private:
+ CbType m_callback;
+ std::tuple<Args ...> m_args;
+ };
+
+ template <class ThisType, class ArgType1>
+ class SmartMemberConnection1 : public SmartConnectionBase
+ {
+ public:
+ typedef void (ThisType::*CbType)(IConnection* connection,
+ void* event_info, ArgType1 *arg1);
+
+ SmartMemberConnection1(const std::string& name,
+ CbType callback,
+ ThisType* callee,
+ ArgType1* arg1,
+ EvasObjectShared* object) :
+ SmartConnectionBase(name, object),
+ m_callback(callback),
+ m_callee(callee),
+ m_arg1(arg1)
+ {
+ }
+
+ virtual ~SmartMemberConnection1()
+ {
+ }
+
+ virtual void Call(void* event_info)
+ {
+ (m_callee->*m_callback)(this, event_info, m_arg1);
+ }
+
+ private:
+ CbType m_callback;
+ ThisType* m_callee;
+ ArgType1* m_arg1;
+ };
+
+ template <class ThisType, class ArgType1, class ArgType2>
+ class SmartMemberConnection2 : public SmartConnectionBase
+ {
+ public:
+ typedef void (ThisType::*CbType)(IConnection* connection,
+ void* event_info, ArgType1 *arg1,
+ ArgType2* arg2);
+
+ SmartMemberConnection2(const std::string& name,
+ CbType callback,
+ ThisType* callee,
+ ArgType1* arg1,
+ ArgType2* arg2,
+ EvasObjectShared* object) :
+ SmartConnectionBase(name, object),
+ m_callback(callback),
+ m_callee(callee),
+ m_arg1(arg1),
+ m_arg2(arg2)
+ {
+ }
+
+ virtual ~SmartMemberConnection2()
+ {
+ }
+
+ virtual void Call(void* event_info)
+ {
+ (m_callee->*m_callback)(this, event_info, m_arg1, m_arg2);
+ }
+
+ private:
+ CbType m_callback;
+ ThisType* m_callee;
+ ArgType1* m_arg1;
+ ArgType2* m_arg2;
+ };
+
+ class EvasConnectionBase : public IConnection
+ {
+ public:
+ EvasConnectionBase(Evas_Callback_Type type,
+ EvasObjectShared* object);
+
+ virtual void ConnectPrv();
+ virtual void DisconnectPrv();
+
+ Evas_Callback_Type m_callbackType;
+ };
+
+ template <class ArgType1>
+ class EvasConnection1 : public EvasConnectionBase
+ {
+ public:
+ typedef void (*CbType)(IConnection* connection, void* event_info,
+ ArgType1 *arg1);
+
+ EvasConnection1(Evas_Callback_Type type,
+ CbType callback,
+ ArgType1* arg1,
+ EvasObjectShared* object) :
+ EvasConnectionBase(type, object),
+ m_callback(callback),
+ m_arg1(arg1)
+ {
+ }
+
+ virtual ~EvasConnection1()
+ {
+ }
+
+ virtual void Call(void* event_info)
+ {
+ m_callback(this, event_info, m_arg1);
+ }
+
+ private:
+ CbType m_callback;
+ ArgType1* m_arg1;
+ };
+
+ template <class ArgType1, class ArgType2>
+ class EvasConnection2 : public EvasConnectionBase
+ {
+ public:
+ typedef void (*CbType)(IConnection* connection, void* event_info,
+ ArgType1 *arg1, ArgType2 *arg2);
+
+ EvasConnection2(Evas_Callback_Type type,
+ CbType callback,
+ ArgType1* arg1,
+ ArgType2* arg2,
+ EvasObjectShared* object) :
+ EvasConnectionBase(type, object),
+ m_callback(callback),
+ m_arg1(arg1),
+ m_arg2(arg2)
+ {
+ }
+
+ virtual ~EvasConnection2()
+ {
+ }
+
+ virtual void Call(void* event_info)
+ {
+ m_callback(this, event_info, m_arg1, m_arg2);
+ }
+
+ private:
+ CbType m_callback;
+ ArgType1* m_arg1;
+ ArgType2* m_arg2;
+ };
+
+ template <class ThisType, class ArgType1>
+ class EvasMemberConnection1 : public EvasConnectionBase
+ {
+ public:
+ typedef void (ThisType::*CbType)(IConnection* connection,
+ void* event_info, ArgType1 *arg1);
+
+ EvasMemberConnection1(Evas_Callback_Type type,
+ CbType callback,
+ ThisType* callee,
+ ArgType1* arg1,
+ EvasObjectShared* object) :
+ EvasConnectionBase(type, object),
+ m_callback(callback),
+ m_callee(callee),
+ m_arg1(arg1)
+ {
+ }
+
+ virtual ~EvasMemberConnection1()
+ {
+ }
+
+ virtual void Call(void* event_info)
+ {
+ (m_callee->*m_callback)(this, event_info, m_arg1);
+ }
+
+ private:
+ CbType m_callback;
+ ThisType* m_callee;
+ ArgType1* m_arg1;
+ };
+
+ template <class ThisType, class ArgType1, class ArgType2>
+ class EvasMemberConnection2 : public EvasConnectionBase
+ {
+ public:
+ typedef void (ThisType::*CbType)(IConnection* connection,
+ void* event_info, ArgType1* arg1,
+ ArgType2* arg2);
+
+ EvasMemberConnection2(Evas_Callback_Type type,
+ CbType callback,
+ ThisType* callee,
+ ArgType1* arg1,
+ ArgType2* arg2,
+ EvasObjectShared* object) :
+ EvasConnectionBase(type, object),
+ m_callback(callback),
+ m_callee(callee),
+ m_arg1(arg1),
+ m_arg2(arg2)
+ {
+ }
+
+ virtual ~EvasMemberConnection2()
+ {
+ }
+
+ virtual void Call(void* event_info)
+ {
+ (m_callee->*m_callback)(this, event_info, m_arg1, m_arg2);
+ }
+
+ private:
+ CbType m_callback;
+ ThisType* m_callee;
+ ArgType1* m_arg1;
+ ArgType2* m_arg2;
+ };
+
+ EvasObjectShared();
+ explicit EvasObjectShared(Evas_Object* object);
+ void SetObject(Evas_Object* object);
+ ~EvasObjectShared();
+
+ template<typename ... Args>
+ IConnection* ConnectSmartCallback(const char* callbackName,
+ typename SmartConnection<Args ...>::CbType callback,
+ Args ... args)
+ {
+ Assert(m_object);
+ Assert(callbackName);
+ Assert(callback);
+ IConnection* connection = new SmartConnection<Args ...>(
+ callbackName,
+ callback,
+ this,
+ args ...);
+ m_connections.insert(connection);
+ connection->ConnectPrv();
+ return connection;
+ }
+
+ template <class ThisType, class ArgType1, class ArgType2>
+ IConnection* ConnectMemberSmartCallback(
+ const char* callbackName,
+ typename SmartMemberConnection2<ThisType, ArgType1,
+ ArgType2>::CbType callback,
+ ThisType* callee,
+ ArgType1* arg1,
+ ArgType2* arg2)
+ {
+ Assert(m_object);
+ Assert(callee);
+ Assert(callbackName);
+ Assert(callback);
+ IConnection* connection =
+ new SmartMemberConnection2<ThisType, ArgType1, ArgType2>(
+ callbackName,
+ callback,
+ callee,
+ arg1,
+ arg2,
+ this);
+ m_connections.insert(connection);
+ connection->ConnectPrv();
+ return connection;
+ }
+
+ template <class ThisType, class ArgType1>
+ IConnection* ConnectMemberSmartCallback(
+ const char* callbackName,
+ typename SmartMemberConnection1<ThisType,
+ ArgType1>::CbType callback,
+ ThisType* callee,
+ ArgType1* arg1)
+ {
+ Assert(m_object);
+ Assert(callee);
+ Assert(callbackName);
+ Assert(callback);
+ IConnection* connection =
+ new SmartMemberConnection1<ThisType, ArgType1>(callbackName,
+ callback,
+ callee,
+ arg1,
+ this);
+ m_connections.insert(connection);
+ connection->ConnectPrv();
+ return connection;
+ }
+
+ template <class ArgType1, class ArgType2>
+ IConnection* ConnectEvasCallback(Evas_Callback_Type callbackType,
+ typename EvasConnection2<ArgType1, ArgType2>::CbType callback,
+ ArgType1* arg1,
+ ArgType2* arg2)
+ {
+ Assert(m_object);
+ Assert(callbackType);
+ Assert(callback);
+ IConnection* connection = new EvasConnection2<ArgType1, ArgType2>(
+ callbackType,
+ callback,
+ arg1,
+ arg2,
+ this);
+ m_connections.insert(connection);
+ connection->ConnectPrv();
+ return connection;
+ }
+
+ template <class ArgType1>
+ IConnection* ConnectEvasCallback(Evas_Callback_Type callbackType,
+ typename EvasConnection1<ArgType1>::CbType callback,
+ ArgType1* arg1)
+ {
+ Assert(m_object);
+ Assert(callbackType);
+ Assert(callback);
+ IConnection* connection = new EvasConnection1<ArgType1>(
+ callbackType,
+ callback,
+ arg1,
+ this);
+ m_connections.insert(connection);
+ connection->ConnectPrv();
+ return connection;
+ }
+
+ template <class ThisType, class ArgType1, class ArgType2>
+ IConnection* ConnectMemberEvasCallback(
+ Evas_Callback_Type callbackType,
+ typename EvasMemberConnection2<ThisType, ArgType1,
+ ArgType2>::CbType callback,
+ ThisType* callee,
+ ArgType1* arg1,
+ ArgType2* arg2)
+ {
+ Assert(m_object);
+ Assert(callee);
+ Assert(callbackType);
+ Assert(callback);
+ IConnection* connection =
+ new EvasMemberConnection2<ThisType, ArgType1, ArgType2>(
+ callbackType,
+ callback,
+ callee,
+ arg1,
+ arg2,
+ this);
+ m_connections.insert(connection);
+ connection->ConnectPrv();
+ return connection;
+ }
+
+ template <class ThisType, class ArgType1>
+ IConnection* ConnectMemberEvasCallback(
+ Evas_Callback_Type callbackType,
+ typename EvasMemberConnection1<ThisType,
+ ArgType1>::CbType callback,
+ ThisType* callee,
+ ArgType1* arg1)
+ {
+ Assert(m_object);
+ Assert(callee);
+ Assert(callbackType);
+ Assert(callback);
+ IConnection* connection =
+ new EvasMemberConnection1<ThisType, ArgType1>(callbackType,
+ callback,
+ callee,
+ arg1,
+ this);
+ m_connections.insert(connection);
+ connection->ConnectPrv();
+ return connection;
+ }
+
+ bool DisconnectCallback(IConnection* connection);
+ void DisconnectAll();
+
+ static void StaticOnDelEvent(void* data,
+ Evas* /*e*/,
+ Evas_Object* /*o*/,
+ void* /*ev*/);
+
+ IConnectionsSet m_connections;
+ Evas_Object* m_object;
+ };
+
+ public:
+ EvasObject();
+ explicit EvasObject(Evas_Object* object);
+ EvasObject(const EvasObject& other);
+ ~EvasObject();
+
+ EvasObject& operator=(const EvasObject& other);
+ EvasObject* operator=(Evas_Object* object);
+
+ operator Evas_Object *();
+
+ bool IsValid() const
+ {
+ Assert(m_object);
+ return m_object->GetObject() != NULL;
+ }
+
+ bool DisconnectCallback(IConnection* connection);
+ void DisconnectAll();
+
+ template <class ... Args>
+ IConnection* ConnectSmartCallback(
+ const char* callbackName,
+ typename EvasObjectShared::SmartConnection<Args ...>::CbType
+ callback,
+ Args ... args)
+ {
+ Assert(m_object);
+ return m_object->ConnectSmartCallback(callbackName, callback, args ...);
+ }
+
+ template <class ThisType, class ArgType1, class ArgType2>
+ IConnection* ConnectMemberSmartCallback(
+ const char* callbackName,
+ typename EvasObjectShared::SmartMemberConnection2<ThisType,
+ ArgType1,
+ ArgType2>::CbType
+ callback,
+ ThisType* callee,
+ ArgType1* arg1,
+ ArgType2* arg2)
+ {
+ Assert(m_object);
+ Assert(callee);
+ Assert(callback);
+ return m_object->ConnectMemberSmartCallback(callbackName,
+ callback,
+ callee,
+ arg1,
+ arg2);
+ }
+
+ template <class ThisType, class ArgType1>
+ IConnection* ConnectMemberSmartCallback(
+ const char* callbackName,
+ typename EvasObjectShared::SmartMemberConnection1<ThisType,
+ ArgType1>::CbType
+ callback,
+ ThisType* callee,
+ ArgType1* arg1)
+ {
+ Assert(m_object);
+ Assert(callee);
+ Assert(callback);
+ return m_object->ConnectMemberSmartCallback(callbackName,
+ callback,
+ callee,
+ arg1);
+ }
+
+ template <class ArgType1, class ArgType2>
+ IConnection* ConnectEvasCallback(
+ Evas_Callback_Type callbackType,
+ typename EvasObjectShared::EvasConnection1<ArgType1>::CbType
+ callback,
+ ArgType1* arg1,
+ ArgType2* arg2)
+ {
+ Assert(m_object);
+ return m_object->ConnectEvasCallback(callbackType, callback, arg1, arg2);
+ }
+
+ template <class ArgType1>
+ IConnection* ConnectEvasCallback(
+ Evas_Callback_Type callbackType,
+ typename EvasObjectShared::EvasConnection1<ArgType1>::CbType
+ callback,
+ ArgType1* arg1)
+ {
+ Assert(m_object);
+ return m_object->ConnectEvasCallback(callbackType, callback, arg1);
+ }
+
+ template <class ThisType, class ArgType1>
+ IConnection* ConnectMemberEvasCallback(
+ Evas_Callback_Type callbackType,
+ typename EvasObjectShared::EvasMemberConnection1<ThisType,
+ ArgType1>::CbType
+ callback,
+ ThisType* callee,
+ ArgType1* arg1)
+ {
+ Assert(m_object);
+ Assert(callee);
+ Assert(callback);
+ return m_object->ConnectMemberEvasCallback(callbackType,
+ callback,
+ callee,
+ arg1);
+ }
+
+ template <class ThisType, class ArgType1, class ArgType2>
+ IConnection* ConnectMemberEvasCallback(
+ Evas_Callback_Type callbackType,
+ typename EvasObjectShared::EvasMemberConnection2<ThisType, ArgType1,
+ ArgType2>::CbType
+ callback,
+ ThisType* callee,
+ ArgType1* arg1,
+ ArgType2* arg2)
+ {
+ Assert(m_object);
+ Assert(callee);
+ Assert(callback);
+ return m_object->ConnectMemberEvasCallback(callbackType,
+ callback,
+ callee,
+ arg1,
+ arg2);
+ }
+
+ private:
+ EvasObjectSharedPtr m_object;
+};
+
+}//namespace
+}//namespace
+
+
+#endif //WRT_SRC_DOMAIN_EFL_EVAS_OBJECT_H
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file popup.h
+ * @author Lukasz Wrzosek (l.wrzosek@samsung.com)
+ * @version 1.0
+ * @brief This is popup inteface declaration
+ */
+
+#ifndef WRT_SRC_POPUP_POPUP_H_
+#define WRT_SRC_POPUP_POPUP_H_
+
+#include <dpl/enable_shared_from_this.h>
+#include <dpl/shared_ptr.h>
+#include <dpl/assert.h>
+#include <dpl/log/log.h>
+#include <string>
+#include <dpl/optional.h>
+#include <dpl/popup/popup_object.h>
+#include <dpl/event/nested_loop.h>
+
+namespace DPL {
+namespace Popup {
+
+struct AnswerCallbackData
+{
+ int buttonAnswer;
+ DPL::Optional<std::string> password;
+ bool chackState;
+ DPL::Event::LoopHandle loopHandle;
+};
+
+class PopupManager;
+class IPopup;
+typedef DPL::SharedPtr<IPopup> IPopupPtr;
+
+class IPopup : protected DPL::EnableSharedFromThis<IPopup>
+{
+ public:
+ virtual void SetTitle(const std::string &title) = 0;
+ /*The object is deleted automatically after rendered */
+ virtual void Append(PopupObject::IPopupObject *object) = 0;
+
+ protected:
+ typedef void (*PopupCallbackType)(const AnswerCallbackData& answer,
+ void *data);
+ virtual void Show(PopupCallbackType callback,
+ void* data) = 0;
+ virtual ~IPopup()
+ {
+ }
+
+ private:
+ friend class PopupManager;
+ friend class DPL::SharedPtr<IPopup>;
+};
+
+} // namespace Popup
+} // namespace DPL
+
+#endif //WRT_SRC_POPUP_POPUP_H_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @file popup_controller.h
+ * @author Lukasz Wrzosek (l.wrzosek@samsung.com)
+ * @version 1.0
+ * @bref Header file for popup controller
+ */
+
+/**
+ * To display a popup from a given class:
+ *
+ **class ABC
+ **{
+ * void AskUser()
+ * {
+ * }
+ *
+ * void DoSomeLogicWithAnswer()
+ * {
+ * }
+ **};
+ *
+ * ... update the class to something simmilar:
+ *
+ **class ABC : Popup::PopupControllerUser
+ **{
+ * void AskUser() {
+ * using namespace Popup;
+ * CtrlPopupPtr popup =
+ * PopupControllerSingletion::Instance().CreatePopup();
+ * popup->SetTitle("Title");
+ * popup->SetContent("Content");
+ * popup->AddButton("name1", 1);
+ * popup->AddButton("name2", 2);
+ * ListenForAnswer(popup);
+ * ShowPopupEvent event(popup,
+ * MakeAnswerCallback(this,
+ * &ABC::DoSomeLogicWithAnswer));
+ * CONTROLLER_POST_EVENT(PopupController, event);
+ * }
+ *
+ * void DoSomeLogicWithAnswer(Popup::LabelId answer) {
+ * if (answer == 1)
+ * ;//name1 pressed
+ * else if (answer == 2)
+ * ;//name2 pressed
+ * }
+ **};
+ **/
+
+#ifndef WRT_SRC_POPUP_CONTROLLER_POPUP_CONTROLLER_H_
+#define WRT_SRC_POPUP_CONTROLLER_POPUP_CONTROLLER_H_
+
+#include <dpl/singleton.h>
+#include <dpl/event/controller.h>
+#include <dpl/event/event_listener.h>
+#include <dpl/generic_event.h>
+#include <dpl/mutex.h>
+#include <dpl/exception.h>
+#include <dpl/shared_ptr.h>
+#include <dpl/enable_shared_from_this.h>
+#include <dpl/noncopyable.h>
+#include <dpl/log/log.h>
+#include <dpl/event/nested_loop.h>
+#include <dpl/popup/popup_manager.h>
+
+namespace DPL {
+namespace Popup {
+typedef int LabelId;
+
+struct PopupAnswerCallback
+{
+ typedef void (PopupAnswerCallback::*MemberPtr)();
+
+ void* callee;
+ MemberPtr member;
+ void (*callTranslator)(PopupAnswerCallback* callData,
+ const AnswerCallbackData& answer);
+
+ void Call(const AnswerCallbackData& answer)
+ {
+ callTranslator(this, answer);
+ }
+};
+
+class PopupController;
+class CtrlPopup;
+
+typedef DPL::SharedPtr<CtrlPopup> CtrlPopupPtr;
+
+DECLARE_GENERIC_EVENT_3(PopupAnswerEvent,
+ CtrlPopupPtr,
+ PopupAnswerCallback,
+ AnswerCallbackData)
+DECLARE_GENERIC_EVENT_3(ShowPopupEvent,
+ CtrlPopupPtr,
+ PopupAnswerCallback,
+ DPL::Event::LoopHandle)
+
+class CtrlPopup : public DPL::Event::EventSupport<PopupAnswerEvent>,
+ protected DPL::EnableSharedFromThis<CtrlPopup>
+{
+ public:
+ void SetTitle(const std::string &title);
+ void Append(PopupObject::IPopupObject *object);
+
+ private:
+ friend class PopupController;
+ friend class DPL::SharedPtr<CtrlPopup>;
+
+ explicit CtrlPopup(IPopupPtr popup);
+ ~CtrlPopup();
+ void EmitAnswer(const AnswerCallbackData& answer);
+
+ IPopupPtr m_popup;
+ PopupAnswerCallback m_callback;
+ DPL::Event::LoopHandle m_loopHandle;
+};
+
+class PopupController :
+ public DPL::Event::Controller<DPL::TypeListDecl<ShowPopupEvent>::Type>
+{
+ public:
+ CtrlPopupPtr CreatePopup() const;
+
+ void setExternalCanvas(void* canvas)
+ {
+ m_canvas = canvas;
+ }
+ void* getExternalCanvas() const
+ {
+ return m_canvas;
+ }
+ void* m_canvas;
+
+ protected:
+ virtual void OnEventReceived(const ShowPopupEvent& event);
+ PopupController();
+
+ private:
+ static void StaticOnAnswerReceived(const AnswerCallbackData& answer,
+ CtrlPopupPtr* popup);
+};
+
+class PopupControllerUser : DPL::Event::EventListener<PopupAnswerEvent>
+{
+ template <class Type>
+ struct PopupAnswerCallbackCreator
+ {
+ typedef void (Type::*MemberPtr)(const AnswerCallbackData& answer);
+ union Caster
+ {
+ MemberPtr specific;
+ PopupAnswerCallback::MemberPtr generic;
+ };
+
+ static PopupAnswerCallback Create(Type* callee,
+ MemberPtr callback)
+ {
+ PopupAnswerCallback callData;
+
+ callData.callee = callee;
+
+ Caster caster;
+ caster.specific = callback;
+ callData.member = caster.generic;
+
+ callData.callTranslator =
+ &PopupAnswerCallbackCreator::MemberCallbackTranslator;
+
+ return callData;
+ }
+
+ static void MemberCallbackTranslator(PopupAnswerCallback* callData,
+ const AnswerCallbackData& answer)
+ {
+ Type* typedThis = static_cast<Type*>(callData->callee);
+ Caster caster;
+ caster.generic = callData->member;
+ MemberPtr typedCallback = caster.specific;
+ (typedThis->*typedCallback)(answer);
+ }
+ };
+
+ protected:
+ virtual void OnEventReceived(const PopupAnswerEvent& event);
+ void ListenForAnswer(CtrlPopupPtr popup);
+
+ template <class Type>
+ PopupAnswerCallback MakeAnswerCallback(Type* This,
+ void (Type::*callback)
+ (const AnswerCallbackData &))
+ {
+ return PopupAnswerCallbackCreator<Type>::Create(This, callback);
+ }
+};
+
+typedef DPL::Singleton<PopupController> PopupControllerSingleton;
+
+} //namespace Popup
+} //namespace DPL
+
+#endif //WRT_SRC_POPUP_CONTROLLER_POPUP_CONTROLLER_H_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file popup_manager.h
+ * @author Lukasz Wrzosek (l.wrzosek@samsung.com)
+ * @version 1.0
+ * @brief This is popup_manager declaration file
+ */
+
+#ifndef WRT_SRC_POPUP_POPUP_MANAGER_H_
+#define WRT_SRC_POPUP_POPUP_MANAGER_H_
+
+#include <dpl/assert.h>
+#include <dpl/shared_ptr.h>
+#include <dpl/noncopyable.h>
+#include <dpl/singleton.h>
+#include <dpl/optional.h>
+#include <dpl/popup/popup.h>
+#include <dpl/popup/popup_renderer.h>
+
+namespace DPL {
+namespace Popup {
+
+class PopupManager : DPL::Noncopyable
+{
+ template <class ArgType>
+ struct TemplatedPopupCallback
+ {
+ typedef void (*Type)(const AnswerCallbackData& answer, ArgType* data);
+ };
+
+ public:
+ PopupManager() : m_initialized(false) {}
+ ~PopupManager()
+ {
+ Assert(!m_initialized);
+ }
+ void Initialize (PopupRendererPtr creator);
+ void Deinitialize();
+ void SetPopupRenderer (PopupRendererPtr creator);
+ IPopupPtr CreatePopup();
+
+ template <class ArgType>
+ void RunAsyncWithArgType(IPopupPtr popup,
+ typename TemplatedPopupCallback<ArgType>::Type callback,
+ ArgType* argument)
+ {
+ Assert(callback);
+ WrapCbAndArg<ArgType>* wrapped =
+ new WrapCbAndArg<ArgType>(callback, argument);
+ popup->Show(&CallbackArgTypeTranslator<ArgType>, wrapped);
+ }
+
+ void Show(IPopupPtr popup,
+ IPopup::PopupCallbackType callback,
+ void* userdata)
+ {
+ popup->Show(callback, userdata);
+ }
+
+ void setExternalCanvas(void* externalCanvas)
+ {
+ Assert(m_initialized && "Manger should be initialized");
+ m_popupRenderer->setExternalCanvas(externalCanvas);
+ }
+
+ private:
+ template <class ArgType>
+ struct WrapCbAndArg
+ {
+ WrapCbAndArg(typename TemplatedPopupCallback<ArgType>::Type cb,
+ ArgType* arg) :
+ callback(cb),
+ argument(arg)
+ {
+ }
+
+ typename TemplatedPopupCallback<ArgType>::Type callback;
+ ArgType* argument;
+ };
+
+ template <class ArgType>
+ static void CallbackArgTypeTranslator(const AnswerCallbackData & answer,
+ void* data)
+ {
+ WrapCbAndArg<ArgType>* wrapped =
+ static_cast< WrapCbAndArg<ArgType>* >(data);
+ wrapped->callback(answer, wrapped->argument);
+ delete wrapped;
+ }
+
+ bool m_initialized;
+ PopupRendererPtr m_popupRenderer;
+};
+
+typedef DPL::Singleton<Popup::PopupManager> PopupManagerSingleton;
+
+} // namespace Popup
+} // namespace DPL
+
+#endif //WRT_SRC_POPUP_POPUP_MANAGER_H_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file popup_object.h
+ * @author Justyna Mejzner (j.mejzner@samsung.com)
+ * @version 1.0
+ * @brief This is declaration file of PopupObject
+ */
+
+#ifndef WRT_SRC_POPUP_POPUPOBJECT_H_
+#define WRT_SRC_POPUP_POPUPOBJECT_H_
+
+#include <dpl/foreach.h>
+
+#include <list>
+#include <string>
+
+namespace DPL {
+namespace Popup {
+
+namespace PopupObject {
+class IPopupObject;
+class PopupObjectBase;
+class Button;
+class Label;
+class Check;
+
+typedef std::list<IPopupObject*> PopupObjects;
+
+enum PopupType
+{
+ BUTTON,
+ LABEL,
+ CHECK
+};
+
+class IPopupObject
+{
+ public:
+ virtual Button* asButton() = 0;
+ virtual Label* asLabel() = 0;
+ virtual Check* asCheck() = 0;
+ virtual PopupType getType() const = 0;
+ virtual ~IPopupObject()
+ {
+ }
+};
+
+class PopupObjectBase : public IPopupObject
+{
+ public:
+ virtual Button* asButton()
+ {
+ Assert("wrong type");
+ return NULL;
+ }
+ virtual Label* asLabel()
+ {
+ Assert("wrong type");
+ return NULL;
+ }
+ virtual Check* asCheck()
+ {
+ Assert("wrong type");
+ return NULL;
+ }
+
+ PopupType getType() const
+ {
+ return m_type;
+ }
+
+ protected:
+ PopupObjectBase(PopupType type) : m_type(type)
+ {
+ }
+
+ PopupType m_type;
+};
+
+class Button : public PopupObjectBase
+{
+ public:
+ Button(const std::string& label,
+ int labelId) :
+ PopupObjectBase(BUTTON),
+ m_label(label),
+ m_labelId(labelId)
+ {
+ }
+
+ Button* asButton()
+ {
+ return this;
+ }
+
+ const std::string& getLabel() const
+ {
+ return m_label;
+ }
+
+ int getLabelId() const
+ {
+ return m_labelId;
+ }
+
+ private:
+ std::string m_label;
+ int m_labelId;
+};
+
+class Label : public PopupObjectBase
+{
+ public:
+ Label(const std::string &label) :
+ PopupObjectBase(LABEL),
+ m_label(label)
+ {
+ }
+
+ Label* asLabel()
+ {
+ return this;
+ }
+
+ const std::string& getLabel() const
+ {
+ return m_label;
+ }
+
+ private:
+ std::string m_label;
+};
+
+class Check : public PopupObjectBase
+{
+ public:
+ Check(const std::string &label) :
+ PopupObjectBase(CHECK),
+ m_checkLabel(label)
+ {
+ }
+
+ Check* asCheck()
+ {
+ return this;
+ }
+
+ const std::string& getCheckLabel() const
+ {
+ return m_checkLabel;
+ }
+
+ private:
+ std::string m_checkLabel;
+};
+} /*PopupObject*/
+
+}//namespace Popup
+}//namespace DPL
+
+#endif //WRT_SRC_POPUP_POPUPOBJECT_H_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file popup_renderer.h
+ * @author Lukasz Wrzosek (l.wrzosek@samsung.com)
+ * @version 1.0
+ * @brief This is declaration file of PopupRenderer
+ */
+
+#ifndef WRT_SRC_POPUP_POPUP_RENDERER_H_
+#define WRT_SRC_POPUP_POPUP_RENDERER_H_
+
+#include <map>
+#include <string>
+
+#include <dpl/shared_ptr.h>
+#include <dpl/noncopyable.h>
+#include <dpl/log/log.h>
+#include <dpl/assert.h>
+#include <dpl/enable_shared_from_this.h>
+#include <dpl/foreach.h>
+
+#include <dpl/popup/popup.h>
+
+namespace DPL {
+namespace Popup {
+
+class PopupRenderer : public DPL::EnableSharedFromThis<PopupRenderer>
+{
+ public:
+ PopupRenderer();
+ ~PopupRenderer();
+ void Initialize();
+ void Deinitialize();
+ IPopupPtr CreatePopup();
+ virtual void setExternalCanvas(void* externalCanvas);
+ protected:
+ class Popup;
+ typedef DPL::SharedPtr<Popup> PopupPtr;
+
+ class Popup : public IPopup
+ {
+ public:
+ typedef std::map<int, std::string> ButtonMap;
+ virtual void SetTitle(const std::string &title)
+ {
+ LogDebug(title);
+ Assert(m_title.empty());
+ m_title = title;
+ }
+
+ virtual void Append(PopupObject::IPopupObject *object)
+ {
+ m_popupObjectList.push_back(object);
+ }
+
+ virtual void Show(IPopup::PopupCallbackType callback,
+ void* data)
+ {
+ Assert(callback);
+ m_data = data;
+ m_callback = callback;
+ m_renderer->Render(DPL::StaticPointerCast<Popup>(SharedFromThis()));
+ }
+
+ const std::string& GetTitle() const
+ {
+ return m_title;
+ }
+
+ PopupObject::PopupObjects& GetPopupObjects()
+ {
+ return m_popupObjectList;
+ }
+
+ virtual ~Popup()
+ {
+ FOREACH(it, m_popupObjectList) {
+ delete *it;
+ }
+ }
+
+ private:
+ friend class PopupRenderer;
+ friend class DPL::SharedPtr<Popup>;
+ friend class PopupObjectTheme;
+
+ Popup(DPL::SharedPtr<PopupRenderer> renderer) : m_renderer(renderer)
+ {
+ }
+
+ void ForwardAnswer(const AnswerCallbackData & answer) const
+ {
+ m_callback(answer, m_data);
+ }
+
+ std::string m_title;
+ void* m_data;
+ IPopup::PopupCallbackType m_callback;
+ PopupObject::PopupObjects m_popupObjectList;
+ DPL::SharedPtr<PopupRenderer> m_renderer;
+ };
+
+ private:
+ void Render (PopupPtr popup);
+
+ class Impl;
+ Impl* m_impl;
+};
+
+typedef DPL::SharedPtr<PopupRenderer> PopupRendererPtr;
+
+} // namespace Popup
+} // namespace DPL
+
+#endif //WRT_SRC_POPUP_POPUP_RENDERER_H_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file evas_object.cpp
+ * @author Lukasz Wrzosek (l.wrzosel@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation for Evas_Object wrapper from Efl.
+ */
+
+#include <dpl/popup/evas_object.h>
+#include <dpl/foreach.h>
+
+namespace DPL {
+namespace Popup {
+
+Evas_Object* EvasObject::IConnection::GetEvasObject()
+{
+ return m_object->GetObject();
+}
+
+void EvasObject::IConnection::Disconnect()
+{
+ m_object->DisconnectCallback(this);
+}
+
+EvasObject::IConnection::IConnection(EvasObject::EvasObjectShared* object) :
+ m_object(object)
+{
+}
+
+void EvasObject::IConnection::SmartCallbackWrapper(void* data,
+ Evas_Object* /*object*/,
+ void* event_info)
+{
+ Assert(data);
+ IConnection* Calle = static_cast<IConnection*>(data);
+ Calle->Call(event_info);
+}
+
+void EvasObject::IConnection::EvasCallbackWrapper(void* data,
+ Evas* /*evas*/,
+ Evas_Object* /*object*/,
+ void* event_info)
+{
+ Assert(data);
+ IConnection* Calle = static_cast<IConnection*>(data);
+ Calle->Call(event_info);
+}
+
+Evas_Object* EvasObject::EvasObjectShared::GetObject()
+{
+ return m_object;
+}
+
+EvasObject::EvasObjectShared::SmartConnectionBase::SmartConnectionBase(
+ const std::string& name,
+ EvasObject::EvasObjectShared* object) :
+ IConnection(object),
+ m_callbackName(name)
+{
+}
+
+void EvasObject::EvasObjectShared::SmartConnectionBase::ConnectPrv()
+{
+ evas_object_smart_callback_add(GetEvasObject(),
+ m_callbackName.c_str(),
+ &IConnection::SmartCallbackWrapper, this);
+}
+
+void EvasObject::EvasObjectShared::SmartConnectionBase::DisconnectPrv()
+{
+ evas_object_smart_callback_del(GetEvasObject(),
+ m_callbackName.c_str(),
+ &IConnection::SmartCallbackWrapper);
+}
+
+EvasObject::EvasObjectShared::EvasConnectionBase::EvasConnectionBase(
+ Evas_Callback_Type type,
+ EvasObject::EvasObjectShared* object) :
+ IConnection(object),
+ m_callbackType(type)
+{
+}
+
+void EvasObject::EvasObjectShared::EvasConnectionBase::ConnectPrv()
+{
+ evas_object_event_callback_add(
+ GetEvasObject(), m_callbackType, &IConnection::EvasCallbackWrapper,
+ this);
+}
+
+void EvasObject::EvasObjectShared::EvasConnectionBase::DisconnectPrv()
+{
+ evas_object_event_callback_del_full(
+ GetEvasObject(), m_callbackType, &IConnection::EvasCallbackWrapper,
+ this);
+}
+
+EvasObject::EvasObjectShared::EvasObjectShared() :
+ m_object(NULL)
+{
+}
+
+EvasObject::EvasObjectShared::EvasObjectShared(Evas_Object* object) :
+ m_object(object)
+{
+ Assert(m_object);
+ evas_object_event_callback_add(m_object,
+ EVAS_CALLBACK_DEL,
+ &StaticOnDelEvent,
+ this);
+}
+
+void EvasObject::EvasObjectShared::SetObject(Evas_Object* object)
+{
+ Assert(m_object == NULL);
+ Assert(object != NULL);
+ m_object = object;
+ evas_object_event_callback_add(m_object,
+ EVAS_CALLBACK_DEL,
+ &StaticOnDelEvent,
+ this);
+}
+
+EvasObject::EvasObjectShared::~EvasObjectShared()
+{
+ if (m_object) {
+ DisconnectAll();
+ evas_object_event_callback_del(m_object,
+ EVAS_CALLBACK_DEL,
+ &StaticOnDelEvent);
+ m_object = NULL;
+ }
+}
+
+bool EvasObject::EvasObjectShared::DisconnectCallback(IConnection* connection)
+{
+ IConnectionsSet::iterator it = m_connections.find(connection);
+ if (it != m_connections.end()) {
+ (*it)->DisconnectPrv();
+ delete connection;
+ m_connections.erase(it);
+ return true;
+ }
+ return false;
+}
+
+void EvasObject::EvasObjectShared::DisconnectAll()
+{
+ FOREACH(it, m_connections)
+ {
+ (*it)->DisconnectPrv();
+ delete *it;
+ }
+ m_connections.clear();
+}
+
+void EvasObject::EvasObjectShared::StaticOnDelEvent(void* data,
+ Evas* /*e*/,
+ Evas_Object* /*o*/,
+ void* /*ev*/)
+{
+ Assert(data);
+ EvasObjectShared* This = static_cast<EvasObjectShared*>(data);
+ if (This->m_object) {
+ evas_object_event_callback_del(This->m_object,
+ EVAS_CALLBACK_DEL,
+ &StaticOnDelEvent);
+ This->DisconnectAll();
+ This->m_object = NULL;
+ }
+}
+
+EvasObject::EvasObject() :
+ m_object(new EvasObjectShared())
+{
+}
+
+EvasObject::EvasObject(Evas_Object* object) :
+ m_object(new EvasObjectShared(object))
+{
+}
+
+EvasObject::EvasObject(const EvasObject& other) :
+ m_object(other.m_object)
+{
+}
+
+//this destructor must be here to let pimpl with shared_ptr work without warning
+EvasObject::~EvasObject()
+{
+}
+
+EvasObject& EvasObject::operator=(const EvasObject& other)
+{
+ Assert(m_object);
+ m_object = other.m_object;
+ return *this;
+}
+
+EvasObject* EvasObject::operator=(Evas_Object* object)
+{
+ Assert(m_object);
+ m_object->SetObject(object);
+ return this;
+}
+
+bool EvasObject::DisconnectCallback(IConnection* connection)
+{
+ Assert(m_object);
+ return m_object->DisconnectCallback(connection);
+}
+
+void EvasObject::DisconnectAll()
+{
+ Assert(m_object);
+ m_object->DisconnectAll();
+}
+
+EvasObject::operator Evas_Object *()
+{
+ Assert(m_object);
+ return m_object->GetObject();
+}
+
+} // namespace DPL
+} // namespace Popup
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @file popup_controller.cpp
+ * @author Lukasz Wrzosek (l.wrzosek@samsung.com)
+ * @version 1.0
+ * @bref Implementation file for popup controller
+ */
+
+#include <dpl/popup/popup_controller.h>
+
+#include <dpl/assert.h>
+#include <dpl/log/log.h>
+#include <dpl/singleton_impl.h>
+IMPLEMENT_SINGLETON(DPL::Popup::PopupController)
+
+namespace DPL {
+namespace Popup {
+
+void CtrlPopup::SetTitle(const std::string &title)
+{
+ Assert(m_popup);
+ m_popup->SetTitle(title);
+}
+
+void CtrlPopup::Append(PopupObject::IPopupObject *object)
+{
+ Assert(m_popup);
+ m_popup->Append(object);
+}
+
+CtrlPopup::CtrlPopup(IPopupPtr popup) :
+ m_popup(popup),
+ m_callback()
+{
+ Assert(m_popup);
+}
+
+CtrlPopup::~CtrlPopup()
+{
+}
+
+void CtrlPopup::EmitAnswer(const AnswerCallbackData & answer)
+{
+ AnswerCallbackData l_answer = answer;
+ l_answer.loopHandle = m_loopHandle;
+ PopupAnswerEvent event(SharedFromThis(), m_callback, l_answer);
+ DPL::Event::EventSupport<PopupAnswerEvent>::EmitEvent(event);
+}
+
+PopupController::PopupController() : m_canvas(NULL)
+{
+}
+
+CtrlPopupPtr PopupController::CreatePopup() const
+{
+ return CtrlPopupPtr(
+ new CtrlPopup(PopupManagerSingleton::Instance().CreatePopup()));
+}
+
+void PopupController::OnEventReceived(const ShowPopupEvent& event)
+{
+ CtrlPopupPtr popup = event.GetArg0();
+ popup->m_callback = event.GetArg1();
+ popup->m_loopHandle = event.GetArg2();
+
+ //pass canvas from controller to manager
+ //canvas is not passed earlier because value wasn't set properly
+ PopupManagerSingleton::Instance().setExternalCanvas(getExternalCanvas());
+
+ PopupManagerSingleton::Instance().RunAsyncWithArgType(
+ popup->m_popup,
+ &PopupController::StaticOnAnswerReceived,
+ new CtrlPopupPtr(popup));
+}
+
+void PopupController::StaticOnAnswerReceived(const AnswerCallbackData & answer,
+ CtrlPopupPtr* popup)
+{
+ Assert(popup != NULL);
+ (*popup)->EmitAnswer(answer);
+ delete popup; // Just SharedPtr is destroyed, not the popup itself
+}
+
+void PopupControllerUser::OnEventReceived(const PopupAnswerEvent& event)
+{
+ //Here we are in a proper context to call the callback
+ PopupAnswerCallback answerCall = event.GetArg1();
+ AnswerCallbackData answer = event.GetArg2();
+ answerCall.Call(answer);
+ event.GetArg0()->DPL::Event::EventSupport<PopupAnswerEvent>::RemoveListener(this);
+}
+
+void PopupControllerUser::ListenForAnswer(CtrlPopupPtr popup)
+{
+ popup->DPL::Event::EventSupport<PopupAnswerEvent>::AddListener(this);
+}
+} //namespace Popup
+} //namespace DPL
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file popup_manager.cpp
+ * @author Lukasz Wrzosek (l.wrzosek@samsung.com)
+ * @version 1.0
+ * @brief This is popup_manager implementation file
+ */
+
+#include <dpl/popup/popup_manager.h>
+#include <dpl/popup/popup.h>
+
+#include <dpl/log/log.h>
+#include <dpl/shared_ptr.h>
+#include <dpl/assert.h>
+#include <dpl/singleton_impl.h>
+
+IMPLEMENT_SINGLETON(DPL::Popup::PopupManager)
+
+namespace DPL {
+namespace Popup {
+
+void PopupManager::Initialize(PopupRendererPtr renderer)
+{
+ Assert(!m_initialized);
+ m_popupRenderer = renderer;
+ m_popupRenderer->Initialize();
+ m_initialized = true;
+}
+
+void PopupManager::Deinitialize()
+{
+ m_popupRenderer->Deinitialize();
+ Assert(m_initialized);
+ m_popupRenderer.Reset();
+ m_initialized = false;
+}
+
+IPopupPtr PopupManager::CreatePopup()
+{
+ Assert(m_initialized);
+ return m_popupRenderer->CreatePopup();
+}
+
+} // namespace Popup
+} // namespace DPL
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file popup_renderer.cpp
+ * @author Lukasz Wrzosek (l.wrzosek@samsung.com)
+ * @version 1.0
+ * @brief This is efl specific implementation for PopupRenderer
+ */
+
+#include <dpl/popup/popup_manager.h>
+#include <dpl/popup/popup_renderer.h>
+#include <dpl/popup/popup_manager.h>
+#include <dpl/popup/evas_object.h>
+#include <dpl/shared_ptr.h>
+#include <dpl/scoped_array.h>
+#include <dpl/assert.h>
+#include <dpl/log/log.h>
+#include <dpl/foreach.h>
+#include <dpl/framework_efl.h>
+#include <dpl/lexical_cast.h>
+#include <queue>
+
+namespace DPL {
+
+namespace {
+using namespace Popup;
+const char* EDJ_NAME = "/usr/share/edje/ace/generic_popup.edj";
+const char* POPUP_LAYOUT1 = "popup_layout1";
+const char* POPUP_LAYOUT2 = "popup_layout2";
+const char* BUTTON_RESPONSE_CALLBACK_NAME = "response";
+const char* CHANGED_CALLBACK_NAME = "changed";
+const unsigned int MAX_NUMBER_OF_VERTICAL = 2;
+
+Evas_Object* create_layout_main(Evas_Object* parent, int totalV)
+{
+ Evas_Object *layout = elm_layout_add(parent);
+
+ if (totalV == 1) {
+ elm_layout_file_set(layout, EDJ_NAME, POPUP_LAYOUT1);
+ } else if (totalV == 2) {
+ elm_layout_file_set(layout, EDJ_NAME, POPUP_LAYOUT2);
+ } else {
+ Assert("popup needs define new group in the edc");
+ }
+
+ evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND,
+ EVAS_HINT_EXPAND);
+ return layout;
+}
+} //namespace
+
+namespace Popup {
+class PopupRenderer::Impl
+{
+ public:
+ Impl() :
+ m_popupsToRender(),
+ m_current(),
+ m_initialized(false)
+ {
+ }
+
+ ~Impl()
+ {
+ Assert(!m_initialized);
+ }
+
+ void Initialize()
+ {
+ Assert(!m_initialized);
+ m_initialized = true;
+ }
+
+ void Deinitialize()
+ {
+ Assert(m_initialized);
+ m_current.Reset(NULL);
+ while (!m_popupsToRender.empty()) {
+ m_popupsToRender.pop();
+ }
+ m_initialized = false;
+ }
+
+ void ButtonCallback(EvasObject::IConnection* /*connection*/,
+ void* event_info,
+ void* /*unused*/)
+ {
+ LogInfo("ButtonCallback");
+ Assert(m_initialized);
+ AnswerCallbackData answerData;
+
+ answerData.buttonAnswer = int(event_info);
+ answerData.chackState = m_checkState;
+ answerData.password = m_password;
+ m_current->ForwardAnswer(answerData);
+ m_current.Reset();
+
+ FOREACH(it, m_createdObjects)
+ {
+ if (it->IsValid()) {
+ evas_object_del(*it);
+ }
+ }
+ m_createdObjects.clear();
+ m_checkState = false;
+ DoRender();
+ }
+
+ void CheckCallback(EvasObject::IConnection* connection,
+ void* /*event_info*/,
+ void* /* unused */)
+ {
+ m_checkState =
+ elm_check_state_get(connection->GetEvasObject());
+ }
+
+ void Render (PopupPtr popup)
+ {
+ Assert(m_initialized);
+ m_popupsToRender.push(popup);
+ DoRender();
+ }
+
+ void DoRender(const PopupObject::Label& object,
+ EvasObject& parent,
+ EvasObject& layout,
+ int themeIndex)
+ {
+ EvasObject label(elm_label_add(parent));
+
+ elm_object_style_set(label, "popup_description/default");
+ elm_label_line_wrap_set(label, ELM_WRAP_WORD);
+ elm_object_text_set(label, object.getLabel().c_str());
+ evas_object_size_hint_weight_set(label, EVAS_HINT_EXPAND, 0.0);
+ evas_object_size_hint_align_set(label, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_object_show(label);
+
+ elm_layout_content_set(
+ layout,
+ DPL::lexical_cast<std::string>(themeIndex).c_str(),
+ label);
+ m_createdObjects.push_back(label);
+ }
+
+ void DoRender(const PopupObject::Check& object,
+ EvasObject& parent,
+ EvasObject& layout,
+ int themeIndex)
+ {
+ EvasObject check(elm_check_add(parent));
+
+ evas_object_size_hint_align_set(check, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_object_size_hint_weight_set(check, EVAS_HINT_EXPAND, 0.0);
+ elm_object_text_set(check,
+ object.getCheckLabel().c_str());
+ elm_layout_content_set(
+ layout,
+ DPL::lexical_cast<std::string>(themeIndex).c_str(),
+ check);
+
+ check.ConnectMemberSmartCallback(CHANGED_CALLBACK_NAME,
+ &Impl::CheckCallback,
+ this,
+ static_cast<void*>(NULL));
+ evas_object_show(check);
+ m_createdObjects.push_back(check);
+ }
+
+ void DoRender(const PopupObject::Button& object,
+ EvasObject &parent)
+ {
+ elm_popup_buttons_add(parent,
+ 1,
+ object.getLabel().c_str(),
+ object.getLabelId(),
+ NULL);
+ parent.ConnectMemberSmartCallback(
+ BUTTON_RESPONSE_CALLBACK_NAME,
+ &Impl::ButtonCallback,
+ this,
+ static_cast<void*>(NULL));
+ }
+
+ void DoRender(const PopupObject::Button& object1,
+ const PopupObject::Button& object2,
+ EvasObject &parent)
+ {
+ elm_popup_buttons_add(parent,
+ 2,
+ object1.getLabel().c_str(),
+ object1.getLabelId(),
+ object2.getLabel().c_str(),
+ object2.getLabelId(),
+ NULL);
+ parent.ConnectMemberSmartCallback(
+ BUTTON_RESPONSE_CALLBACK_NAME,
+ &Impl::ButtonCallback,
+ this,
+ static_cast<void*>(NULL));
+ }
+
+ void DoRender(const PopupObject::Button& object1,
+ const PopupObject::Button& object2,
+ const PopupObject::Button& object3,
+ EvasObject &parent)
+ {
+ elm_popup_buttons_add(parent,
+ 3,
+ object1.getLabel().c_str(),
+ object1.getLabelId(),
+ object2.getLabel().c_str(),
+ object2.getLabelId(),
+ object3.getLabel().c_str(),
+ object3.getLabelId(),
+ NULL);
+ parent.ConnectMemberSmartCallback(
+ BUTTON_RESPONSE_CALLBACK_NAME,
+ &Impl::ButtonCallback,
+ this,
+ static_cast<void*>(NULL));
+ }
+
+ EvasObject getBaseObject()
+ {
+ if (getExternalCanvas() == NULL) {
+ LogInfo("Create old style popup");
+ EvasObject win(elm_win_add(NULL, "Popup", ELM_WIN_DIALOG_BASIC));
+ elm_win_borderless_set(win, EINA_TRUE);
+ elm_win_alpha_set(win, EINA_TRUE);
+ elm_win_raise(win);
+ {
+ int w, h, x, y;
+ ecore_x_window_geometry_get(ecore_x_window_root_first_get(),
+ &x,
+ &y,
+ &w,
+ &h);
+ evas_object_resize(win, w, h);
+ evas_object_move(win, x, y);
+ }
+ m_createdObjects.push_back(win);
+ evas_object_show(win);
+ return win;
+ } else {
+ LogInfo("Create new style popup");
+ EvasObject win(getExternalCanvas());
+ evas_object_show(win);
+ return win;
+ }
+ }
+
+ void DoRender()
+ {
+ if (!m_current && !m_popupsToRender.empty()) {
+ m_current = m_popupsToRender.front();
+ m_popupsToRender.pop();
+
+ m_themeIndexV = 0;
+
+ // preprocessing
+ std::vector<int> countPopupObjects = {0 /* PopupObject::BUTTON */,
+ 0 /* PopupObject::LABEL */,
+ 0 /* PopupObject::CHECK */};
+ FOREACH(it, m_current->GetPopupObjects()) {
+ Assert((*it)->getType() < countPopupObjects.size() &&
+ "Wrong PopupObject assigned");
+ countPopupObjects[(*it)->getType()]++;
+ }
+ int needsIndexV = countPopupObjects[PopupObject::LABEL] +
+ countPopupObjects[PopupObject::CHECK];
+
+ EvasObject win = getBaseObject();
+ EvasObject main(elm_popup_add(win));
+
+ evas_object_size_hint_weight_set(main,
+ EVAS_HINT_EXPAND,
+ EVAS_HINT_EXPAND);
+ elm_popup_title_label_set(main,
+ m_current->GetTitle().c_str());
+
+ m_createdObjects.push_back(main);
+ std::vector<PopupObject::Button> buttonObjectList;
+ EvasObject layout(create_layout_main(main, needsIndexV));
+ m_createdObjects.push_back(layout);
+
+ FOREACH(it, m_current->GetPopupObjects()) {
+ switch ((*it)->getType()) {
+ case PopupObject::BUTTON:
+ buttonObjectList.push_back(*(*it)->asButton());
+ break;
+ case PopupObject::LABEL:
+ DoRender(*(*it)->asLabel(),
+ main,
+ layout,
+ m_themeIndexV++);
+ break;
+ case PopupObject::CHECK:
+ DoRender(*(*it)->asCheck(),
+ main,
+ layout,
+ m_themeIndexV++);
+ break;
+ default:
+ Assert("incorrect type");
+ }
+ Assert(m_themeIndexV <= MAX_NUMBER_OF_VERTICAL);
+ }
+ elm_popup_content_set(main,
+ layout);
+
+ // show buution
+ switch(buttonObjectList.size()) {
+ case 0:
+ LogInfo("no button");
+ break;
+ case 1:
+ DoRender(buttonObjectList.at(0),
+ main);
+ break;
+ case 2:
+ DoRender(buttonObjectList.at(0),
+ buttonObjectList.at(1),
+ main);
+ break;
+ case 3:
+ DoRender(buttonObjectList.at(0),
+ buttonObjectList.at(1),
+ buttonObjectList.at(2),
+ main);
+ break;
+ default:
+ Assert("incorrect button number");
+ break;
+ }
+
+ evas_object_show(main);
+ }
+ }
+
+ void setExternalCanvas(void* externalCanvas)
+ {
+ m_externalCanvas = static_cast<Evas_Object*>(externalCanvas);
+ }
+
+ Evas_Object* getExternalCanvas() const
+ {
+ return m_externalCanvas;
+ }
+
+ std::queue<PopupPtr> m_popupsToRender;
+ std::list<EvasObject> m_createdObjects;
+ PopupPtr m_current;
+ bool m_initialized;
+ bool m_checkState;
+ DPL::Optional<std::string> m_password;
+ unsigned int m_themeIndexV;
+
+ private:
+ Evas_Object* m_externalCanvas;
+};
+
+PopupRenderer::PopupRenderer()
+{
+ m_impl = new PopupRenderer::Impl();
+}
+
+PopupRenderer::~PopupRenderer()
+{
+ delete m_impl;
+}
+
+void PopupRenderer::Initialize()
+{
+ Assert(m_impl);
+ m_impl->Initialize();
+}
+
+void PopupRenderer::Deinitialize()
+{
+ Assert(m_impl);
+ m_impl->Deinitialize();
+}
+
+IPopupPtr PopupRenderer::CreatePopup()
+{
+ return DPL::StaticPointerCast<IPopup>(IPopupPtr
+ (new Popup(SharedFromThis())));
+}
+
+void PopupRenderer::Render(PopupPtr popup)
+{
+ m_impl->Render(popup);
+}
+
+void PopupRenderer::setExternalCanvas(void* externalCanvas)
+{
+ m_impl->setExternalCanvas(externalCanvas);
+}
+
+} // namespace Popup
+} // namespace DPL
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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
+)
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <dpl/scoped_ptr.h>
+
+namespace DPL
+{
+namespace RPC
+{
+
+class GenericRPCConnection
+ : public AbstractRPCConnection,
+ private DPL::Socket::WaitableInputOutputExecutionContextSupport
+{
+private:
+ // WaitableInputOutputExecutionContextSupport
+ virtual void OnInputStreamRead();
+ virtual void OnInputStreamClosed();
+ virtual void OnInputStreamBroken();
+
+ ScopedPtr<AbstractWaitableInputOutput> m_inputOutput;
+
+public:
+ /**
+ * Costructor
+ *
+ * Abstract waitable input/outobject is acquired by class and destroyed upon desctructor
+ */
+ explicit GenericRPCConnection(AbstractWaitableInputOutput *inputOutput);
+ virtual ~GenericRPCConnection();
+
+ virtual void AsyncCall(const RPCFunction &function);
+ virtual void Ping();
+};
+
+}
+} // namespace DPL
+
+#endif // DPL_GENERIC_RPC_CONNECTION_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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.
+//
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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.
+//
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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.
+//
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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.
+//
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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.
+//
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <dpl/rpc/unix_socket_rpc_connection.h>
+
+namespace DPL
+{
+namespace RPC
+{
+UnixSocketRPCConnection::UnixSocketRPCConnection(DPL::Socket::UnixSocket *socket)
+ : GenericSocketRPCConnection<DPL::Socket::UnixSocket>(socket)
+{
+}
+}
+} // namespace DPL
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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
+)
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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.
+//
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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>
+
+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);
+ sockAddress->sun_path[sizeof(sockAddress->sun_path) - 1] = '\0'; // Prevent buffer overflows
+
+ // 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
+ chmod(address.GetAddress().c_str(), 0777);
+}
+
+}
+} // namespace DPL
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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
+ 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
+ PARENT_SCOPE
+)
+
+SET(DPL_TEST_ENGINE_INCLUDE_DIR
+ ${PROJECT_SOURCE_DIR}/modules/test/include
+ PARENT_SCOPE
+)
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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/shared_ptr.h>
+#include <dpl/noncopyable.h>
+#include <vector>
+#include <list>
+#include <map>
+#include <string>
+
+namespace DPL
+{
+namespace Test
+{
+
+class TestResultsCollectorBase;
+typedef DPL::SharedPtr<TestResultsCollectorBase>
+ TestResultsCollectorBasePtr;
+
+class TestResultsCollectorBase
+ : private DPL::Noncopyable
+{
+ public:
+ typedef TestResultsCollectorBase* (*CollectorConstructorFunc)();
+ typedef std::list<std::string> TestCaseIdList;
+ struct FailStatus
+ {
+ enum Type
+ {
+ NONE,
+ FAILED,
+ IGNORED,
+ TODO,
+ INTERNAL
+ };
+ };
+
+ virtual ~TestResultsCollectorBase() {}
+
+ virtual bool Configure() { return true; }
+ virtual void Start() { }
+ 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 */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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/unused.h>
+#include <dpl/atomic.h>
+#include <dpl/test/test_results_collector.h>
+#include <sstream>
+#include <string>
+#include <vector>
+#include <list>
+#include <set>
+
+namespace DPL
+{
+namespace Test
+{
+class TestRunner
+{
+ TestResultsCollectorBasePtr m_collector;
+ std::string m_collectorName;
+ std::string m_startTestId;
+
+public:
+ 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;
+
+ void Banner();
+ void InvalidArgs();
+ void Usage();
+
+ enum Status { FAILED, TODO, IGNORED, PASS };
+
+ Status RunTestCase(const TestCaseStruct& testCase);
+
+ void RunTests();
+
+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);
+
+ std::string GetMessage() const
+ {
+ return m_message;
+ }
+ };
+
+ class ToDo
+ {
+ private:
+ std::string m_message;
+
+ public:
+ ToDo()
+ {
+ }
+
+ ToDo(const std::string &message)
+ : m_message(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);
+};
+
+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()
+
+//! \brief Returns base name for path
+
+#define RUNNER_ASSERT_MSG(test, message) \
+do \
+{ \
+ DPL::Test::TestRunnerSingleton::Instance().MarkAssertion(); \
+ \
+ if (!(test)) \
+ { \
+ std::ostringstream assertMsg; \
+ assertMsg << message; \
+ throw DPL::Test::TestRunner::TestFailed(#test, __FILE__, __LINE__, assertMsg.str()); \
+ } \
+} while (0)
+
+#define RUNNER_ASSERT(test) RUNNER_ASSERT_MSG(test, "")
+
+#define RUNNER_FAIL RUNNER_ASSERT(false)
+
+#define RUNNER_TODO_MSG(message) do { std::ostringstream assertMsg; assertMsg << message; throw DPL::Test::TestRunner::ToDo(assertMsg.str()); } while (0)
+
+#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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <dpl/test/test_results_collector.h>
+#include <dpl/colors.h>
+#include <dpl/assert.h>
+#include <dpl/foreach.h>
+#include <dpl/scoped_fclose.h>
+
+#include <string>
+#include <cstdio>
+
+namespace DPL
+{
+namespace Test
+{
+
+namespace
+{
+const char *DEFAULT_HTML_FILE_NAME = "index.html";
+
+class Statistic
+{
+ public:
+ Statistic() :
+ m_failed(0),
+ m_ignored(0),
+ m_todo(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::TODO: ++m_todo; break;
+ case TestResultsCollectorBase::FailStatus::NONE: ++m_passed; break;
+ default:
+ Assert(false && "Bad FailStatus");
+ }
+ }
+
+ size_t GetTotal() const { return m_count; }
+ size_t GetPassed() const { return m_passed; }
+ size_t GetSuccesed() const { return m_passed; }
+ size_t GetFailed() const { return m_failed; }
+ size_t GetTODO() const { return m_todo; }
+ 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:
+ size_t m_failed;
+ size_t m_ignored;
+ size_t m_todo;
+ size_t m_passed;
+ 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("[%s%s%s]\n", BOLD_GREEN_BEGIN, " OK ", BOLD_GREEN_END); break;
+ case TestResultsCollectorBase::FailStatus::FAILED:
+ PrintfErrorMessage( " FAILED ", reason, true); break;
+ case TestResultsCollectorBase::FailStatus::IGNORED:
+ PrintfIgnoredMessage("Ignored ", reason, true); break;
+ case TestResultsCollectorBase::FailStatus::TODO:
+ PrintfTODOMessage( " TODO ", 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 PrintfTODOMessage(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_WHITE_BEGIN,
+ type,
+ BOLD_WHITE_END,
+ BOLD_GOLD_BEGIN,
+ message.c_str(),
+ BOLD_GOLD_END);
+ } else {
+ printf("[%s%s%s]\n",
+ BOLD_WHITE_BEGIN,
+ type,
+ BOLD_WHITE_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 or ignored: ", stats.GetPassed() + stats.GetIgnored(), CYAN_END);
+ printf(" %s%s%3d%s\n", CYAN_BEGIN, "Succeeded: ", stats.GetPassed(), CYAN_END);
+ printf(" %s%s%3d%s\n", CYAN_BEGIN, "Ignored: ", stats.GetIgnored(), CYAN_END);
+ printf("%s%s%3d%s\n", CYAN_BEGIN, "Failed: ", stats.GetFailed(), CYAN_END);
+ printf("%s%s%3d%s\n", CYAN_BEGIN, "Todo: ", stats.GetTODO(), CYAN_END);
+ printf("%s%s%3.0f%%%s\n", CYAN_BEGIN, "Succeeded or ignored %: ", stats.GetPassedOrIgnoredPercend(), 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()
+ {
+ Assert(!!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)
+ {
+ const std::string argname = "--file=";
+ if (0 == arg.find(argname)) {
+ m_filename = arg.substr(argname.size());
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ 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(), "[%s%s%s]\n", BOLD_GREEN_BEGIN, " OK ", BOLD_GREEN_END); break;
+ case TestResultsCollectorBase::FailStatus::FAILED:
+ PrintfErrorMessage( " FAILED ", reason, true); break;
+ case TestResultsCollectorBase::FailStatus::IGNORED:
+ PrintfIgnoredMessage("Ignored ", reason, true); break;
+ case TestResultsCollectorBase::FailStatus::TODO:
+ PrintfTODOMessage( " TODO ", 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 PrintfTODOMessage(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_WHITE_BEGIN,
+ type,
+ BOLD_WHITE_END,
+ BOLD_GOLD_BEGIN,
+ message.c_str(),
+ BOLD_GOLD_END);
+ } else {
+ fprintf(m_fp.Get(),
+ "[%s%s%s]\n",
+ BOLD_WHITE_BEGIN,
+ type,
+ BOLD_WHITE_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 or ignored: ", stats.GetPassed() + stats.GetIgnored(), 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, "Ignored: ", stats.GetIgnored(), 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, "Todo: ", stats.GetTODO(), CYAN_END);
+ fprintf(m_fp.Get(), "%s%s%3.0f%%%s\n", CYAN_BEGIN, "Succeeded or ignored %: ", stats.GetPassedOrIgnoredPercend(), 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 CSVCollector
+ : public TestResultsCollectorBase
+{
+ public:
+ static TestResultsCollectorBase* Constructor();
+
+ private:
+ CSVCollector() {}
+
+ virtual void Start() {
+ 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::TODO: statusMsg = "TODO"; 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();
+}
+
+}
+
+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);
+
+ return 0;
+}
+
+}
+
+}
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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 <dpl/singleton_impl.h>
+IMPLEMENT_SINGLETON(DPL::Test::TestRunner)
+
+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();
+}
+
+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;
+}
+
+
+TestRunner::Status TestRunner::RunTestCase(const TestCaseStruct& testCase)
+{
+ try
+ {
+ testCase.proc();
+ }
+ catch (const TestFailed &e)
+ {
+ // Simple test failure
+ m_collector->CollectResult(testCase.name,
+ "",
+ TestResultsCollectorBase::FailStatus::FAILED,
+ e.GetMessage());
+ return FAILED;
+ }
+ catch (const Ignored &e)
+ {
+ // Simple test have to be implemented
+ m_collector->CollectResult(testCase.name,
+ "",
+ TestResultsCollectorBase::FailStatus::IGNORED,
+ e.GetMessage());
+
+ return IGNORED;
+ }
+ catch (const ToDo &e)
+ {
+ // Simple test have to be implemented
+ m_collector->CollectResult(testCase.name,
+ "",
+ TestResultsCollectorBase::FailStatus::TODO,
+ e.GetMessage());
+
+ return TODO;
+ }
+ catch (const DPL::Exception &e)
+ {
+ // DPL exception failure
+ m_collector->CollectResult(testCase.name,
+ "",
+ TestResultsCollectorBase::FailStatus::INTERNAL,
+ "DPL exception:" +
+ e.GetMessage());
+
+ return FAILED;
+ }
+ catch (const std::exception &)
+ {
+ // std exception failure
+ m_collector->CollectResult(testCase.name,
+ "",
+ TestResultsCollectorBase::FailStatus::INTERNAL,
+ "std exception");
+
+ return FAILED;
+ }
+ catch (...)
+ {
+ // Unknown exception failure
+ m_collector->CollectResult(testCase.name,
+ "",
+ TestResultsCollectorBase::FailStatus::INTERNAL,
+ "unknown exception");
+
+ return FAILED;
+ }
+
+ m_collector->CollectResult(testCase.name,
+ "",
+ TestResultsCollectorBase::FailStatus::NONE);
+ // Everything OK
+ return PASS;
+}
+
+void TestRunner::RunTests()
+{
+ using namespace DPL::Colors::Text;
+
+ Banner();
+ m_collector->Start();
+
+ fprintf(stderr, "%s%s%s\n", GREEN_BEGIN, "Running tests...", GREEN_END);
+ FOREACH(group, m_testGroups) {
+ TestCaseStructList list = group->second;
+ if (!list.empty()) {
+ m_collector->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);
+ }
+ }
+ }
+ }
+
+ m_collector->Finish();
+ // Finished
+ fprintf(stderr, "%s%s%s\n\n", GREEN_BEGIN, "Finished", GREEN_END);
+}
+
+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()
+{
+ using namespace DPL::Colors::Text;
+ fprintf(stderr,
+ "%s%s%s\n",
+ BOLD_RED_BEGIN,
+ "Invalid parameters!",
+ BOLD_RED_END);
+}
+
+void TestRunner::Usage()
+{
+ fprintf(stderr, "Usage: runner [options]\n\n");
+ fprintf(stderr, "Output type:\n");
+ fprintf(stderr, " --output=<output type>\n");
+ fprintf(stderr, " possible output types:\n");
+ FOREACH (type, TestResultsCollectorBase::GetCollectorsNames()) {
+ fprintf(stderr, " --output=%s\n", type->c_str());
+ }
+ 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, " --list\t Show a list of Test IDs\n");
+ fprintf(stderr, " --listgroups\t Show a list of Test Group names \n");
+ fprintf(stderr, " --listingroup=<group name>\t Show a list of Test IDS in one group\n");
+ fprintf(stderr, " --help\t This help\n\n");
+ if (m_collector) {
+ fprintf(stderr, "Output %s has specific args:\n", m_collectorName.c_str());
+ fprintf(stderr, "%s\n", m_collector->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)
+{
+ ArgsList args = value;
+ // Parse command line
+ if (args.size() == 1)
+ {
+ InvalidArgs();
+ Usage();
+ return -1;
+ }
+
+ args.erase(args.begin());
+
+ bool showHelp = false;
+
+ // 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 listCmd = "--list";
+ const std::string startCmd = "--start=";
+ const std::string listGroupsCmd = "--listgroups";
+ const std::string listInGroup = "--listingroup=";
+
+ if (m_collector && m_collector->ParseCollectorSpecificArg(arg)) continue;
+ else 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 == listCmd)
+ {
+ FOREACH(group, m_testGroups) {
+ FOREACH(test, group->second) {
+ printf("ID:%s:%s\n", group->first.c_str(), test->name.c_str());
+ }
+ }
+ return 0;
+ }
+ 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 == "--help")
+ showHelp = true;
+ else if (arg.find(output) == 0)
+ {
+ arg.erase(0, output.length());
+ m_collector.Reset(TestResultsCollectorBase::Create(arg));
+ if (!m_collector) {
+ InvalidArgs();
+ Usage();
+ return -1;
+ } else {
+ m_collectorName = arg;
+ }
+ }
+ 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
+ {
+ InvalidArgs();
+ Usage();
+ return -1;
+ }
+ }
+
+ // Show help
+ if (showHelp)
+ {
+ Usage();
+ return 0;
+ }
+
+ if (!m_collector)
+ m_collector.Reset(TestResultsCollectorBase::Create("text"));
+
+ if (!m_collector->Configure()) {
+ fprintf(stderr, "Could not configure selected output");
+ return 0;
+ }
+
+ // Run tests
+ RunTests();
+
+ return 0;
+}
+
+}
+} // namespace DPL
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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/file_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_internal.cpp
+ ${PROJECT_SOURCE_DIR}/modules/utils/src/wrt_global_settings.cpp
+ ${PROJECT_SOURCE_DIR}/modules/utils/src/wrt_utility.cpp
+ PARENT_SCOPE
+)
+
+
+SET(DPL_UTILS_HEADERS
+ ${PROJECT_SOURCE_DIR}/modules/utils/include/file_utils.h
+ ${PROJECT_SOURCE_DIR}/modules/utils/include/folder_size.h
+ ${PROJECT_SOURCE_DIR}/modules/utils/include/mime_type_utils.h
+ ${PROJECT_SOURCE_DIR}/modules/utils/include/warp_iri.h
+ ${PROJECT_SOURCE_DIR}/modules/utils/include/widget_version.h
+ ${PROJECT_SOURCE_DIR}/modules/utils/include/wrt_global_settings.h
+ ${PROJECT_SOURCE_DIR}/modules/utils/include/wrt_global_settings_internal.h
+ ${PROJECT_SOURCE_DIR}/modules/utils/include/wrt_utility.h
+ PARENT_SCOPE
+)
+
+SET(DPL_UTILS_INCLUDE_DIR
+ ${PROJECT_SOURCE_DIR}/modules/utils/include
+ PARENT_SCOPE
+)
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_utils.h
+ * @author Bartosz Janiak (b.janiak@samsung.com)
+ * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com)
+ * @version 1.0
+ */
+
+#ifndef FILEUTILS_H
+#define FILEUTILS_H
+
+#include <sys/types.h>
+#include <string>
+
+#include <dpl/string.h>
+#include <dpl/exception.h>
+
+namespace FileUtils {
+DECLARE_EXCEPTION_TYPE(DPL::Exception, RemoveDirectoryException)
+
+bool FileExists(const DPL::String& absolutePath);
+
+/**
+ * Creates specified path recursively.
+ * @param path Path to create (e.g. /tmp/dir1/dir2).
+ * @param mode Mode for the non-existing parts of the path (e.g. 0755).
+ * @throw DPL::CommonException::::InternalError If sth bad happens.
+ */
+void MakePath(const std::string& path,
+ mode_t mode);
+
+/**
+ * Removes specified directory recursively.
+ * @param path Full path to directory to remove.
+ * @throw FileUtils::DirectoryRemoveException If an error occured.
+ */
+void RemoveDir(const std::string& path);
+};
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 */
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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;
+ // KW bool isIRIValid() const;
+ bool getSubDomain() const;
+
+ /* This is debug function */
+ // KW void print() const {
+ // KW LogInfo("P:" << m_port << " S:" << m_schema);
+ // KW for (size_t i = 0; i < m_host.size(); ++i)
+ // KW LogInfo(" " << m_host[i]);
+ // KW }
+
+ 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_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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> µ,
+ 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> µ,
+ 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 {
+//TODO description
+bool GetPopupsEnabledFlag();
+}
+
+#endif /* WRT_COMMON_GLOBAL_SETTINGS_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_internal.h
+ * @version 0.6
+ * @author Lukasz Wrzosek (l.wrzosek@samsung.com)
+ * @brief Header file for global predefined wrt setting - internal interface
+ */
+
+#ifndef WRT_SRC_COMMON_WRT_GLOBAL_SETTINGS_INTERNAL_H_
+#define WRT_SRC_COMMON_WRT_GLOBAL_SETTINGS_INTERNAL_H_
+
+namespace GlobalSettings {
+struct IGlobalSettingsFunctions
+{
+ bool (*getPopupsEnabledFlag)();
+};
+
+void SetPredefinedGlobalSettings(IGlobalSettingsFunctions functions);
+}
+
+#endif //WRT_SRC_COMMON_WRT_GLOBAL_SETTINGS_INTERNAL_H_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.6
+ * @author Wei Dong(d.wei@samsung.com)
+ * @author Ma Quan(jason.ma@samsung.com)
+ * @brief Header file of widget manager common functions
+ */
+
+#ifndef _WRT_UTILITY_H_
+#define _WRT_UTILITY_H_
+
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#ifndef MAX_WIDGET_PATH_LENGTH
+#define MAX_WIDGET_PATH_LENGTH 1024
+#endif
+
+/**
+ * File options
+ */
+enum
+{
+ WRT_FILEUTILS_PRESERVE_STATUS = 1,
+ WRT_FILEUTILS_PRESERVE_SYMLINKS = 2,
+ WRT_FILEUTILS_RECUR = 4,
+ WRT_FILEUTILS_FORCE = 8,
+ WRT_FILEUTILS_INTERACTIVE = 16
+};
+
+/**
+ * Combine the parentPath and fileName into a new absolute file name.
+ *
+ * @param[out] absolutePath
+ * @param[in] parentPath
+ * @param[in] fileName
+ *
+ * @return if success, return true; or return false.
+ */
+bool _WrtUtilSetAbsolutePath(char* absolutePath,
+ const char* parentPath,
+ const char* fileName);
+
+/**
+ * Change the string to bool value,no case sensitive, e.x., "true" or "1" to ture; "False" or "0" to false.
+ *
+ * @param[in] value
+ * @param[out] result
+ *
+ * @return if success, return true; or return false.
+ */
+// KW bool _WrtUtilConvertStrToBool(char* value, bool *result);
+
+/**
+ * Get the dir path and file name from the full path. e.x., "/opt/lib/filename" as fullPath, "/opt/lib/" as dirName, "filename" as fileName.
+ * it's necessary to free *dirName or *fileName if either of them is not NULL.
+ *
+ * @param[in] fullPath
+ * @param[out] dirName
+ * @param[out] fileName
+ *
+ * @return
+ */
+void _WrtUtilGetDirAndFileName(const char* fullPath,
+ char** dirName,
+ char** fileName);
+
+#if 0
+/**
+ * Change the provided string into lower case, caller should allocate the memory of source and dest.
+ *
+ * @param[in] source the source string to be changed
+ * @param[out] dest the dest string with lower case
+ *
+ * return if success, return true, or return false.
+ */
+bool _WrtUtilStringToLower(const char* source,
+ char* dest);
+#endif
+
+/**
+ * Compare two string, no case sensitive.
+ *
+ * @param[in] srcStr
+ * @param[in] destStr
+ *
+ * return return true if the two strings are identical, or return false.
+ */
+// KW bool _WrtUtilStringCmp(const char* srcStr, const char* destStr);
+
+/**
+ * This function is used to make a directory.
+ * it's neccessary to free the returned dir path.
+ *
+ * @param[in] path Specified the directory path
+ * @param[in] mode Operation mode the you want to set
+ * @param[in] flags WRT_FILEUTILS_RECUR if you want to make parent's directory recusively,
+ * WRT_FILEUTILS_NONE if not.
+ *
+ * @return TRUE on success or FALSE on failure.
+ */
+bool _WrtMakeDir (const char *path,
+ long mode,
+ int flags);
+
+/**
+ * This function is used to change to specified directory.
+ * If the directory does not exist, it will create it directly.
+ *
+ * @param[in] path Specified the directory path
+ *
+ * @return TRUE on success or FALSE on failure.
+ */
+bool _WrtUtilChangeDir(const char* path);
+
+/**
+ * This function is used to remove a directory from the file system.
+ *
+ * @param[in] path Specified the directory path
+ *
+ * @return TRUE on success or FALSE on failure.
+ */
+bool _WrtUtilRemoveDir(const char* path);
+
+// KW /**
+// KW * This function is used to make a temp directory in root directory.
+// KW *
+// KW * @param[in] root Specified the root directory
+// KW *
+// KW * @return if fails, return NULL, else return the temp path.
+// KW * it's necessary to free the returned memory space.
+// KW */
+// KW char* _WrtUtilMakeTempDir(const char* root);
+
+/**
+ * This function is used to convert a string to lowercase.
+ *
+ * @param[in] str the string need to be converted.
+ * @param[in] lowerStr the converted string.
+ *
+ * @return TRUE on success or FALSE on failure.
+ */
+bool _WrtUtilStringToLower(const char* str,
+ char** lowerStr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //_WRT_UTILITY_H_
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_utils.cpp
+ * @author Bartosz Janiak (b.janiak@samsung.com)
+ * @version 1.0
+ */
+
+
+#include <sys/stat.h>
+#include <cerrno>
+#include <cstring>
+#include <cstdlib>
+#include <dirent.h>
+#include <unistd.h>
+
+#include <dpl/exception.h>
+#include <dpl/errno_string.h>
+#include <file_utils.h>
+
+#include <dpl/wrt-dao-ro/path_builder.h>
+
+namespace {
+int try_mkdir(const char* path,
+ mode_t mode)
+{
+ struct stat st;
+ int err = 0;
+
+ if (::stat(path, &st) != 0) {
+ if (::mkdir(path, mode) != 0) {
+ err = -1;
+ }
+ } else if (!S_ISDIR(st.st_mode)) {
+ errno = ENOTDIR;
+ err = -1;
+ }
+
+ return err;
+}
+
+int mkpath(const char* path,
+ mode_t mode)
+{
+ char* copy = ::strdup(path);
+ if (NULL == copy) {
+ return -1;
+ }
+
+ int err = 0;
+ char* ptr = copy;
+ char* slash = NULL;
+
+ while ((0 == err) && (NULL != (slash = ::strchr(ptr, '/')))) {
+ if (slash != ptr) {
+ *slash = '\0';
+ err = try_mkdir(copy, mode);
+ *slash = '/';
+ }
+ ptr = slash + 1;
+ }
+
+ if (0 == err) {
+ err = try_mkdir(path, mode);
+ }
+
+ ::free(copy);
+ return err;
+}
+
+int RmNode(const char* path);
+
+int RmDir(const char* path)
+{
+ DIR* dir = ::opendir(path);
+ if (NULL == dir) {
+ return -1;
+ }
+
+ struct dirent* entry = NULL;
+ do {
+ errno = 0;
+ if (NULL != (entry = ::readdir(dir))) {
+ if (!::strncmp(entry->d_name, ".", 1) ||
+ !::strncmp(entry->d_name, "..", 2)) {
+ continue;
+ }
+ std::string fullPath = WrtDB::PathBuilder(path)
+ .Append(entry->d_name)
+ .GetFullPath();
+ if (RmNode(fullPath.c_str()) != 0) {
+ int error = errno;
+ TEMP_FAILURE_RETRY(::closedir(dir));
+ errno = error;
+ return -1;
+ }
+ }
+ }
+ while (NULL != entry);
+
+ int error = errno;
+ if (TEMP_FAILURE_RETRY(::closedir(dir)) != 0) {
+ return -1;
+ }
+ errno = error;
+
+ return (errno == 0 ? ::rmdir(path) : -1);
+}
+
+int RmNode(const char* path)
+{
+ struct stat st;
+ if (::lstat(path, &st) != 0) {
+ return -1;
+ }
+ return (S_ISDIR(st.st_mode) ? RmDir(path) : ::unlink(path));
+}
+}
+
+namespace FileUtils {
+bool FileExists(const DPL::String& absolutePath)
+{
+ struct stat statStruct;
+ if (stat(DPL::ToUTF8String(absolutePath).c_str(), &statStruct) == 0) {
+ return S_ISREG(statStruct.st_mode);
+ } else {
+ return false;
+ }
+}
+
+void MakePath(const std::string& path,
+ mode_t mode)
+{
+ if (mkpath(path.c_str(), mode) == -1) {
+ ThrowMsg(DPL::CommonException::InternalError, "Cannot make path");
+ }
+}
+
+void RemoveDir(const std::string& path)
+{
+ if (RmDir(path.c_str()) != 0) {
+ ThrowMsg(RemoveDirectoryException, DPL::GetErrnoString());
+ }
+}
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <string.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <sstream>
+#include <vector>
+
+#include <dpl/log/log.h>
+#include <dpl/foreach.h>
+#include <folder_size.h>
+
+namespace Utils {
+namespace {
+
+size_t getObjectSize(const std::string& path)
+{
+ struct stat tmp;
+
+ if (stat(path.c_str(), &tmp) == -1) {
+ LogError("Failed to open file" << path);
+ return 0;
+ }
+ //it is not a file nor a directory
+ //not counting
+ if (!S_ISDIR(tmp.st_mode) && !S_ISREG(tmp.st_mode)) {
+ LogWarning("Not a regular file nor a directory: " << path);
+ return 0;
+ }
+ return tmp.st_size;
+}
+}
+
+size_t getFolderSize(const std::string& path)
+{
+ size_t size = 0;
+
+ DIR *dir;
+ std::vector<std::string> localDirs;
+ if ((dir=opendir(path.c_str())) == NULL) {
+ LogError("Cannot open dir " << path);
+ return 0;
+ }
+ struct dirent* el;
+ while ((el = readdir(dir)) != 0) {
+ if (strcmp(el->d_name, ".") == 0 || strcmp(el->d_name, "..") == 0) {
+ continue;
+ }
+ struct stat tmp;
+ std::string local = path + el->d_name;
+ if (stat(local.c_str(), &tmp) == -1) {
+ LogError("Failed to open file " << local);
+ char* errstring = strerror(errno);
+ LogError("Reason: " << errstring);
+ continue;
+ }
+
+ size += getObjectSize(local);
+ if (S_ISDIR(tmp.st_mode)) {
+ localDirs.push_back(local + "/");
+ }
+ }
+
+ closedir(dir);
+
+ FOREACH (localDir, localDirs) {
+ size += getFolderSize(*localDir);
+ }
+
+ 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 = Pre<Rest...>::value * stepSize;
+ 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;
+
+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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <set>
+#include <dpl/assert.h>
+#include <vector>
+
+#include <map>
+
+#include <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"));
+ }
+ 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;
+ }
+ }
+ }
+ //TODO step 10 - sniff
+ return DPL::FromASCIIString("application/sniff");
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <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://", "tel:", "sms:",
+ "mmsto:", "mailto:", "data:", "blob:", 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
+
+// This will create AutoPtr deleter for iri_struct.
+// Deleter must be in the same namespace as definition of AutoPtr.
+namespace ValidationCore {
+VC_DECLARE_DELETER(iri_struct, iri_destroy)
+}
+
+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;
+ }
+
+ ValidationCore::AutoPtr<iri_struct> iri(iri_parse(p_iri));
+
+ 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;
+ }
+ }
+
+ DPL::String str = DPL::FromASCIIString(std::string(iri->host));
+
+ 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;
+}
+
+// KW bool WarpIRI::isIRIValid() const {
+// KW return m_isIRIValid;
+// KW }
+
+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;
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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() && str[pos + 1] == LEADING_ZERO_CHAR) {
+ ++pos;
+ }
+
+ 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> µ,
+ 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;
+ m_raw += WAC_CERTIFY_MANDATORY_NUMBER_PART_SPLIT_CHAR;
+
+ if (!!micro) {
+ 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> µ,
+ 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)
+{
+ Assert(
+ 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)
+{
+ Assert(
+ left.IsWac() && right.IsWac() &&
+ "Only WAC version strings are comparable!");
+
+ return (left == right) || (left < right);
+}
+
+bool operator>(const WidgetVersion &left,
+ const WidgetVersion &right)
+{
+ Assert(
+ left.IsWac() && right.IsWac() &&
+ "Only WAC version strings are comparable!");
+
+ return !(left <= right);
+}
+
+bool operator>=(const WidgetVersion &left,
+ const WidgetVersion &right)
+{
+ Assert(
+ left.IsWac() && right.IsWac() &&
+ "Only WAC version strings are comparable!");
+
+ return (left == right) || (left > right);
+}
+
+bool operator==(const WidgetVersion &left,
+ const WidgetVersion &right)
+{
+ Assert(
+ left.IsWac() && right.IsWac() &&
+ "Only WAC version strings are comparable!");
+
+ return RemoveLeadingZeroes(left.Major()) ==
+ RemoveLeadingZeroes(right.Major()) && // Major are equal
+ RemoveLeadingZeroes(left.Minor()) ==
+ RemoveLeadingZeroes(right.Minor()) && // and Minor are equal
+ ( // and ...
+ (!!left.Micro() && !!right.Micro() &&
+ RemoveLeadingZeroes(*left.Micro()) ==
+ RemoveLeadingZeroes(*right.Micro())) || // Both Micro exist and are equal
+ (!left.Micro() && !right.Micro()) // or both Micro do not exist
+ );
+}
+
+bool operator!=(const WidgetVersion &left,
+ const WidgetVersion &right)
+{
+ Assert(
+ 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;
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <dpl/assert.h>
+#include <dpl/log/log.h>
+#include <string.h>
+#include <stdlib.h>
+#include <wrt_global_settings_internal.h>
+
+namespace {
+bool GetPopupsEnabledFlag()
+{
+ //TODO : env var. will be removed after UX guide for POWDER is enabled.
+ const char *env = getenv("WRT_POPUP_ENABLE");
+ if (env && 0 == strcmp(env, "1")) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+static bool initializeGlobalSettings();
+
+static bool initHelper = initializeGlobalSettings();
+
+bool initializeGlobalSettings()
+{
+ (void)initHelper;
+ LogDebug("Initializing globall settings");
+ GlobalSettings::IGlobalSettingsFunctions functions;
+ functions.getPopupsEnabledFlag = &GetPopupsEnabledFlag;
+ GlobalSettings::SetPredefinedGlobalSettings(functions);
+ return false;
+}
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_internal.cpp
+ * @version 0.6
+ * @author Lukasz Wrzosek (l.wrzosek@samsung.com)
+ */
+
+#include <wrt_global_settings.h>
+#include <wrt_global_settings_internal.h>
+#include <dpl/assert.h>
+#include <dpl/log/log.h>
+
+namespace GlobalSettings {
+static IGlobalSettingsFunctions globalSettingsFunctions;
+
+// INTERNAL
+void SetPredefinedGlobalSettings(IGlobalSettingsFunctions functions)
+{
+ globalSettingsFunctions = functions;
+ LogDebug("Global settings are set");
+}
+
+// PUBLIC
+bool GetPopupsEnabledFlag()
+{
+ Assert(globalSettingsFunctions.getPopupsEnabledFlag &&
+ "Global settings are unset");
+ return globalSettingsFunctions.getPopupsEnabledFlag();
+}
+} //namespace GlobalSettings
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.6
+ * @author Wei Dong(d.wei@samsung.com)
+ * @author Ma Quan(jason.ma@samsung.com)
+ * @brief This file implemented some common functions for widget manager
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <libgen.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dpl/log/log.h>
+#include <wrt_utility.h>
+
+using namespace std;
+
+bool _WrtUtilSetAbsolutePath(char* absolutePath,
+ const char* parentPath,
+ const char* fileName)
+{
+ int len;
+ if (NULL == absolutePath || NULL == parentPath || NULL == fileName) {
+ return false;
+ }
+ len = strlen(parentPath);
+ if (len > 0) {
+ // not check the valid of parentPath and fileName.
+ if (parentPath[len - 1] == '/') {
+ snprintf(absolutePath,
+ MAX_WIDGET_PATH_LENGTH,
+ "%s%s",
+ parentPath,
+ fileName);
+ } else {
+ snprintf(absolutePath,
+ MAX_WIDGET_PATH_LENGTH,
+ "%s/%s",
+ parentPath,
+ fileName);
+ }
+ } else {
+ LogDebug("The parent path is null");
+ return false;
+ }
+
+ //some widget use Windows notation. We need to change '\' to '/'
+ for (int i = 0; absolutePath[i] != 0; ++i) {
+ if (absolutePath[i] == '\\') {
+ absolutePath[i] = '/';
+ }
+ }
+
+ return true;
+}
+
+// KW bool _WrtUtilConvertStrToBool(char* value, bool *result)
+// KW {
+// KW bool ret = false;
+// KW if (NULL == value || NULL == result)
+// KW {
+// KW return ret;
+// KW }
+// KW
+// KW char* source = value;
+// KW char* changed = (char*)malloc(strlen(value) + 1);
+// KW if (NULL == changed)
+// KW {
+// KW return ret;
+// KW }
+// KW memset(changed, 0, strlen(value) + 1);
+// KW
+// KW char* cur = changed;
+// KW while(*source)
+// KW {
+// KW *cur++ = tolower(*source++);
+// KW }
+// KW if (!strcmp(changed,"false") || !strcmp(changed,"0"))
+// KW {
+// KW *result = false;
+// KW ret = true;
+// KW }
+// KW else if(!strcmp(changed,"true") || !strcmp(changed,"1"))
+// KW {
+// KW *result = true;
+// KW ret = true;
+// KW }
+// KW free(changed);
+// KW
+// KW return ret;
+// KW }
+
+void _WrtUtilGetDirAndFileName(const char* fullPath,
+ char** dirName,
+ char** fileName)
+{
+ int length = 0;
+ int index = 0;
+ if (NULL == fullPath || (NULL == dirName && NULL == fileName)) {
+ return;
+ }
+
+ length = strlen(fullPath);
+ for (index = length - 1; index >= 0; index--) {
+ if ('/' == fullPath[index]) {
+ if (index == length - 1) {
+ LogDebug(" Warning: The end of directroy is '/'! ");
+ if (dirName) {
+ *dirName = (char*)malloc(sizeof(char) * (length + 1));
+ if (*dirName != NULL) {
+ memset(*dirName, 0, sizeof(char) * (length + 1));
+ strncpy(*dirName, fullPath, length);
+ }
+ }
+ return;
+ }
+ break;
+ }
+ }
+ if (index >= 0) {
+ if (dirName) {
+ int dirName_len = index + 2;
+
+ *dirName = (char*)malloc(sizeof(char) * dirName_len);
+ if (*dirName != NULL) {
+ memset(*dirName, 0, sizeof(char) * dirName_len);
+ strncpy(*dirName, fullPath, dirName_len - 1);
+ }
+ }
+
+ if (fileName) {
+ int fileName_len = length - index;
+
+ *fileName = (char*)malloc(sizeof(char) * fileName_len);
+ if (*fileName != NULL) {
+ memset(*fileName, 0, sizeof(char) * fileName_len);
+ strncpy(*fileName, &fullPath[index + 1], fileName_len - 1);
+ }
+ }
+ } else {
+ if (fileName) {
+ *fileName = (char*)malloc(sizeof(char) * (length + 1));
+ if (*fileName != NULL) {
+ memset(*fileName, 0, sizeof(char) * (length + 1));
+ strncpy(*fileName, fullPath, length);
+ }
+ }
+ }
+}
+
+// KW bool _WrtUtilStringCmp(const char* srcStr, const char* destStr)
+// KW {
+// KW bool ret = false;
+// KW char* strString = NULL;
+// KW char* destString = NULL;
+// KW
+// KW if (NULL == srcStr || NULL == destStr )
+// KW {
+// KW return ret;
+// KW }
+// KW
+// KW _WrtUtilStringToLower(srcStr, &strString);
+// KW _WrtUtilStringToLower(destStr,&destString);
+// KW
+// KW if(!strcmp(strString, destString))
+// KW {
+// KW ret = true;
+// KW }
+// KW
+// KW free(strString);
+// KW free(destString);
+// KW
+// KW return ret;
+// KW }
+
+// check it deeply later.
+bool _WrtMakeDir (const char *path,
+ long mode,
+ int flags)
+{
+ if (NULL == path) {
+ return false;
+ }
+
+ const int defaultMode = 0777;
+ if (!(flags & WRT_FILEUTILS_RECUR)) {
+ if (mkdir(path, defaultMode) < 0) {
+ LogDebug("Failed to make dir " << path);
+ return false;
+ }
+ if (mode != -1 && chmod(path, mode) < 0) {
+ LogDebug("Failed to chmod");
+ remove(path);
+ return false;
+ }
+ } else {
+ struct stat st;
+ if (stat(path, &st) < 0 && errno == ENOENT) {
+ bool ret;
+ char *buf = NULL;
+ char *parent = NULL;
+ // mode_t mask;
+
+ // mask = umask (0);
+ // umask (mask);
+
+ buf = strdup(path);
+ parent = dirname(buf);
+ //ret = _WrtMakeDir(parent, (defaultMode & ~mask) | 0300, WRT_FILEUTILS_RECUR);
+ ret = _WrtMakeDir(parent, (defaultMode) | 0300, WRT_FILEUTILS_RECUR);
+ free(buf);
+
+ if ((!ret) || (!_WrtMakeDir(path, mode, 0))) {
+ LogDebug("Failed to _WrtMakeDir");
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+bool _WrtUtilChangeDir(const char* path)
+{
+ if (NULL == path) {
+ return false;
+ }
+ if (-1 == chdir(path)) {
+ if (ENOENT == errno) {
+ if (!_WrtMakeDir(path, 0664, WRT_FILEUTILS_RECUR)) {
+ return false;
+ }
+ if (-1 == chdir(path)) {
+ remove(path);
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool _WrtUtilRemoveDir(const char* path)
+{
+ DIR* dir = NULL;
+ struct dirent* ptr = NULL;
+ char childPath[MAX_WIDGET_PATH_LENGTH + 1] = { 0 };
+ if (path == NULL) {
+ LogWarning("Path is null");
+ return false;
+ }
+ dir = opendir(path);
+ if (NULL != dir) {
+ while ((ptr = readdir(dir)) != NULL) {
+ if ((!strcmp(ptr->d_name, ".")) || (!strcmp(ptr->d_name, ".."))) {
+ continue;
+ }
+ int len = strlen(path);
+ if (path[len - 1] == '/') {
+ snprintf(childPath,
+ MAX_WIDGET_PATH_LENGTH,
+ "%s%s",
+ path,
+ ptr->d_name);
+ } else {
+ snprintf(childPath,
+ MAX_WIDGET_PATH_LENGTH,
+ "%s/%s",
+ path,
+ ptr->d_name);
+ }
+ if (ptr->d_type == DT_DIR) {
+ if (!_WrtUtilRemoveDir(childPath)) {
+ closedir(dir);
+ return false;
+ }
+ } else {
+ if (unlink(childPath) != 0) {
+ closedir(dir);
+ LogWarning("Failed to remove file " << childPath);
+ return false;
+ }
+ }
+ }
+ closedir(dir);
+ } else if (errno == ENOTDIR) {
+ if (unlink(path) != 0) {
+ LogWarning("Failed to remove file " << path);
+ return false;
+ }
+ return true;
+ } else if (errno == ENOENT) { //not exist
+ LogWarning("Cannot remove non existent directory " << path);
+ return true;
+ } else {
+ LogWarning("Can't remove directory " << path);
+ return false;
+ }
+ if (rmdir(path) != 0) {
+ LogWarning("Removing directory failed :" << path << " errno: " << errno);
+ return false;
+ }
+
+ return true;
+}
+
+bool
+_WrtUtilStringToLower(const char* str,
+ char** lowerStr)
+{
+ if (!str || !lowerStr) {
+ return true;
+ }
+
+ char* cur = NULL;
+ int length = strlen(str);
+
+ *lowerStr = (char*)malloc(length + 1);
+
+ if (!(*lowerStr)) {
+ return false;
+ }
+
+ memset(*lowerStr, 0, length + 1);
+ strncpy(*lowerStr, str, length);
+
+ cur = *lowerStr;
+
+ while (*str != '\0') {
+ *cur++ = tolower(*str++);
+ //cur++;
+ }
+
+ return true;
+}
+
--- /dev/null
+#DB vcore
+ADD_CUSTOM_COMMAND(
+ OUTPUT ${CMAKE_BINARY_DIR}/modules/vcore/src/database_checksum_vcore.h
+ COMMAND ${CMAKE_SOURCE_DIR}/modules/vcore/src/orm/gen_db_md5.sh
+ ARGS ${CMAKE_BINARY_DIR}/modules/vcore/src/database_checksum_vcore.h
+ ${CMAKE_SOURCE_DIR}/modules/vcore/src/orm/vcore_db
+ DEPENDS ${CMAKE_SOURCE_DIR}/modules/vcore/src/orm/vcore_db
+ ${CMAKE_SOURCE_DIR}/modules/vcore/src/orm/gen_db_md5.sh
+ COMMENT "Generating VCORE database checksum"
+ )
+
+ADD_CUSTOM_COMMAND( OUTPUT .vcore.db
+ COMMAND rm -f ${CMAKE_CURRENT_BINARY_DIR}/.vcore.db
+ COMMAND gcc -Wall -include ${CMAKE_BINARY_DIR}/modules/vcore/src/database_checksum_vcore.h -I${PROJECT_SOURCE_DIR}/modules/db/include/ -I${PROJECT_SOURCE_DIR}/modules/vcore/src/orm -E ${PROJECT_SOURCE_DIR}/modules/vcore/src/orm/vcore_db_sql_generator.h | grep --invert-match "^#" > ${CMAKE_CURRENT_BINARY_DIR}/vcore_db.sql
+ COMMAND sqlite3 ${CMAKE_CURRENT_BINARY_DIR}/.vcore.db ".read ${CMAKE_CURRENT_BINARY_DIR}/vcore_db.sql" || rm -f ${CMAKE_CURRENT_BINARY_DIR}/.vcore.db
+ DEPENDS ${CMAKE_BINARY_DIR}/modules/vcore/src/database_checksum_vcore.h ${PROJECT_SOURCE_DIR}/modules/vcore/src/orm/vcore_db_sql_generator.h ${PROJECT_SOURCE_DIR}/modules/vcore/src/orm/vcore_db
+ )
+
+ADD_CUSTOM_COMMAND( OUTPUT .vcore.db-journal
+ COMMAND touch
+ ARGS ${CMAKE_CURRENT_BINARY_DIR}/.vcore.db-journal
+ )
+
+ADD_CUSTOM_TARGET(Sqlite3DbVCORE ALL DEPENDS .vcore.db .vcore.db-journal)
+
+INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/vcore_db.sql
+ DESTINATION share/wrt-engine/
+ )
+
+ADD_SUBDIRECTORY(src)
--- /dev/null
+INCLUDE(FindPkgConfig)
+
+PKG_CHECK_MODULES(VCORE_DEPS
+ cert-svc
+ ecore
+ appcore-efl
+ libxml-2.0
+ libsoup-2.4
+ openssl
+ xmlsec1
+ tapi
+ REQUIRED)
+
+SET(VCORE_DIR
+ ${PROJECT_SOURCE_DIR}/modules/vcore
+ )
+
+SET(VCORE_SRC_DIR
+ ${VCORE_DIR}/src/vcore
+ )
+
+SET(VCORE_SOURCES
+ ${VCORE_SRC_DIR}/Base64.cpp
+ ${VCORE_SRC_DIR}/CachedCRL.cpp
+ ${VCORE_SRC_DIR}/CachedOCSP.cpp
+ ${VCORE_SRC_DIR}/Certificate.cpp
+ ${VCORE_SRC_DIR}/CertificateCacheDAO.cpp
+ ${VCORE_SRC_DIR}/CertificateCollection.cpp
+ ${VCORE_SRC_DIR}/CertificateConfigReader.cpp
+ ${VCORE_SRC_DIR}/CertificateLoader.cpp
+ ${VCORE_SRC_DIR}/CertificateVerifier.cpp
+ ${VCORE_SRC_DIR}/Config.cpp
+ ${VCORE_SRC_DIR}/CRL.cpp
+ ${VCORE_SRC_DIR}/Database.cpp
+ ${VCORE_SRC_DIR}/DeveloperModeValidator.cpp
+ ${VCORE_SRC_DIR}/OCSP.cpp
+ ${VCORE_SRC_DIR}/OCSPCertMgrUtil.cpp
+ ${VCORE_SRC_DIR}/OCSPUtil.c
+ ${VCORE_SRC_DIR}/ReferenceValidator.cpp
+ ${VCORE_SRC_DIR}/RevocationCheckerBase.cpp
+ ${VCORE_SRC_DIR}/SaxReader.cpp
+ ${VCORE_SRC_DIR}/SignatureFinder.cpp
+ ${VCORE_SRC_DIR}/SignatureReader.cpp
+ ${VCORE_SRC_DIR}/SignatureValidator.cpp
+ ${VCORE_SRC_DIR}/SoupMessageSendBase.cpp
+ ${VCORE_SRC_DIR}/SoupMessageSendSync.cpp
+ ${VCORE_SRC_DIR}/SoupMessageSendAsync.cpp
+ ${VCORE_SRC_DIR}/VerificationStatus.cpp
+ ${VCORE_SRC_DIR}/ValidatorFactories.cpp
+ ${VCORE_SRC_DIR}/VCore.cpp
+ ${VCORE_SRC_DIR}/XmlsecAdapter.cpp
+ )
+
+SET(VCORE_INCLUDES
+ ${PROJECT_SOURCE_DIR}/modules/core/include
+ ${PROJECT_SOURCE_DIR}/modules/log/include
+ ${PROJECT_SOURCE_DIR}/modules/db/include
+ ${VCORE_DEPS_INCLUDE_DIRS}
+ ${VCORE_SRC_DIR}
+ ${VCORE_DIR}/src
+ ${VCORE_DIR}/src/orm
+ ${VCORE_DIR}/src/legacy
+ ${CMAKE_BINARY_DIR}/modules/vcore/src
+ )
+
+ADD_DEFINITIONS(${VCORE_DEPS_CFLAGS})
+ADD_DEFINITIONS(${VCORE_DEPS_CFLAGS_OTHER})
+ADD_DEFINITIONS("-DSEPARATED_SINGLETON_IMPLEMENTATION")
+
+INCLUDE_DIRECTORIES(${VCORE_INCLUDES})
+
+ADD_LIBRARY(${TARGET_VCORE_LIB} SHARED ${VCORE_SOURCES})
+SET_TARGET_PROPERTIES(${TARGET_VCORE_LIB} PROPERTIES
+ SOVERSION ${VERSION})
+
+ADD_DEPENDENCIES(${TARGET_VCORE_LIB} Sqlite3DbWTF)
+
+SET_TARGET_PROPERTIES(${TARGET_VCORE_LIB} PROPERTIES
+ COMPILE_FLAGS -fPIC)
+
+TARGET_LINK_LIBRARIES(${TARGET_VCORE_LIB}
+ ${VCORE_DEPS_LIBRARIES}
+ ${TARGET_DPL_EFL}
+ ${TARGET_DPL_DB_EFL}
+ )
+
+INSTALL(TARGETS ${TARGET_VCORE_LIB}
+ DESTINATION lib
+ PERMISSIONS OWNER_READ GROUP_READ WORLD_READ
+ )
+
+INSTALL(FILES
+ ${VCORE_SRC_DIR}/Base64.h
+ ${VCORE_SRC_DIR}/CachedCRL.h
+ ${VCORE_SRC_DIR}/CachedOCSP.h
+ ${VCORE_SRC_DIR}/Certificate.h
+ ${VCORE_SRC_DIR}/CertificateCacheDAO.h
+ ${VCORE_SRC_DIR}/CertificateCollection.h
+ ${VCORE_SRC_DIR}/CertificateConfigReader.h
+ ${VCORE_SRC_DIR}/CertificateLoader.h
+ ${VCORE_SRC_DIR}/CertificateStorage.h
+ ${VCORE_SRC_DIR}/CertificateVerifier.h
+ ${VCORE_SRC_DIR}/CertStoreType.h
+ ${VCORE_SRC_DIR}/Config.h
+ ${VCORE_SRC_DIR}/CRL.h
+ ${VCORE_SRC_DIR}/Database.h
+ ${VCORE_SRC_DIR}/DeveloperModeValidator.h
+ ${VCORE_SRC_DIR}/IAbstractResponseCache.h
+ ${VCORE_SRC_DIR}/OCSP.h
+ ${VCORE_SRC_DIR}/OCSPCertMgrUtil.h
+ ${VCORE_SRC_DIR}/ParserSchema.h
+ ${VCORE_SRC_DIR}/ReferenceValidator.h
+ ${VCORE_SRC_DIR}/RevocationCheckerBase.h
+ ${VCORE_SRC_DIR}/SaxReader.h
+ ${VCORE_SRC_DIR}/scoped_gpointer.h
+ ${VCORE_SRC_DIR}/SignatureData.h
+ ${VCORE_SRC_DIR}/SignatureFinder.h
+ ${VCORE_SRC_DIR}/SignatureReader.h
+ ${VCORE_SRC_DIR}/SignatureValidator.h
+ ${VCORE_SRC_DIR}/SoupMessageSendBase.h
+ ${VCORE_SRC_DIR}/SoupMessageSendSync.h
+ ${VCORE_SRC_DIR}/SoupMessageSendAsync.h
+ ${VCORE_SRC_DIR}/SSLContainers.h
+ ${VCORE_SRC_DIR}/VerificationStatus.h
+ ${VCORE_SRC_DIR}/ValidatorCommon.h
+ ${VCORE_SRC_DIR}/ValidatorFactories.h
+ ${VCORE_SRC_DIR}/VCore.h
+ ${VCORE_SRC_DIR}/XmlsecAdapter.h
+ DESTINATION include/dpl-efl/dpl/vcore/vcore
+ PERMISSIONS OWNER_READ GROUP_READ WORLD_READ
+ )
+
--- /dev/null
+Scripts required to create vcoredatabase.
--- /dev/null
+#!/bin/sh
+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}
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_VCORE_H
+#define ORM_GENERATOR_VCORE_H
+
+#define ORM_GENERATOR_DATABASE_NAME vcore_db_definitions
+#include <dpl/db/orm_generator.h>
+#undef ORM_GENERATOR_DATABASE_NAME
+
+#endif // ORM_GENERATOR_VCORE_H
--- /dev/null
+SQL(
+ PRAGMA foreign_keys = ON;
+ BEGIN TRANSACTION;
+)
+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()
+
+SQL(
+ COMMIT;
+)
--- /dev/null
+DATABASE_START(vcore)
+
+#include "vcore_db"
+#include "version_db"
+
+DATABASE_END()
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//Do not include this file directly! It is used only for SQL code generation.
+
+#include <dpl/db/orm_macros.h>
+
+#include "vcore_db_definitions"
--- /dev/null
+SQL(
+ BEGIN TRANSACTION;
+ CREATE TABLE DB_CHECKSUM (version INT);
+ COMMIT;
+)
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <algorithm>
+#include <string>
+#include <string.h>
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+#include <openssl/buffer.h>
+
+#include <dpl/log/log.h>
+#include <dpl/scoped_free.h>
+
+#include "Base64.h"
+
+namespace ValidationCore {
+Base64Encoder::Base64Encoder() :
+ m_b64(0),
+ m_bmem(0),
+ m_finalized(false)
+{
+}
+
+void Base64Encoder::append(const std::string &data)
+{
+ if (m_finalized) {
+ LogWarning("Already finalized.");
+ ThrowMsg(Exception::AlreadyFinalized, "Already finalized");
+ }
+
+ if (!m_b64) {
+ reset();
+ }
+ BIO_write(m_b64, data.c_str(), data.size());
+}
+
+void Base64Encoder::finalize()
+{
+ if (m_finalized) {
+ LogWarning("Already finalized.");
+ ThrowMsg(Exception::AlreadyFinalized, "Already finalized.");
+ }
+ m_finalized = true;
+ BIO_flush(m_b64);
+}
+
+std::string Base64Encoder::get()
+{
+ if (!m_finalized) {
+ LogWarning("Not finalized");
+ ThrowMsg(Exception::NotFinalized, "Not finalized");
+ }
+ BUF_MEM *bptr = 0;
+ BIO_get_mem_ptr(m_b64, &bptr);
+ if (bptr == 0) {
+ LogError("Bio internal error");
+ ThrowMsg(Exception::InternalError, "Bio internal error");
+ }
+
+ if (bptr->length > 0) {
+ return std::string(bptr->data, bptr->length - 1);
+ }
+ return std::string();
+}
+
+void Base64Encoder::reset()
+{
+ m_finalized = false;
+ BIO_free_all(m_b64);
+ m_b64 = BIO_new(BIO_f_base64());
+ m_bmem = BIO_new(BIO_s_mem());
+ if (!m_b64 || !m_bmem) {
+ LogError("Error during allocation memory in BIO");
+ ThrowMsg(Exception::InternalError,
+ "Error during allocation memory in BIO");
+ }
+ m_b64 = BIO_push(m_b64, m_bmem);
+}
+
+Base64Encoder::~Base64Encoder()
+{
+ BIO_free_all(m_b64);
+}
+
+Base64Decoder::Base64Decoder() :
+ m_finalized(false)
+{
+}
+
+void Base64Decoder::append(const std::string &data)
+{
+ if (m_finalized) {
+ LogWarning("Already finalized.");
+ ThrowMsg(Exception::AlreadyFinalized, "Already finalized.");
+ }
+ m_input.append(data);
+}
+
+static bool whiteCharacter(char a)
+{
+ if (a == '\n') { return true; }
+ return false;
+}
+
+bool Base64Decoder::finalize()
+{
+ if (m_finalized) {
+ LogWarning("Already finalized.");
+ ThrowMsg(Exception::AlreadyFinalized, "Already finalized.");
+ }
+
+ m_finalized = true;
+
+ m_input.erase(std::remove_if(m_input.begin(),
+ m_input.end(),
+ whiteCharacter),
+ m_input.end());
+
+ for (size_t i = 0; i<m_input.size(); ++i) {
+ if (isalnum(m_input[i])
+ || m_input[i] == '+'
+ || m_input[i] == '/'
+ || m_input[i] == '=')
+ {
+ continue;
+ }
+ LogError("Base64 input contains illegal chars: " << m_input[i]);
+ return false;
+ }
+
+ BIO *b64, *bmem;
+ size_t len = m_input.size();
+
+ DPL::ScopedFree<char> buffer(static_cast<char*>(malloc(len)));
+
+ if (!buffer) {
+ LogError("Error in malloc.");
+ ThrowMsg(Exception::InternalError, "Error in malloc.");
+ }
+
+ memset(buffer.Get(), 0, len);
+ b64 = BIO_new(BIO_f_base64());
+ if (!b64) {
+ LogError("Couldn't create BIO object.");
+ ThrowMsg(Exception::InternalError, "Couldn't create BIO object.");
+ }
+ BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
+ DPL::ScopedFree<char> tmp(strdup(m_input.c_str()));
+ m_input.clear();
+
+ bmem = BIO_new_mem_buf(tmp.Get(), len);
+
+ if (!bmem) {
+ BIO_free(b64);
+ LogError("Internal error in BIO");
+ ThrowMsg(Exception::InternalError, "Internal error in BIO");
+ }
+
+ bmem = BIO_push(b64, bmem);
+
+ if (!bmem) {
+ BIO_free(b64);
+ LogError("Internal error in BIO");
+ ThrowMsg(Exception::InternalError, "Internal error in BIO");
+ }
+
+ int readlen = BIO_read(bmem, buffer.Get(), len);
+ m_output.clear();
+
+ bool status = true;
+
+ if (readlen > 0) {
+ m_output.append(buffer.Get(), readlen);
+ } else {
+ status = false;
+ }
+
+ BIO_free_all(bmem);
+ return status;
+}
+
+std::string Base64Decoder::get() const
+{
+ if (!m_finalized) {
+ LogWarning("Not finalized.");
+ ThrowMsg(Exception::NotFinalized, "Not finalized");
+ }
+ return m_output;
+}
+
+void Base64Decoder::reset()
+{
+ m_finalized = false;
+ m_input.clear();
+ m_output.clear();
+}
+} // namespace ValidationCore
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 _BASE64_H_
+#define _BASE64_H_
+
+#include <string>
+#include <dpl/noncopyable.h>
+#include <dpl/exception.h>
+
+struct bio_st;
+typedef bio_st BIO;
+
+namespace ValidationCore {
+class Base64Encoder : public DPL::Noncopyable
+{
+ public:
+ class Exception
+ {
+ public:
+ DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+ DECLARE_EXCEPTION_TYPE(Base, InternalError)
+ DECLARE_EXCEPTION_TYPE(Base, NotFinalized)
+ DECLARE_EXCEPTION_TYPE(Base, AlreadyFinalized)
+ };
+ Base64Encoder();
+ void append(const std::string &data);
+ void finalize();
+ std::string get();
+ void reset();
+ ~Base64Encoder();
+
+ private:
+ BIO *m_b64;
+ BIO *m_bmem;
+ bool m_finalized;
+};
+
+class Base64Decoder : public DPL::Noncopyable
+{
+ public:
+ class Exception
+ {
+ public:
+ DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+ DECLARE_EXCEPTION_TYPE(Base, InternalError)
+ DECLARE_EXCEPTION_TYPE(Base, NotFinalized)
+ DECLARE_EXCEPTION_TYPE(Base, AlreadyFinalized)
+ };
+ Base64Decoder();
+ void append(const std::string &data);
+
+ /*
+ * Function will return false when BIO_read fails
+ * (for example: when string was not in base64 format).
+ */
+ bool finalize();
+ std::string get() const;
+ void reset();
+ ~Base64Decoder()
+ {
+ }
+
+ private:
+ std::string m_input;
+ std::string m_output;
+ bool m_finalized;
+};
+} // namespace ValidationCore
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 Piotr Marcinkiewicz(p.marcinkiew@samsung.com)
+ * @version 0.1
+ * @file CRL.h
+ * @brief Routines for certificate validation over CRL
+ */
+
+#include "CRL.h"
+
+#include <set>
+#include <algorithm>
+
+#include <openssl/err.h>
+#include <openssl/objects.h>
+#include <openssl/ocsp.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+
+#include <dpl/log/log.h>
+#include <dpl/assert.h>
+#include <dpl/exception.h>
+#include <dpl/scoped_ptr.h>
+#include <dpl/scoped_array.h>
+#include <dpl/db/orm.h>
+#include <dpl/foreach.h>
+
+#include "Base64.h"
+#include "Certificate.h"
+#include "SoupMessageSendSync.h"
+#include "CertificateCacheDAO.h"
+
+namespace {
+const char *CRL_LOOKUP_DIR_1 = "/usr/share/cert-svc/ca-certs/code-signing/wac";
+const char *CRL_LOOKUP_DIR_2 = "/opt/share/cert-svc/certs/code-signing/wac";
+} //anonymous namespace
+
+namespace ValidationCore {
+
+CRL::StringList CRL::getCrlUris(const CertificatePtr &argCert)
+{
+ StringList result = argCert->getCrlUris();
+
+ if (!result.empty()) {
+ return result;
+ }
+ LogInfo("No distribution points found. Getting from CA cert.");
+ X509_STORE_CTX *ctx = createContext(argCert);
+ X509_OBJECT obj;
+
+ //Try to get distribution points from CA certificate
+ int retVal = X509_STORE_get_by_subject(ctx, X509_LU_X509,
+ X509_get_issuer_name(argCert->
+ getX509()),
+ &obj);
+ X509_STORE_CTX_free(ctx);
+ if (0 >= retVal) {
+ LogError("No dedicated CA certificate available");
+ return result;
+ }
+ CertificatePtr caCert(new Certificate(obj.data.x509));
+ X509_OBJECT_free_contents(&obj);
+ return caCert->getCrlUris();
+}
+
+CRL::CRL()
+{
+ LogInfo("CRL storage initialization.");
+ m_store = X509_STORE_new();
+ if (!m_store) {
+ LogError("Failed to create new store.");
+ ThrowMsg(CRLException::StorageError,
+ "Not possible to create new store.");
+ }
+ m_lookup = X509_STORE_add_lookup(m_store, X509_LOOKUP_hash_dir());
+ if (!m_lookup) {
+ cleanup();
+ LogError("Failed to add hash dir lookup");
+ ThrowMsg(CRLException::StorageError,
+ "Not possible to add hash dir lookup.");
+ }
+ // Add hash dir pathname for CRL checks
+ bool retVal = X509_LOOKUP_add_dir(m_lookup,
+ CRL_LOOKUP_DIR_1, X509_FILETYPE_PEM) == 1;
+ retVal &= retVal && (X509_LOOKUP_add_dir(m_lookup, CRL_LOOKUP_DIR_1,
+ X509_FILETYPE_ASN1) == 1);
+ retVal &= retVal && (X509_LOOKUP_add_dir(m_lookup, CRL_LOOKUP_DIR_2,
+ X509_FILETYPE_PEM) == 1);
+ retVal &= retVal && (X509_LOOKUP_add_dir(m_lookup, CRL_LOOKUP_DIR_2,
+ X509_FILETYPE_ASN1) == 1);
+ if (!retVal) {
+ LogError("Failed to add lookup dir for PEM files.");
+ cleanup();
+ ThrowMsg(CRLException::StorageError,
+ "Failed to add lookup dir for PEM files.");
+ }
+ LogInfo("CRL storage initialization complete.");
+}
+
+CRL::~CRL()
+{
+ cleanup();
+}
+
+void CRL::cleanup()
+{
+ LogInfo("Free CRL storage");
+ // STORE is responsible for LOOKUP release
+ // X509_LOOKUP_free(m_lookup);
+ X509_STORE_free(m_store);
+}
+
+CRL::RevocationStatus CRL::checkCertificate(const CertificatePtr &argCert)
+{
+ RevocationStatus retStatus = {false, false};
+ int retVal = 0;
+ StringList crlUris = getCrlUris(argCert);
+ FOREACH(it, crlUris) {
+ CRLDataPtr crl = getCRL(*it);
+ if (!crl) {
+ LogDebug("CRL not found for URI: " << *it);
+ continue;
+ }
+ X509_CRL *crlInternal = convertToInternal(crl);
+
+ //Check date
+ if (X509_CRL_get_nextUpdate(crlInternal)) {
+ retVal = X509_cmp_current_time(
+ X509_CRL_get_nextUpdate(crlInternal));
+ retStatus.isCRLValid = retVal > 0;
+ } else {
+ // If nextUpdate is not set assume it is actual.
+ retStatus.isCRLValid = true;
+ }
+ LogInfo("CRL valid: " << retStatus.isCRLValid);
+ X509_REVOKED rev;
+ rev.serialNumber = X509_get_serialNumber(argCert->getX509());
+ // sk_X509_REVOKED_find returns index if serial number is found on list
+ retVal = sk_X509_REVOKED_find(crlInternal->crl->revoked, &rev);
+ X509_CRL_free(crlInternal);
+ retStatus.isRevoked = retVal != -1;
+ LogInfo("CRL revoked: " << retStatus.isRevoked);
+
+ if (!retStatus.isRevoked && isOutOfDate(crl)) {
+ LogDebug("Certificate is not Revoked, but CRL is outOfDate.");
+ continue;
+ }
+
+ return retStatus;
+ }
+ // If there is no CRL for any of URIs it means it's not possible to
+ // tell anything about revocation status but it's is not an error.
+ return retStatus;
+}
+
+CRL::RevocationStatus CRL::checkCertificateChain(CertificateCollection
+ certChain)
+{
+ if (!certChain.sort()) {
+ LogError("Certificate list doesn't create chain.");
+ ThrowMsg(CRLException::InvalidParameter,
+ "Certificate list doesn't create chain.");
+ }
+
+ RevocationStatus ret;
+ ret.isCRLValid = true;
+ ret.isRevoked = false;
+ const CertificateList &certList = certChain.getChain();
+ FOREACH(it, certList) {
+ if (!(*it)->isRootCert()) {
+ LogInfo("Certificate common name: " << *((*it)->getCommonName()));
+ RevocationStatus certResult = checkCertificate(*it);
+ ret.isCRLValid &= certResult.isCRLValid;
+ ret.isRevoked |= certResult.isRevoked;
+ if (ret.isCRLValid && !ret.isRevoked) {
+ addToStorage(*it);
+ }
+ if (ret.isRevoked) {
+ return ret;
+ }
+ }
+ }
+ return ret;
+}
+
+VerificationStatus CRL::checkEndEntity(CertificateCollection &chain)
+{
+ if (!chain.sort() && !chain.empty()) {
+ LogInfo("Could not find End Entity certificate. "
+ "Collection does not form chain.");
+ return VERIFICATION_STATUS_ERROR;
+ }
+ CertificateList::const_iterator iter = chain.begin();
+ RevocationStatus stat = checkCertificate(*iter);
+ if (stat.isRevoked) {
+ return VERIFICATION_STATUS_REVOKED;
+ }
+ if (stat.isCRLValid) {
+ return VERIFICATION_STATUS_GOOD;
+ }
+ return VERIFICATION_STATUS_ERROR;
+}
+
+void CRL::addToStorage(const CertificatePtr &argCert)
+{
+ X509_STORE_add_cert(m_store, argCert->getX509());
+}
+
+bool CRL::isOutOfDate(const CRLDataPtr &crl) const {
+ X509_CRL *crlInternal = convertToInternal(crl);
+
+ bool result = false;
+ if (X509_CRL_get_nextUpdate(crlInternal)) {
+ if (0 > X509_cmp_current_time(X509_CRL_get_nextUpdate(crlInternal))) {
+ result = true;
+ } else {
+ result = false;
+ }
+ } else {
+ result = true;
+ }
+ X509_CRL_free(crlInternal);
+ return result;
+}
+
+bool CRL::updateList(const CertificatePtr &argCert,
+ const UpdatePolicy updatePolicy)
+{
+ LogInfo("Update CRL for certificate");
+
+ // Retrieve distribution points
+ StringList crlUris = getCrlUris(argCert);
+ FOREACH(it, crlUris) {
+ // Try to get CRL from database
+ LogInfo("Getting CRL for URI: " << *it);
+
+ bool downloaded = false;
+
+ CRLDataPtr crl;
+
+ // If updatePolicy == UPDATE_ON_DEMAND we dont care
+ // about data in cache. New crl must be downloaded.
+ if (updatePolicy == UPDATE_ON_EXPIRED) {
+ crl = getCRL(*it);
+ }
+
+ if (!!crl && isOutOfDate(crl)) {
+ LogDebug("Crl out of date - downloading.");
+ crl = downloadCRL(*it);
+ downloaded = true;
+ }
+
+ if (!crl) {
+ LogDebug("Crl not found in cache - downloading.");
+ crl = downloadCRL(*it);
+ downloaded = true;
+ }
+
+ if (!crl) {
+ LogDebug("Failed to obtain CRL. URL: " << *it);
+ continue;
+ }
+
+ if (!!crl && isOutOfDate(crl)) {
+ LogError("CRL out of date. Broken URL: " << *it);
+ }
+
+ // Make X509 internal structure
+ X509_CRL *crlInternal = convertToInternal(crl);
+
+ //Check if CRL is signed
+ if (!verifyCRL(crlInternal, argCert)) {
+ LogError("Failed to verify CRL. URI: " << crl->uri);
+ X509_CRL_free(crlInternal);
+ return false;
+ }
+ X509_CRL_free(crlInternal);
+
+ if (downloaded) {
+ updateCRL(crl);
+ }
+ return true;
+ }
+
+ return false;
+}
+
+void CRL::addToStore(const CertificateCollection &collection)
+{
+ FOREACH(it, collection){
+ addToStorage(*it);
+ }
+}
+
+bool CRL::updateList(const CertificateCollection &collection,
+ UpdatePolicy updatePolicy)
+{
+ bool failed = false;
+
+ FOREACH(it, collection){
+ failed |= !updateList(*it, updatePolicy);
+ }
+
+ return !failed;
+}
+
+bool CRL::verifyCRL(X509_CRL *crl,
+ const CertificatePtr &cert)
+{
+ X509_OBJECT obj;
+ X509_STORE_CTX *ctx = createContext(cert);
+
+ /* get issuer certificate */
+ int retVal = X509_STORE_get_by_subject(ctx, X509_LU_X509,
+ X509_CRL_get_issuer(crl), &obj);
+ X509_STORE_CTX_free(ctx);
+ if (0 >= retVal) {
+ LogError("Unknown CRL issuer certificate!");
+ return false;
+ }
+
+ /* extract public key and verify signature */
+ EVP_PKEY *pkey = X509_get_pubkey(obj.data.x509);
+ X509_OBJECT_free_contents(&obj);
+ if (!pkey) {
+ LogError("Failed to get issuer's public key.");
+ return false;
+ }
+ retVal = X509_CRL_verify(crl, pkey);
+ EVP_PKEY_free(pkey);
+ if (0 > retVal) {
+ LogError("Failed to verify CRL.");
+ return false;
+ } else if (0 == retVal) {
+ LogError("CRL is invalid");
+ return false;
+ }
+ LogInfo("CRL is valid.");
+ return true;
+}
+
+bool CRL::isPEMFormat(const CRLDataPtr &crl) const
+{
+ const char *pattern = "-----BEGIN X509 CRL-----";
+ std::string content(crl->buffer, crl->length);
+ if (content.find(pattern) != std::string::npos) {
+ LogInfo("CRL is in PEM format.");
+ return true;
+ }
+ LogInfo("CRL is in DER format.");
+ return false;
+}
+
+X509_CRL *CRL::convertToInternal(const CRLDataPtr &crl) const
+{
+ //At this point it's not clear does crl have DER or PEM format
+ X509_CRL *ret = NULL;
+ if (isPEMFormat(crl)) {
+ BIO *bmem = BIO_new_mem_buf(crl->buffer, crl->length);
+ if (!bmem) {
+ LogError("Failed to allocate memory in BIO");
+ ThrowMsg(CRLException::InternalError,
+ "Failed to allocate memory in BIO");
+ }
+ ret = PEM_read_bio_X509_CRL(bmem, NULL, NULL, NULL);
+ BIO_free_all(bmem);
+ } else {
+ //If it's not PEM it must be DER format
+ std::string content(crl->buffer, crl->length);
+ const unsigned char *buffer =
+ reinterpret_cast<unsigned char*>(crl->buffer);
+ ret = d2i_X509_CRL(NULL, &buffer, crl->length);
+ }
+ if (!ret) {
+ LogError("Failed to convert to internal structure");
+ ThrowMsg(CRLException::InternalError,
+ "Failed to convert to internal structure");
+ }
+ return ret;
+}
+
+X509_STORE_CTX *CRL::createContext(const CertificatePtr &argCert)
+{
+ X509_STORE_CTX *ctx;
+ ctx = X509_STORE_CTX_new();
+ if (!ctx) {
+ ThrowMsg(CRLException::StorageError, "Failed to create new context.");
+ }
+ X509_STORE_CTX_init(ctx, m_store, argCert->getX509(), NULL);
+ return ctx;
+}
+
+CRL::CRLDataPtr CRL::downloadCRL(const std::string &uri)
+{
+ using namespace SoupWrapper;
+
+ char *cport = 0, *chost = 0,*cpath = 0;
+ int use_ssl = 0;
+
+ if (!OCSP_parse_url(const_cast<char*>(uri.c_str()),
+ &chost,
+ &cport,
+ &cpath,
+ &use_ssl))
+ {
+ LogWarning("Error in OCSP_parse_url");
+ return CRLDataPtr();
+ }
+
+ std::string host = chost;
+ if (cport) {
+ host += ":";
+ host += cport;
+ }
+
+ free(cport);
+ free(chost);
+ free(cpath);
+
+ SoupMessageSendSync message;
+ message.setHost(uri);
+ message.setHeader("Host", host);
+
+ if (SoupMessageSendSync::REQUEST_STATUS_OK != message.sendSync()) {
+ LogWarning("Error in sending network request.");
+ return CRLDataPtr();
+ }
+
+ SoupMessageSendBase::MessageBuffer mBuffer = message.getResponse();
+ return CRLDataPtr(new CRLData(mBuffer,uri));
+}
+
+CRL::CRLDataPtr CRL::getCRL(const std::string &uri) const
+{
+ CRLCachedData cachedCrl;
+ cachedCrl.distribution_point = uri;
+ if (!CertificateCacheDAO::getCRLResponse(&cachedCrl)) {
+ LogInfo("CRL not present in database. URI: " << uri);
+ return CRLDataPtr();
+ }
+
+ std::string body = cachedCrl.crl_body;
+
+ LogInfo("CRL found in database.");
+ //TODO: remove when ORM::blob available
+ //Encode buffer to base64 format to store in database
+
+ Base64Decoder decoder;
+ decoder.append(body);
+ if (!decoder.finalize()) {
+ LogError("Failed to decode base64 format.");
+ ThrowMsg(CRLException::StorageError, "Failed to decode base64 format.");
+ }
+ std::string crlBody = decoder.get();
+
+ DPL::ScopedArray<char> bodyBuffer(new char[crlBody.length()]);
+ crlBody.copy(bodyBuffer.Get(), crlBody.length());
+ return CRLDataPtr(new CRLData(bodyBuffer.Release(), crlBody.length(),
+ uri));
+}
+
+void CRL::updateCRL(const CRLDataPtr &crl)
+{
+ //TODO: remove when ORM::blob available
+ //Encode buffer to base64 format to store in database
+ Base64Encoder encoder;
+ if (!crl || !crl->buffer) {
+ ThrowMsg(CRLException::InternalError, "CRL buffer is empty");
+ }
+ encoder.append(std::string(crl->buffer, crl->length));
+ encoder.finalize();
+ std::string b64CRLBody = encoder.get();
+
+ time_t nextUpdateTime = 0;
+ X509_CRL *crlInternal = convertToInternal(crl);
+
+ if (X509_CRL_get_nextUpdate(crlInternal)) {
+ asn1TimeToTimeT(X509_CRL_get_nextUpdate(crlInternal),
+ &nextUpdateTime);
+ }
+
+ X509_CRL_free(crlInternal);
+ //Update/insert crl body
+ CertificateCacheDAO::setCRLResponse(crl->uri,b64CRLBody,nextUpdateTime);
+}
+} // ValidationCore
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 Piotr Marcinkiewicz(p.marcinkiew@samsung.com)
+ * @version 0.4
+ * @file CRL.h
+ * @brief Routines for certificate validation over CRL
+ */
+
+#ifndef WRT_ENGINE_SRC_VALIDATION_CORE_ENGINE_CRL_H_
+#define WRT_ENGINE_SRC_VALIDATION_CORE_ENGINE_CRL_H_
+
+#include <dpl/exception.h>
+#include <dpl/shared_ptr.h>
+#include <dpl/noncopyable.h>
+#include <dpl/log/log.h>
+
+#include "Certificate.h"
+#include "CertificateCollection.h"
+#include "SoupMessageSendBase.h"
+#include "VerificationStatus.h"
+
+namespace ValidationCore {
+namespace CRLException {
+DECLARE_EXCEPTION_TYPE(DPL::Exception, CRLException)
+DECLARE_EXCEPTION_TYPE(CRLException, StorageError)
+DECLARE_EXCEPTION_TYPE(CRLException, DownloadFailed)
+DECLARE_EXCEPTION_TYPE(CRLException, InternalError)
+DECLARE_EXCEPTION_TYPE(CRLException, InvalidParameter)
+}
+
+class CachedCRL; // forward declaration
+
+class CRL
+{
+ protected:
+ X509_STORE *m_store;
+ X509_LOOKUP *m_lookup;
+
+ class CRLData : DPL::Noncopyable
+ {
+ public:
+ //TODO: change to SharedArray when available
+ char *buffer;
+ size_t length;
+ std::string uri;
+
+ CRLData(char* _buffer,
+ size_t _length,
+ const std::string &_uri) :
+ buffer(_buffer),
+ length(_length),
+ uri(_uri)
+ {
+ }
+
+ CRLData(const SoupWrapper::SoupMessageSendBase::MessageBuffer &mBuff,
+ const std::string &mUri)
+ : uri(mUri)
+ {
+ buffer = new char[mBuff.size()];
+ length = mBuff.size();
+ memcpy(buffer, &mBuff[0], mBuff.size());
+ }
+
+ ~CRLData()
+ {
+ LogInfo("Delete buffer");
+ delete[] buffer;
+ }
+ };
+ typedef DPL::SharedPtr<CRLData> CRLDataPtr;
+ typedef std::list<std::string> StringList;
+
+ CRLDataPtr getCRL(const std::string &uri) const;
+ CRLDataPtr downloadCRL(const std::string &uri);
+ X509_STORE_CTX *createContext(const CertificatePtr &argCert);
+ void updateCRL(const CRLDataPtr &crl);
+ X509_CRL *convertToInternal(const CRLDataPtr &crl) const;
+ StringList getCrlUris(const CertificatePtr &argCert);
+ bool isPEMFormat(const CRLDataPtr &crl) const;
+ bool verifyCRL(X509_CRL *crl,
+ const CertificatePtr &cert);
+ void addToStorage(const CertificatePtr &argCert);
+ void cleanup();
+ bool isOutOfDate(const CRLDataPtr &crl) const;
+
+ friend class CachedCRL;
+ public:
+ enum UpdatePolicy
+ {
+ UPDATE_ON_EXPIRED, /**< Download and update CRL only when next update
+ date has expired */
+ UPDATE_ON_DEMAND /**< Download and update CRL regardless next update
+ date */
+ };
+
+ struct RevocationStatus
+ {
+ bool isCRLValid; /**< True when CRL was valid during
+ certificate validation */
+ bool isRevoked; /**< True when certificate is revoked */
+ };
+
+ CRL();
+ ~CRL();
+
+ /**
+ * @brief Checks if given certificate is revoked.
+ *
+ * @details This function doesn't update CRL list. If related CRL
+ * is out of date the #isCRLValid return parameter is set to false.
+ *
+ * @param[in] argCert The certificate to check against revocation.
+ * @return RevocationStatus.isRevoked True when certificate is revoked,
+ * false otherwise.
+ * RevocationStatus.isCRLValid True if related CRL has not expired,
+ * false otherwise.
+ */
+ RevocationStatus checkCertificate(const CertificatePtr &argCert);
+
+ /**
+ * @brief Checks if any certificate from certificate chain is revoked.
+ *
+ * @details This function doesn't update CRL lists. If any of related
+ * CRL is out of date the #isCRLValid parameter is set to true.
+ * This function adds valid certificates from the chain to internal storage
+ * map so they'll be available in further check operations for current
+ * CRL object.
+ *
+ * @param[in] argCert The certificate chain to check against revocation.
+ * @return RevocationStatus.isRevoked True when any from certificate chain
+ * is revoked, false otherwise.
+ * RevocationStatus.isCRLValid True if all of related CRLs has
+ * not expired, false otherwise.
+ */
+ RevocationStatus checkCertificateChain(CertificateCollection certChain);
+
+ VerificationStatus checkEndEntity(CertificateCollection &chain);
+
+ /**
+ * @brief Updates CRL related with given certificate.
+ *
+ * @details This function updates CRL list related with given certificate.
+ * If CRL related with given certificate is not stored in database
+ * then this function will download CRL and store it in database.
+ *
+ * @param[in] argCert The certificate for which the CRL will be updated
+ * @param[in] updatePolicy Determine when CRL will be downloaded and updated
+ * @return True when CRL for given certificate was updated successfully,
+ * false otherwise.
+ */
+ bool updateList(const CertificatePtr &argCert,
+ const UpdatePolicy updatePolicy);
+
+ /**
+ * @brief Updates CRL related with given certificates.
+ *
+ * @details This function updates CRL lists related with given certificates.
+ * If CRL related with given certificate is not stored in database
+ * then this function will download CRL and store it in database.
+ *
+ * @param[in] collection The certificate collection for which the CRL will
+ * be updated
+ * @param[in] updatePolicy Determine when CRL will be downloaded and updated
+ * @return True when CRL for given certificate was updated successfully,
+ * false otherwise.
+ */
+ bool updateList(const CertificateCollection &collection,
+ const UpdatePolicy updatePolisy);
+
+ /**
+ * @brief Add certificate to known certificates store.
+ *
+ * @param[in] collection The certificate collection which will be
+ * added to known certificate store.
+ */
+ void addToStore(const CertificateCollection &collection);
+};
+} // ValidationCore
+
+#endif //ifndef WRT_ENGINE_SRC_VALIDATION_CORE_ENGINE_CRL_H_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ *
+ * @file CachedCRL.cpp
+ * @author Tomasz Swierczek (t.swierczek@samsung.com)
+ * @version 0.1
+ * @brief Cached CRL class implementation
+ */
+
+#include <string>
+#include <time.h>
+
+#include <dpl/foreach.h>
+#include <dpl/log/log.h>
+#include <dpl/foreach.h>
+
+#include "CRL.h"
+#include "CachedCRL.h"
+#include "Certificate.h"
+#include "CertificateCacheDAO.h"
+
+namespace ValidationCore {
+
+const time_t CachedCRL::CRL_minTimeValid = 3600; // one hour in seconds
+
+const time_t CachedCRL::CRL_maxTimeValid = 3600 * 24 * 7; // one week in seconds
+
+const time_t CachedCRL::CRL_refreshBefore = 3600; // one hour in seconds
+
+VerificationStatus CachedCRL::check(const CertificateCollection &certs)
+{
+ CRL crl;
+ bool allValid = true;
+ // we dont check CRL validity since
+ // we may use crl for longer time
+ // in smart cache than in regular CRL class (time clamping)
+ crl.addToStore(certs);
+ FOREACH(cert, certs){
+ CRL::StringList crlUris = crl.getCrlUris(*cert);
+ FOREACH(uri, crlUris) {
+ allValid = allValid && updateCRLForUri(*uri,false);
+ }
+ }
+ if (!allValid) {
+ // problems with CRL validity
+ LogDebug("Some CRLs not valid");
+ }
+ CRL::RevocationStatus stat = crl.checkCertificateChain(certs);
+ if (stat.isRevoked) {
+ LogDebug("Status REVOKED");
+ return VERIFICATION_STATUS_REVOKED;
+ }
+ LogDebug("Status GOOD");
+ return VERIFICATION_STATUS_GOOD;
+}
+
+VerificationStatus CachedCRL::checkEndEntity(CertificateCollection &certs)
+{
+ if (certs.empty()) {
+ LogError("Collection empty. This should never happen.");
+ LogDebug("Status ERROR");
+ return VERIFICATION_STATUS_ERROR;
+ }
+ if (!certs.sort()) {
+ LogError("Could not find End Entity certificate. "
+ "Collection does not form chain.");
+ LogDebug("Status ERROR");
+ return VERIFICATION_STATUS_ERROR;
+ }
+ CRL crl;
+ bool allValid = true;
+ // we dont check CRL validity since
+ // we may use crl for longer time
+ // in smart cache than in regular CRL class (time clamping)
+ crl.addToStore(certs);
+ CertificateList::const_iterator icert = certs.begin();
+ if (icert != certs.end()) {
+ CRL::StringList crlUris = crl.getCrlUris(*icert);
+ FOREACH(uri, crlUris) {
+ allValid = allValid && updateCRLForUri(*uri,false);
+ }
+ }
+ if (!allValid) {
+ // problems with CRL validity
+ LogDebug("Some CRLs not valid");
+ }
+ CertificateList::const_iterator iter = certs.begin();
+ CRL::RevocationStatus stat = crl.checkCertificate(*iter);
+ if (stat.isRevoked) {
+ LogDebug("Status REVOKED");
+ return VERIFICATION_STATUS_REVOKED;
+ }
+ LogDebug("Status GOOD");
+ return VERIFICATION_STATUS_GOOD;
+}
+
+void CachedCRL::updateCache()
+{
+ CRLCachedDataList list;
+ CertificateCacheDAO::getCRLResponseList(&list);
+ FOREACH(db_crl, list) {
+ updateCRLForUri(db_crl->distribution_point, true);
+ }
+}
+
+bool CachedCRL::updateCRLForUri(const std::string & uri, bool useExpiredShift)
+{
+ CRLCachedData cachedCRL;
+ cachedCRL.distribution_point = uri;
+ time_t now;
+ time(&now);
+ if (useExpiredShift) {
+ now += CRL_refreshBefore;
+ }
+ if (CertificateCacheDAO::getCRLResponse(&cachedCRL)) {
+ if (now < cachedCRL.next_update_time) {
+ LogDebug("Cached CRL still valid for: " << uri);
+ return true;
+ }
+ }
+ // need to download new CRL
+ CRL crl;
+ CRL::CRLDataPtr list = crl.downloadCRL(uri);
+ if (!list) {
+ LogWarning("Could not retreive CRL from " << uri);
+ return false;
+ }
+ crl.updateCRL(list);
+ CertificateCacheDAO::getCRLResponse(&cachedCRL); // save it the way CRL does
+ cachedCRL.next_update_time =
+ getNextUpdateTime(now,cachedCRL.next_update_time);
+ CertificateCacheDAO::setCRLResponse(cachedCRL.distribution_point,
+ cachedCRL.crl_body,
+ cachedCRL.next_update_time);
+ return true;
+}
+
+time_t CachedCRL::getNextUpdateTime(time_t now, time_t response_validity)
+{
+ time_t min = now + CRL_minTimeValid;
+ time_t max = now + CRL_maxTimeValid;
+ if (response_validity < min) {
+ return min;
+ }
+ if (response_validity > max) {
+ return max;
+ }
+ return response_validity;
+}
+
+} // namespace ValidationCore
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ *
+ * @file CachedCRL.h
+ * @author Tomasz Swierczek (t.swierczek@samsung.com)
+ * @version 0.1
+ * @brief Header file for smart cached CRL class
+ */
+
+#ifndef _SRC_VALIDATION_CORE_CACHED_CRL_
+#define _SRC_VALIDATION_CORE_CACHED_CRL_
+
+#include "CRL.h"
+#include "IAbstractResponseCache.h"
+
+namespace ValidationCore {
+
+class CachedCRL : public IAbstractResponseCache {
+ public:
+ // cache can't be refreshed more frequently than CRL_minTimeValid
+ static const time_t CRL_minTimeValid;
+
+ // to be even more secure, cache will be refreshed for certificate at least
+ // after CRL_maxTimeValid from last response
+ static const time_t CRL_maxTimeValid;
+
+ // upon cache refresh, responses that will be invalid in CRL_refreshBefore
+ // seconds will be refreshed
+ static const time_t CRL_refreshBefore;
+
+ VerificationStatus check(const CertificateCollection &certs);
+ VerificationStatus checkEndEntity(CertificateCollection &certs);
+ void updateCache();
+
+ CachedCRL()
+ {
+ }
+ virtual ~CachedCRL()
+ {
+ }
+
+ private:
+
+ // updates CRL cache for distributor URI
+ // useExpiredShift ==true should be used in cron/global cache update
+ // since it updates all CRLs that will be out of date in next
+ // CRL_refreshBefore seconds
+ bool updateCRLForUri(const std::string & uri,
+ bool useExpiredShift);
+ time_t getNextUpdateTime(time_t now, time_t response_validity);
+};
+
+} // namespace ValidationCore
+
+#endif /* _SRC_VALIDATION_CORE_CACHED_CRL_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ *
+ * @file CachedOCSP.cpp
+ * @author Tomasz Swierczek (t.swierczek@samsung.com)
+ * @version 0.1
+ * @brief Cached OCSP class implementation
+ */
+
+#include <string>
+#include <time.h>
+
+#include <dpl/foreach.h>
+#include <dpl/log/log.h>
+#include <dpl/foreach.h>
+
+#include "OCSP.h"
+#include "CachedOCSP.h"
+#include "Certificate.h"
+#include "CertificateCacheDAO.h"
+
+namespace ValidationCore {
+
+const time_t CachedOCSP::OCSP_minTimeValid = 3600; // one hour in seconds
+
+const time_t CachedOCSP::OCSP_maxTimeValid =
+ 3600 * 24 * 7; // one week in seconds
+
+const time_t CachedOCSP::OCSP_refreshBefore = 3600; // one hour in seconds
+
+VerificationStatus CachedOCSP::check(const CertificateCollection &certs)
+{
+ OCSPCachedStatus db_status;
+ time_t now;
+ time(&now);
+
+ db_status.cert_chain = certs.toBase64String();
+ db_status.end_entity_check = false;
+
+ if (CertificateCacheDAO::getOCSPStatus(&db_status)) {
+ LogDebug("Found cache entry for OCSP");
+ if (now < db_status.next_update_time) {
+ LogDebug("Cache response valid");
+ return db_status.ocsp_status;
+ }
+ }
+
+ // here we need to get OCSP result and add/update cache
+ OCSP ocsp;
+ CertificateList list = certs.getChain();
+ ocsp.setTrustedStore(list);
+
+ VerificationStatusSet statusSet = ocsp.validateCertificateList(list);
+ db_status.ocsp_status = statusSet.convertToStatus();
+ db_status.next_update_time = ocsp.getResponseValidity();
+ CertificateCacheDAO::setOCSPStatus(db_status.cert_chain,
+ db_status.ocsp_status,
+ db_status.end_entity_check,
+ getNextUpdateTime(
+ now,
+ db_status.next_update_time));
+ return db_status.ocsp_status;
+}
+
+VerificationStatus CachedOCSP::checkEndEntity(CertificateCollection &certs)
+{
+ OCSPCachedStatus db_status;
+ time_t now;
+ time(&now);
+
+ db_status.cert_chain = certs.toBase64String();
+ db_status.end_entity_check = true;
+
+ if (CertificateCacheDAO::getOCSPStatus(&db_status)) {
+ LogDebug("Found cache entry for OCSP");
+ if (now < db_status.next_update_time) {
+ LogDebug("Cache response valid");
+ return db_status.ocsp_status;
+ }
+ }
+
+ // here we need to send request via OCSP and add/update cache
+ CertificateList clst;
+ getCertsForEndEntity(certs, &clst);
+
+ OCSP ocsp;
+ ocsp.setTrustedStore(certs.getCertificateList());
+
+ const char *defResponderURI = getenv(OCSP::DEFAULT_RESPONDER_URI_ENV);
+
+ if (defResponderURI) {
+ ocsp.setUseDefaultResponder(true);
+ ocsp.setDefaultResponder(defResponderURI);
+ }
+
+ VerificationStatusSet statusSet = ocsp.validateCertificateList(clst);
+ db_status.ocsp_status = statusSet.convertToStatus();
+ db_status.next_update_time = ocsp.getResponseValidity();
+
+ CertificateCacheDAO::setOCSPStatus(db_status.cert_chain,
+ db_status.ocsp_status,
+ db_status.end_entity_check,
+ getNextUpdateTime(
+ now,
+ db_status.next_update_time));
+
+ return db_status.ocsp_status;
+}
+
+void CachedOCSP::updateCache()
+{
+ time_t now;
+ time(&now);
+ now += OCSP_refreshBefore;
+ OCSPCachedStatusList list;
+ CertificateCacheDAO::getOCSPStatusList(&list);
+ FOREACH(db_status, list) {
+ if (now >= db_status->next_update_time) {
+ // this response needs to be refreshed
+ // TODO: check result? update even errors? need to check RFC
+ CertificateCollection col;
+ col.load(db_status->cert_chain);
+
+ OCSP ocsp;
+ CertificateList chain = col.getChain();
+ ocsp.setTrustedStore(chain);
+
+ VerificationStatusSet statusSet;
+
+ if (db_status->end_entity_check) {
+ CertificateList clst;
+ getCertsForEndEntity(col, &clst);
+ statusSet = ocsp.validateCertificateList(clst);
+ } else {
+ statusSet = ocsp.validateCertificateList(chain);
+ }
+
+ db_status->ocsp_status = statusSet.convertToStatus();
+ db_status->next_update_time = ocsp.getResponseValidity();
+
+ CertificateCacheDAO::setOCSPStatus(db_status->cert_chain,
+ db_status->ocsp_status,
+ db_status->end_entity_check,
+ db_status->next_update_time);
+ }
+ }
+}
+
+void CachedOCSP::getCertsForEndEntity(
+ const CertificateCollection &certs, CertificateList* clst)
+{
+ if (NULL == clst) {
+ LogError("NULL pointer");
+ return;
+ }
+
+ if (certs.isChain() && certs.size() >= 2) {
+ CertificateList::const_iterator icert = certs.begin();
+ clst->push_back(*icert);
+ ++icert;
+ clst->push_back(*icert);
+ }
+}
+
+time_t CachedOCSP::getNextUpdateTime(time_t now, time_t response_validity)
+{
+ long min = now + OCSP_minTimeValid;
+ long max = now + OCSP_maxTimeValid;
+ if (response_validity < min) {
+ return min;
+ }
+ if (response_validity > max) {
+ return max;
+ }
+ return response_validity;
+}
+
+} // namespace ValidationCore
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ *
+ * @file CachedOCSP.h
+ * @author Tomasz Swierczek (t.swierczek@samsung.com)
+ * @version 0.1
+ * @brief Header file for smart cached OCSP class
+ */
+
+#ifndef _SRC_VALIDATION_CORE_CACHED_OCSP_
+#define _SRC_VALIDATION_CORE_CACHED_OCSP_
+
+#include "OCSP.h"
+#include "IAbstractResponseCache.h"
+
+namespace ValidationCore {
+
+class CachedOCSP : public IAbstractResponseCache {
+ public:
+ // cache can't be refreshed more frequently than OCSP_minTimeValid
+ static const time_t OCSP_minTimeValid;
+
+ // to be even more secure, cache will be refreshed for certificate at least
+ // after OCSP_minTimeValid from last response
+ static const time_t OCSP_maxTimeValid;
+
+ // upon cache refresh, responses that will be invalid in OCSP_refreshBefore
+ // seconds will be refreshed
+ static const time_t OCSP_refreshBefore;
+
+ VerificationStatus check(const CertificateCollection &certs);
+ VerificationStatus checkEndEntity(CertificateCollection &certs);
+ void updateCache();
+
+ CachedOCSP()
+ {
+ }
+ virtual ~CachedOCSP()
+ {
+ }
+
+ private:
+
+ void getCertsForEndEntity(const CertificateCollection &certs,
+ CertificateList* clst);
+ time_t getNextUpdateTime(time_t now, time_t response_validity);
+};
+
+} // namespace ValidationCore
+
+#endif /* _SRC_VALIDATION_CORE_CACHED_OCSP_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file
+ * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 1.0
+ * @brief
+ */
+#ifndef _WRT_ENGINE_SRC_INSTALLER_CORE_VALIDATION_CORE_CERTSTORETYPE_H_
+#define _WRT_ENGINE_SRC_INSTALLER_CORE_VALIDATION_CORE_CERTSTORETYPE_H_
+
+namespace ValidationCore {
+namespace CertStoreId {
+typedef unsigned int Type;
+
+// RootCA certificates for developer mode.
+const Type DEVELOPER = 1;
+// RootCA certificates for author signatures.
+const Type WAC_PUBLISHER = 1 << 1;
+// RootCA certificates for wac-signed widgets.
+const Type WAC_ROOT = 1 << 2;
+// RootCA certificates for wac-members ie. operators, manufacturers.
+const Type WAC_MEMBER = 1 << 3;
+
+class Set
+{
+ public:
+ Set() :
+ m_certificateStorage(0)
+ {
+ }
+
+ void add(Type second)
+ {
+ m_certificateStorage |= second;
+ }
+
+ bool contains(Type second) const
+ {
+ return static_cast<bool>(m_certificateStorage & second);
+ }
+
+ bool isEmpty() const
+ {
+ return m_certificateStorage == 0;
+ }
+
+ private:
+ Type m_certificateStorage;
+};
+} // namespace CertStoreId
+} // namespace ValidationCore
+
+#endif // _WRT_ENGINE_SRC_INSTALLER_CORE_VALIDATION_CORE_CERTSTORETYPE_H_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file
+ * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 1.0
+ * @brief
+ */
+#include "Certificate.h"
+
+#include <openssl/x509v3.h>
+
+#include <dpl/assert.h>
+#include <dpl/log/log.h>
+
+#include <Base64.h>
+
+namespace ValidationCore {
+
+int asn1TimeToTimeT(ASN1_TIME *t,
+ time_t *res)
+{
+ struct tm tm;
+ int offset;
+
+ (*res) = 0;
+ if (!ASN1_TIME_check(t)) {
+ return -1;
+ }
+
+ memset(&tm, 0, sizeof(tm));
+
+#define g2(p) (((p)[0] - '0') * 10 + (p)[1] - '0')
+ if (t->type == V_ASN1_UTCTIME) {
+ Assert(t->length > 12);
+
+ /* this code is copied from OpenSSL asn1/a_utctm.c file */
+ tm.tm_year = g2(t->data);
+ if (tm.tm_year < 50) {
+ tm.tm_year += 100;
+ }
+ tm.tm_mon = g2(t->data + 2) - 1;
+ tm.tm_mday = g2(t->data + 4);
+ tm.tm_hour = g2(t->data + 6);
+ tm.tm_min = g2(t->data + 8);
+ tm.tm_sec = g2(t->data + 10);
+ if (t->data[12] == 'Z') {
+ offset = 0;
+ } else {
+ Assert(t->length > 16);
+
+ offset = g2(t->data + 13) * 60 + g2(t->data + 15);
+ if (t->data[12] == '-') {
+ offset = -offset;
+ }
+ }
+ tm.tm_isdst = -1;
+ } else {
+ Assert(t->length > 14);
+
+ tm.tm_year = g2(t->data) * 100 + g2(t->data + 2);
+ tm.tm_mon = g2(t->data + 4) - 1;
+ tm.tm_mday = g2(t->data + 6);
+ tm.tm_hour = g2(t->data + 8);
+ tm.tm_min = g2(t->data + 10);
+ tm.tm_sec = g2(t->data + 12);
+ if (t->data[14] == 'Z') {
+ offset = 0;
+ } else {
+ Assert(t->length > 18);
+
+ offset = g2(t->data + 15) * 60 + g2(t->data + 17);
+ if (t->data[14] == '-') {
+ offset = -offset;
+ }
+ }
+ tm.tm_isdst = -1;
+ }
+#undef g2
+ (*res) = timegm(&tm) - offset * 60;
+ return 0;
+}
+
+int asn1GeneralizedTimeToTimeT(ASN1_GENERALIZEDTIME *tm,
+ time_t *res)
+{
+ /*
+ * This code is based on following assumption:
+ * from openssl/a_gentm.c:
+ * GENERALIZEDTIME is similar to UTCTIME except the year is
+ * represented as YYYY. This stuff treats everything as a two digit
+ * field so make first two fields 00 to 99
+ */
+ const int DATE_BUFFER_LENGTH = 15; // YYYYMMDDHHMMSSZ
+
+ if (NULL == res || NULL == tm) {
+ LogError("NULL pointer");
+ return -1;
+ }
+
+ if (DATE_BUFFER_LENGTH != tm->length || NULL == tm->data) {
+ LogError("Invalid ASN1_GENERALIZEDTIME");
+ return -1;
+ }
+
+ struct tm time_s;
+ if (sscanf ((char*)tm->data,
+ "%4d%2d%2d%2d%2d%2d",
+ &time_s.tm_year,
+ &time_s.tm_mon,
+ &time_s.tm_mday,
+ &time_s.tm_hour,
+ &time_s.tm_min,
+ &time_s.tm_sec) < 6)
+ {
+ LogError("Could not extract time data from ASN1_GENERALIZEDTIME");
+ return -1;
+ }
+
+ time_s.tm_year -= 1900;
+ time_s.tm_mon -= 1;
+ time_s.tm_isdst = 0; // UTC
+ time_s.tm_gmtoff = 0; // UTC
+ time_s.tm_zone = NULL; // UTC
+
+ *res = mktime(&time_s);
+
+ return 0;
+}
+
+Certificate::Certificate(X509 *cert)
+{
+ Assert(cert);
+ m_x509 = X509_dup(cert);
+ if (!m_x509) {
+ LogWarning("Internal Openssl error in d2i_X509 function.");
+ ThrowMsg(Exception::OpensslInternalError,
+ "Internal Openssl error in d2i_X509 function.");
+ }
+}
+
+Certificate::Certificate(cert_svc_mem_buff &buffer)
+{
+ Assert(buffer.data);
+ const unsigned char *ptr = buffer.data;
+ m_x509 = d2i_X509(NULL, &ptr, buffer.size);
+ if (!m_x509) {
+ LogWarning("Internal Openssl error in d2i_X509 function.");
+ ThrowMsg(Exception::OpensslInternalError,
+ "Internal Openssl error in d2i_X509 function.");
+ }
+}
+
+Certificate::Certificate(const std::string &der,
+ Certificate::FormType form)
+{
+ Assert(der.size());
+
+ int size;
+ const unsigned char *ptr;
+ std::string tmp;
+
+ if (FORM_BASE64 == form) {
+ Base64Decoder base64;
+ base64.reset();
+ base64.append(der);
+ base64.finalize();
+ tmp = base64.get();
+ ptr = reinterpret_cast<const unsigned char*>(tmp.c_str());
+ size = static_cast<int>(tmp.size());
+ } else {
+ ptr = reinterpret_cast<const unsigned char*>(der.c_str());
+ size = static_cast<int>(der.size());
+ }
+
+ m_x509 = d2i_X509(NULL, &ptr, size);
+ if (!m_x509) {
+ LogError("Internal Openssl error in d2i_X509 function.");
+ ThrowMsg(Exception::OpensslInternalError,
+ "Internal Openssl error in d2i_X509 function.");
+ }
+}
+
+Certificate::~Certificate()
+{
+ X509_free(m_x509);
+}
+
+X509* Certificate::getX509(void) const
+{
+ return m_x509;
+}
+
+std::string Certificate::getDER(void) const
+{
+ unsigned char *rawDer = NULL;
+ int size = i2d_X509(m_x509, &rawDer);
+ if (!rawDer || size <= 0) {
+ LogError("i2d_X509 failed");
+ ThrowMsg(Exception::OpensslInternalError,
+ "i2d_X509 failed");
+ }
+
+ std::string output(reinterpret_cast<char*>(rawDer), size);
+ OPENSSL_free(rawDer);
+ return output;
+}
+
+std::string Certificate::getBase64(void) const
+{
+ Base64Encoder base64;
+ base64.reset();
+ base64.append(getDER());
+ base64.finalize();
+ return base64.get();
+}
+
+bool Certificate::isSignedBy(const CertificatePtr &parent) const
+{
+ if (!parent) {
+ LogDebug("Invalid certificate parameter.");
+ return false;
+ }
+ return 0 == X509_NAME_cmp(X509_get_subject_name(parent->m_x509),
+ X509_get_issuer_name(m_x509));
+}
+
+Certificate::Fingerprint Certificate::getFingerprint(
+ Certificate::FingerprintType type) const
+{
+ size_t fingerprintlength = EVP_MAX_MD_SIZE;
+ unsigned char fingerprint[EVP_MAX_MD_SIZE];
+ Fingerprint raw;
+
+ if (type == FINGERPRINT_MD5) {
+ if (!X509_digest(m_x509, EVP_md5(), fingerprint, &fingerprintlength)) {
+ LogError("MD5 digest counting failed!");
+ ThrowMsg(Exception::OpensslInternalError,
+ "MD5 digest counting failed!");
+ }
+ }
+
+ if (type == FINGERPRINT_SHA1) {
+ if (!X509_digest(m_x509, EVP_sha1(), fingerprint,
+ &fingerprintlength))
+ {
+ LogError("SHA1 digest counting failed");
+ ThrowMsg(Exception::OpensslInternalError,
+ "SHA1 digest counting failed!");
+ }
+ }
+
+ raw.resize(fingerprintlength); // improve performance
+ std::copy(fingerprint, fingerprint + fingerprintlength, raw.begin());
+
+ return raw;
+}
+
+DPL::OptionalString Certificate::getField(FieldType type,
+ int fieldNid) const
+{
+ X509_NAME *subjectName = NULL;
+ switch (type) {
+ case FIELD_ISSUER:
+ subjectName = X509_get_issuer_name(m_x509);
+ break;
+ case FIELD_SUBJECT:
+ subjectName = X509_get_subject_name(m_x509);
+ break;
+ default:
+ Assert("Invalid type");
+ }
+
+ if (!subjectName) {
+ LogError("Error during subject name extraction.");
+ ThrowMsg(Exception::OpensslInternalError,
+ "Error during subject name extraction.");
+ }
+
+ X509_NAME_ENTRY *subjectEntry = NULL;
+
+ DPL::Optional < DPL::String > output;
+
+ int entryCount = X509_NAME_entry_count(subjectName);
+
+ for (int i = 0; i < entryCount; ++i) {
+ subjectEntry = X509_NAME_get_entry(subjectName,
+ i);
+
+ if (!subjectEntry) {
+ continue;
+ }
+
+ int nid = OBJ_obj2nid(
+ static_cast<ASN1_OBJECT*>(
+ X509_NAME_ENTRY_get_object(subjectEntry)));
+
+ if (nid != fieldNid) {
+ continue;
+ }
+
+ ASN1_STRING* pASN1Str = subjectEntry->value;
+
+ unsigned char* pData = NULL;
+ int nLength = ASN1_STRING_to_UTF8(&pData,
+ pASN1Str);
+
+ if (nLength < 0) {
+ LogError("Reading field error.");
+ ThrowMsg(Exception::OpensslInternalError,
+ "Reading field error.");
+ }
+
+ std::string strEntry(reinterpret_cast<char*>(pData),
+ nLength);
+ output = DPL::FromUTF8String(strEntry);
+ OPENSSL_free(pData);
+ }
+ return output;
+}
+
+DPL::OptionalString Certificate::getCommonName(FieldType type) const
+{
+ return getField(type, NID_commonName);
+}
+
+DPL::OptionalString Certificate::getCountryName(FieldType type) const
+{
+ return getField(type, NID_countryName);
+}
+
+DPL::OptionalString Certificate::getStateOrProvinceName(FieldType type) const
+{
+ return getField(type, NID_stateOrProvinceName);
+}
+
+DPL::OptionalString Certificate::getLocalityName(FieldType type) const
+{
+ return getField(type, NID_localityName);
+}
+
+DPL::OptionalString Certificate::getOrganizationName(FieldType type) const
+{
+ return getField(type, NID_organizationName);
+}
+
+DPL::OptionalString Certificate::getOrganizationalUnitName(FieldType type) const
+{
+ return getField(type, NID_organizationalUnitName);
+}
+
+DPL::OptionalString Certificate::getOCSPURL() const
+{
+ // TODO verify this code
+ DPL::OptionalString retValue;
+ AUTHORITY_INFO_ACCESS *aia = static_cast<AUTHORITY_INFO_ACCESS*>(
+ X509_get_ext_d2i(m_x509,
+ NID_info_access,
+ NULL,
+ NULL));
+
+ // no AIA extension in the cert
+ if (NULL == aia) {
+ return retValue;
+ }
+
+ int count = sk_ACCESS_DESCRIPTION_num(aia);
+
+ for (int i = 0; i < count; ++i) {
+ ACCESS_DESCRIPTION* ad = sk_ACCESS_DESCRIPTION_value(aia, i);
+
+ if (OBJ_obj2nid(ad->method) == NID_ad_OCSP &&
+ ad->location->type == GEN_URI)
+ {
+ void* data = ASN1_STRING_data(ad->location->d.ia5);
+ retValue = DPL::OptionalString(DPL::FromUTF8String(
+ static_cast<char*>(data)));
+
+ break;
+ }
+ }
+ sk_ACCESS_DESCRIPTION_free(aia);
+ return retValue;
+}
+
+Certificate::AltNameSet Certificate::getAlternativeNameDNS() const
+{
+ AltNameSet set;
+
+ GENERAL_NAME *namePart = NULL;
+
+ STACK_OF(GENERAL_NAME)* san =
+ static_cast<STACK_OF(GENERAL_NAME)*>(
+ X509_get_ext_d2i(m_x509,NID_subject_alt_name,NULL,NULL));
+
+ while (sk_GENERAL_NAME_num(san) > 0) {
+ namePart = sk_GENERAL_NAME_pop(san);
+ if (GEN_DNS == namePart->type) {
+ std::string temp =
+ reinterpret_cast<char*>(ASN1_STRING_data(namePart->d.dNSName));
+ DPL::String altDNSName = DPL::FromASCIIString(temp);
+ set.insert(altDNSName);
+ LogDebug("FOUND GEN_DNS: " << temp);
+ } else {
+ LogDebug("FOUND GEN TYPE ID: " << namePart->type);
+ }
+ }
+ return set;
+}
+
+time_t Certificate::getNotAfter() const
+{
+ ASN1_TIME *time = X509_get_notAfter(m_x509);
+ if (!time) {
+ LogError("Reading Not After error.");
+ ThrowMsg(Exception::OpensslInternalError, "Reading Not After error.");
+ }
+ time_t output;
+ if (asn1TimeToTimeT(time, &output)) {
+ LogError("Converting ASN1_time to time_t error.");
+ ThrowMsg(Exception::OpensslInternalError,
+ "Converting ASN1_time to time_t error.");
+ }
+ return output;
+}
+
+bool Certificate::isRootCert()
+{
+ // based on that root certificate has the same subject as issuer name
+ return isSignedBy(this->SharedFromThis());
+}
+
+std::list<std::string>
+Certificate::getCrlUris() const
+{
+ std::list<std::string> result;
+
+ STACK_OF(DIST_POINT)* distPoints =
+ static_cast<STACK_OF(DIST_POINT)*>(
+ X509_get_ext_d2i(
+ getX509(),
+ NID_crl_distribution_points,
+ NULL,
+ NULL));
+ if (!distPoints) {
+ LogDebug("No distribution points in certificate.");
+ return result;
+ }
+
+ int count = sk_DIST_POINT_num(distPoints);
+ for (int i = 0; i < count; ++i) {
+ DIST_POINT* point = sk_DIST_POINT_value(distPoints, i);
+ if (!point) {
+ LogError("Failed to get distribution point.");
+ continue;
+ }
+ if (point->distpoint != NULL &&
+ point->distpoint->name.fullname != NULL)
+ {
+ int countName =
+ sk_GENERAL_NAME_num(point->distpoint->name.fullname);
+ for (int j = 0; j < countName; ++j) {
+ GENERAL_NAME* name = sk_GENERAL_NAME_value(
+ point->distpoint->name.fullname, j);
+ if (name != NULL && GEN_URI == name->type) {
+ char *crlUri =
+ reinterpret_cast<char*>(name->d.ia5->data);
+ if (!crlUri) {
+ LogError("Failed to get URI.");
+ continue;
+ }
+ result.push_back(crlUri);
+ }
+ }
+ }
+ }
+ sk_DIST_POINT_pop_free(distPoints, DIST_POINT_free);
+ return result;
+}
+} // namespace ValidationCore
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file
+ * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 1.0
+ * @brief
+ */
+#ifndef _WRT_ENGINE_SRC_INSTALLER_CORE_VALIDATION_CORE_CERTIFICATE_H_
+#define _WRT_ENGINE_SRC_INSTALLER_CORE_VALIDATION_CORE_CERTIFICATE_H_
+
+#include <list>
+#include <string>
+#include <set>
+#include <vector>
+#include <ctime>
+
+#include <openssl/x509.h>
+
+#include <dpl/exception.h>
+#include <dpl/noncopyable.h>
+#include <dpl/shared_ptr.h>
+#include <dpl/enable_shared_from_this.h>
+#include <dpl/optional.h>
+#include <dpl/optional_typedefs.h>
+#include <dpl/string.h>
+
+#include <cert-service.h>
+
+namespace ValidationCore {
+
+// from OpenSSL asn1/a_utctm.c code
+int asn1TimeToTimeT(ASN1_TIME *t,
+ time_t *res);
+
+
+int asn1GeneralizedTimeToTimeT(ASN1_GENERALIZEDTIME *tm,
+ time_t *res);
+
+class Certificate;
+
+typedef DPL::SharedPtr<Certificate> CertificatePtr;
+typedef std::list<CertificatePtr> CertificateList;
+
+class Certificate : public DPL::EnableSharedFromThis<Certificate>
+{
+ public:
+ typedef std::vector<unsigned char> Fingerprint;
+ typedef DPL::String AltName;
+ typedef std::set<AltName> AltNameSet;
+
+ enum FingerprintType
+ {
+ FINGERPRINT_MD5,
+ FINGERPRINT_SHA1
+ };
+ enum FieldType
+ {
+ FIELD_ISSUER,
+ FIELD_SUBJECT
+ };
+
+ enum FormType
+ {
+ FORM_DER,
+ FORM_BASE64
+ };
+
+ class Exception
+ {
+ public:
+ DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+ DECLARE_EXCEPTION_TYPE(Base, OpensslInternalError)
+ };
+
+ explicit Certificate(X509 *cert);
+
+ explicit Certificate(cert_svc_mem_buff &buffer);
+
+ explicit Certificate(const std::string &der,
+ FormType form = FORM_DER);
+
+ ~Certificate();
+
+ // It returns pointer to internal structure!
+ // Do not free this pointer!
+ X509 *getX509(void) const;
+
+ std::string getDER(void) const;
+
+ std::string getBase64(void) const;
+
+ // This const is cheating here because you have no
+ // guarantee that X509_get_subject_name will not
+ // change X509 object.
+ bool isSignedBy(const CertificatePtr &parent) const;
+
+ Fingerprint getFingerprint(FingerprintType type) const;
+
+ DPL::OptionalString getCommonName(FieldType type = FIELD_SUBJECT) const;
+ DPL::OptionalString getCountryName(FieldType type = FIELD_SUBJECT) const;
+ DPL::OptionalString getStateOrProvinceName(
+ FieldType type = FIELD_SUBJECT) const;
+ DPL::OptionalString getLocalityName(FieldType type = FIELD_SUBJECT) const;
+ DPL::OptionalString getOrganizationName(
+ FieldType type = FIELD_SUBJECT) const;
+ DPL::OptionalString getOrganizationalUnitName(
+ FieldType type = FIELD_SUBJECT) const;
+ DPL::OptionalString getOCSPURL() const;
+
+ // Openssl supports 9 types of alternative name filed.
+ // 4 of them are "string similar" types so it is possible
+ // to create more generic function.
+ AltNameSet getAlternativeNameDNS() const;
+
+ time_t getNotAfter() const;
+
+ /**
+ * @brief This is convenient function.
+ *
+ * @details It can't be const function (however it doesn't change internal
+ * object). For details see #isSignedBy() function description.
+ */
+ bool isRootCert();
+
+ /**
+ * @brief Gets list of CRL distribution's points URIs
+ */
+ std::list<std::string> getCrlUris() const;
+
+ protected:
+ DPL::OptionalString getField(FieldType type,
+ int fieldNid) const;
+
+ X509 *m_x509;
+};
+} // namespace ValidationCore
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ *
+ *
+ * @file CertificateCacheDAO.cpp
+ * @author Tomasz Swierczek (t.swierczek@samsung.com)
+ * @version 0.1
+ * @brief CertificateCacheDAO implementation
+ */
+
+#include "CertificateCacheDAO.h"
+#include "VCorePrivate.h"
+
+#include <dpl/foreach.h>
+#include <dpl/log/log.h>
+#include <dpl/db/orm.h>
+#include <orm_generator_vcore.h>
+#include <vcore/Database.h>
+
+using namespace DPL::DB::ORM;
+using namespace DPL::DB::ORM::vcore;
+
+namespace ValidationCore {
+
+void CertificateCacheDAO::setOCSPStatus(const std::string& cert_chain,
+ VerificationStatus ocsp_status,
+ bool end_entity_check,
+ time_t next_update_time)
+{
+ Try {
+ ScopedTransaction transaction(&ThreadInterface());
+ OCSPCachedStatus status;
+ status.cert_chain = cert_chain;
+ status.end_entity_check = end_entity_check;
+ if (getOCSPStatus(&status)) {
+ // only need to update data in DB
+ Equals<OCSPResponseStorage::cert_chain> e1(
+ DPL::FromUTF8String(cert_chain));
+ Equals<OCSPResponseStorage::end_entity_check> e2(
+ end_entity_check ? 1 : 0);
+
+ OCSPResponseStorage::Row row;
+
+ row.Set_ocsp_status(ocsp_status);
+ row.Set_next_update_time(next_update_time);
+
+ VCORE_DB_UPDATE(update, OCSPResponseStorage, &ThreadInterface())
+ update->Where(And(e1,e2));
+ update->Values(row);
+ update->Execute();
+ } else {
+ // need to insert data
+ OCSPResponseStorage::Row row;
+
+ row.Set_cert_chain(DPL::FromUTF8String(cert_chain));
+ row.Set_ocsp_status(ocsp_status);
+ row.Set_next_update_time(next_update_time);
+ row.Set_end_entity_check(end_entity_check ? 1 : 0);
+
+ VCORE_DB_INSERT(insert, OCSPResponseStorage, &ThreadInterface())
+ insert->Values(row);
+ insert->Execute();
+ }
+ transaction.Commit();
+ } Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(Exception::DatabaseError, "Failed to setOCSPStatus");
+ }
+}
+
+bool CertificateCacheDAO::getOCSPStatus(OCSPCachedStatus* cached_status)
+{
+ if (NULL == cached_status) {
+ LogError("NULL pointer");
+ return false;
+ }
+ Try {
+ Equals<OCSPResponseStorage::cert_chain> e1(
+ DPL::FromUTF8String(cached_status->cert_chain));
+ Equals<OCSPResponseStorage::end_entity_check> e2(
+ cached_status->end_entity_check ? 1 : 0);
+
+ VCORE_DB_SELECT(select, OCSPResponseStorage, &ThreadInterface())
+
+ select->Where(And(e1,e2));
+ std::list<OCSPResponseStorage::Row> rows = select->GetRowList();
+ if (1 == rows.size()) {
+ OCSPResponseStorage::Row row = rows.front();
+ cached_status->ocsp_status = intToVerificationStatus(
+ *(row.Get_ocsp_status()));
+ cached_status->next_update_time = *(row.Get_next_update_time());
+ return true;
+ }
+
+ LogDebug("Cached OCSP status not found");
+ return false;
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(Exception::DatabaseError, "Failed to getOCSPStatus");
+ }
+}
+
+void CertificateCacheDAO::getOCSPStatusList(
+ OCSPCachedStatusList* cached_status_list)
+{
+ if (NULL == cached_status_list) {
+ LogError("NULL pointer");
+ return;
+ }
+ Try {
+ VCORE_DB_SELECT(select, OCSPResponseStorage, &ThreadInterface())
+ typedef std::list<OCSPResponseStorage::Row> RowList;
+ RowList list = select->GetRowList();
+
+ FOREACH(i, list) {
+ OCSPCachedStatus status;
+ status.cert_chain = DPL::ToUTF8String(i->Get_cert_chain());
+ status.ocsp_status = intToVerificationStatus(
+ *(i->Get_ocsp_status()));
+ status.end_entity_check =
+ *(i->Get_end_entity_check()) == 1 ? true : false;
+ status.next_update_time = *(i->Get_next_update_time());
+ cached_status_list->push_back(status);
+ }
+
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(Exception::DatabaseError, "Failed to getOCSPStatusList");
+ }
+}
+
+
+void CertificateCacheDAO::setCRLResponse(const std::string& distribution_point,
+ const std::string& crl_body,
+ time_t next_update_time)
+{
+ Try {
+ ScopedTransaction transaction(&ThreadInterface());
+ CRLCachedData data;
+ data.distribution_point = distribution_point;
+ if (getCRLResponse(&data)) {
+ // only need to update data in DB
+ VCORE_DB_UPDATE(update, CRLResponseStorage, &ThreadInterface())
+ Equals<CRLResponseStorage::distribution_point> e1(
+ DPL::FromUTF8String(distribution_point));
+ CRLResponseStorage::Row row;
+
+ update->Where(e1);
+ row.Set_crl_body(DPL::FromUTF8String(crl_body));
+ row.Set_next_update_time(next_update_time);
+ update->Values(row);
+ update->Execute();
+ } else {
+ // need to insert data
+ VCORE_DB_INSERT(insert, CRLResponseStorage, &ThreadInterface())
+ CRLResponseStorage::Row row;
+
+ row.Set_distribution_point(DPL::FromUTF8String(distribution_point));
+ row.Set_crl_body(DPL::FromUTF8String(crl_body));
+ row.Set_next_update_time(next_update_time);
+ insert->Values(row);
+ insert->Execute();
+ }
+ transaction.Commit();
+ } Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(Exception::DatabaseError, "Failed to setOCSPStatus");
+ }
+}
+
+bool CertificateCacheDAO::getCRLResponse(CRLCachedData* cached_data)
+{
+ if (NULL == cached_data) {
+ LogError("NULL pointer");
+ return false;
+ }
+ Try {
+ VCORE_DB_SELECT(select, CRLResponseStorage, &ThreadInterface())
+ Equals<CRLResponseStorage::distribution_point> e1(
+ DPL::FromUTF8String(cached_data->distribution_point));
+
+ select->Where(e1);
+ std::list<CRLResponseStorage::Row> rows = select->GetRowList();
+ if (1 == rows.size()) {
+ CRLResponseStorage::Row row = rows.front();
+ cached_data->crl_body = DPL::ToUTF8String(row.Get_crl_body());
+ cached_data->next_update_time = *(row.Get_next_update_time());
+ return true;
+ }
+
+ LogDebug("Cached CRL not found");
+ return false;
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(Exception::DatabaseError, "Failed to getCRLResponse");
+ }
+}
+
+void CertificateCacheDAO::getCRLResponseList(
+ CRLCachedDataList* cached_data_list)
+{
+ if (NULL == cached_data_list) {
+ LogError("NULL pointer");
+ return;
+ }
+ Try {
+ VCORE_DB_SELECT(select, CRLResponseStorage, &ThreadInterface())
+ typedef std::list<CRLResponseStorage::Row> RowList;
+ RowList list = select->GetRowList();
+
+ FOREACH(i, list) {
+ CRLCachedData response;
+ response.distribution_point = DPL::ToUTF8String(
+ i->Get_distribution_point());
+ response.crl_body = DPL::ToUTF8String(i->Get_crl_body());
+ response.next_update_time = *(i->Get_next_update_time());
+ cached_data_list->push_back(response);
+ }
+
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(Exception::DatabaseError, "Failed to getCRLResponses");
+ }
+}
+
+void CertificateCacheDAO::clearCertificateCache()
+{
+ Try {
+ ScopedTransaction transaction(&ThreadInterface());
+ VCORE_DB_DELETE(del1, OCSPResponseStorage, &ThreadInterface())
+ del1->Execute();
+ VCORE_DB_DELETE(del2, CRLResponseStorage, &ThreadInterface())
+ del2->Execute();
+ transaction.Commit();
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(Exception::DatabaseError, "Failed to clearUserSettings");
+ }
+}
+
+VerificationStatus CertificateCacheDAO::intToVerificationStatus(int p)
+{
+ switch (p) {
+ case 1:
+ return VERIFICATION_STATUS_GOOD;
+ case 1 << 1:
+ return VERIFICATION_STATUS_REVOKED;
+ case 1 << 2:
+ return VERIFICATION_STATUS_UNKNOWN;
+ case 1 << 3:
+ return VERIFICATION_STATUS_VERIFICATION_ERROR;
+ case 1 << 4:
+ return VERIFICATION_STATUS_NOT_SUPPORT;
+ case 1 << 5:
+ return VERIFICATION_STATUS_CONNECTION_FAILED;
+ case 1 << 6:
+ return VERIFICATION_STATUS_ERROR;
+ default:
+ return VERIFICATION_STATUS_ERROR;
+ }
+}
+
+} // namespace ValidationCore
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ *
+ *
+ * @file CertificateCacheDAO.h
+ * @author Tomasz Swierczek (t.swierczek@samsung.com)
+ * @version 0.1
+ * @brief Header file for class managing CRL and OCSP cached responses
+ */
+
+#ifndef _WRT_SRC_CONFIGURATION_CERTIFICATE_CACHE_DAO_H_
+#define _WRT_SRC_CONFIGURATION_CERTIFICATE_CACHE_DAO_H_
+
+#include <string>
+#include <list>
+
+#include <dpl/exception.h>
+
+#include "VerificationStatus.h"
+
+namespace ValidationCore {
+
+struct OCSPCachedStatus
+{
+ std::string cert_chain;
+ VerificationStatus ocsp_status;
+ bool end_entity_check;
+ time_t next_update_time;
+};
+
+typedef std::list<OCSPCachedStatus> OCSPCachedStatusList;
+
+struct CRLCachedData
+{
+ std::string distribution_point;
+ std::string crl_body;
+ time_t next_update_time;
+};
+
+typedef std::list<CRLCachedData> CRLCachedDataList;
+
+class CertificateCacheDAO {
+ public:
+ class Exception
+ {
+ public:
+ DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+ DECLARE_EXCEPTION_TYPE(Base, DatabaseError)
+ };
+
+ // OCSP statuses
+
+ static void setOCSPStatus(const std::string& cert_chain,
+ VerificationStatus ocsp_status,
+ bool end_entity_check,
+ time_t next_update_time);
+
+ /*
+ * fill cert_chain and end_entity_check in cached_status
+ * returns true iff cached status found without errors
+ */
+ static bool getOCSPStatus(OCSPCachedStatus* cached_status);
+ static void getOCSPStatusList(OCSPCachedStatusList* cached_status_list);
+
+ // CRL responses
+
+ static void setCRLResponse(const std::string& distribution_point,
+ const std::string& crl_body,
+ time_t next_update_time);
+
+ /*
+ * fill distribution_point
+ * returns true iff cached list for dist. point found without errors
+ */
+ static bool getCRLResponse(CRLCachedData* cached_data);
+ static void getCRLResponseList(CRLCachedDataList* cached_data_list);
+
+
+ // clears CRL and OCSP cached data
+ static void clearCertificateCache();
+
+ private:
+
+ static VerificationStatus intToVerificationStatus(int p);
+
+ CertificateCacheDAO()
+ {
+ }
+};
+
+} // namespace ValidationCore
+
+#endif /* _WRT_SRC_CONFIGURATION_CERTIFICATE_CACHE_DAO_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <vcore/CertificateCollection.h>
+
+#include <algorithm>
+
+#include <dpl/binary_queue.h>
+#include <dpl/foreach.h>
+#include <dpl/log/log.h>
+
+#include <vcore/Base64.h>
+
+namespace {
+using namespace ValidationCore;
+
+inline std::string toBinaryString(int data)
+{
+ char buffer[sizeof(int)];
+ memcpy(buffer, &data, sizeof(int));
+ return std::string(buffer, buffer + sizeof(int));
+}
+
+// helper functor for finding certificate basing on subject field
+class SubjectElementFinder
+{
+ public:
+ SubjectElementFinder(CertificatePtr &cert) : m_searchFor(cert)
+ {
+ }
+ bool operator()(const CertificatePtr &cert) const
+ {
+ return cert->isSignedBy(m_searchFor);
+ }
+ void setCert(CertificatePtr &cert)
+ {
+ m_searchFor = cert;
+ }
+
+ private:
+ CertificatePtr m_searchFor;
+};
+
+// helper functor for finding certificate basing on issuer field
+class IssuerElementFinder
+{
+ public:
+ IssuerElementFinder(CertificatePtr &cert) : m_searchFor(cert)
+ {
+ }
+ bool operator()(const CertificatePtr &cert) const
+ {
+ return m_searchFor->isSignedBy(cert);
+ }
+ void setCert(CertificatePtr &cert)
+ {
+ m_searchFor = cert;
+ }
+
+ private:
+ CertificatePtr m_searchFor;
+};
+
+//! Helper function
+// pops an element from list, finder is responsible for match certificates
+template <typename T>
+static CertificatePtr popAnElementFromList(CertificateList& lCertificates,
+ const T& finder)
+{
+ CertificatePtr pOutCertificate;
+ CertificateList::iterator it =
+ std::find_if(lCertificates.begin(), lCertificates.end(), finder);
+
+ if (it != lCertificates.end()) {
+ pOutCertificate = *it;
+ lCertificates.erase(it);
+ }
+
+ return pOutCertificate;
+}
+} // namespace
+
+namespace ValidationCore {
+CertificateCollection::CertificateCollection() :
+ m_collectionStatus(COLLECTION_UNSORTED)
+{
+}
+
+void CertificateCollection::clear(void)
+{
+ m_collectionStatus = COLLECTION_UNSORTED;
+ m_certList.clear();
+}
+
+void CertificateCollection::load(const CertificateList &certList)
+{
+ m_collectionStatus = COLLECTION_UNSORTED;
+ std::copy(certList.begin(),
+ certList.end(),
+ std::back_inserter(m_certList));
+}
+
+bool CertificateCollection::load(const std::string &buffer)
+{
+ Base64Decoder base64;
+ base64.reset();
+ base64.append(buffer);
+ if (!base64.finalize()) {
+ LogWarning("Error during chain decoding");
+ return false;
+ }
+ std::string binaryData = base64.get();
+
+ DPL::BinaryQueue queue;
+ queue.AppendCopy(binaryData.c_str(), binaryData.size());
+
+ int certNum;
+ queue.FlattenConsume(&certNum, sizeof(int));
+
+ CertificateList list;
+
+ for (int i = 0; i < certNum; ++i) {
+ int certSize;
+ queue.FlattenConsume(&certSize, sizeof(int));
+ std::vector<char> rawDERCert;
+ rawDERCert.resize(certSize);
+ queue.FlattenConsume(&rawDERCert[0], certSize);
+ Try {
+ list.push_back(CertificatePtr(
+ new Certificate(std::string(rawDERCert.begin(),
+ rawDERCert.end()))));
+ } Catch(Certificate::Exception::Base) {
+ LogWarning("Error during certificate creation.");
+ return false;
+ }
+ LogDebug("Read certificate from database. Certificate common name: " <<
+ list.back()->getCommonName());
+ }
+ load(list);
+ return true;
+}
+
+std::string CertificateCollection::toBase64String() const
+{
+ std::ostringstream output;
+ int certNum = m_certList.size();
+ output << toBinaryString(certNum);
+ FOREACH(i, m_certList){
+ std::string derCert = (*i)->getDER();
+ output << toBinaryString(derCert.size());
+ output << derCert;
+ }
+ Base64Encoder base64;
+ base64.reset();
+ base64.append(output.str());
+ base64.finalize();
+ return base64.get();
+}
+
+CertificateList CertificateCollection::getCertificateList() const
+{
+ return m_certList;
+}
+
+bool CertificateCollection::isChain() const
+{
+ if (COLLECTION_SORTED != m_collectionStatus) {
+ LogError("You must sort certificates first");
+ ThrowMsg(Exception::WrongUsage,
+ "You must sort certificates first");
+ }
+ return (COLLECTION_SORTED == m_collectionStatus) ? true : false;
+}
+
+bool CertificateCollection::sort()
+{
+ if (COLLECTION_UNSORTED == m_collectionStatus) {
+ sortCollection();
+ }
+ return (COLLECTION_SORTED == m_collectionStatus) ? true : false;
+}
+
+CertificateList CertificateCollection::getChain() const
+{
+ if (COLLECTION_SORTED != m_collectionStatus) {
+ LogError("You must sort certificates first");
+ ThrowMsg(Exception::WrongUsage,
+ "You must sort certificates first");
+ }
+ return m_certList;
+}
+
+void CertificateCollection::sortCollection()
+{
+ CertificateList lCertificates = m_certList;
+ // sorting is not necessary
+ if (lCertificates.empty()) {
+ m_collectionStatus = COLLECTION_SORTED;
+ return;
+ }
+
+ // backup input list
+ CertificateList lBackup = lCertificates;
+
+ // create a new output list
+ CertificateList lSortedCertificates;
+
+ CertificatePtr pCertificate = lCertificates.front();
+
+ lCertificates.pop_front();
+ lSortedCertificates.push_back(pCertificate);
+
+ // indicates whether any matching certificate was found
+ bool bFound = false;
+
+ CertificatePtr pSubjectCert = pCertificate;
+
+ // lCertificates is very short (3 elements) so
+ // O(n^2) algorithm is good enough.
+ if (!lCertificates.empty()) {
+ // First, find all predecessors for, next all successors
+ // for pCertificate
+ SubjectElementFinder subjectFinder(pCertificate);
+ while ((pSubjectCert = popAnElementFromList(lCertificates,
+ subjectFinder)) != NULL) {
+ lSortedCertificates.push_front(pSubjectCert);
+ subjectFinder.setCert(pSubjectCert);
+ bFound = true;
+ }
+
+ CertificatePtr pIssuerCert = pCertificate;
+
+ IssuerElementFinder issuerFinder(pCertificate);
+ while ((pIssuerCert = popAnElementFromList(lCertificates,
+ issuerFinder)) != NULL) {
+ lSortedCertificates.push_back(pIssuerCert);
+ issuerFinder.setCert(pIssuerCert);
+ bFound = true;
+ }
+
+ if (!bFound || !lCertificates.empty()) {
+ // well, those certificates don't form a valid chain
+ LogWarning("Certificates don't form a valid chain");
+ lCertificates = lBackup;
+ m_collectionStatus = COLLECTION_CHAIN_BROKEN;
+ return;
+ }
+ }
+
+ m_certList = lSortedCertificates;
+ m_collectionStatus = COLLECTION_SORTED;
+}
+} // namespace ValidationCore
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_ENGINE_SRC_VALIDATION_CORE_CERTIFICATECOLLECTION_H_
+#define _WRT_ENGINE_SRC_VALIDATION_CORE_CERTIFICATECOLLECTION_H_
+
+#include <list>
+#include <string>
+
+#include <dpl/exception.h>
+
+#include <vcore/Certificate.h>
+
+namespace ValidationCore {
+/*
+ * This class is used to store Certificate Chain.
+ * It could serialize chain to std::string in base64 form.
+ * It could read chain written in base64 form.
+ * It could check if collection creates certificate chain.
+ */
+
+class CertificateCollection
+{
+ public:
+ class Exception
+ {
+ public:
+ DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+ DECLARE_EXCEPTION_TYPE(Base, WrongUsage)
+ };
+
+ CertificateCollection();
+
+ typedef CertificateList::const_iterator const_iterator;
+
+ /*
+ * Remove all certificates from collection.
+ */
+ void clear();
+
+ /*
+ * In current implemenation this function MUST success.
+ *
+ * This function will add new certificate to collection.
+ * This function DOES NOT clean collection.
+ */
+ void load(const CertificateList &certList);
+
+ /*
+ * This function will return false if base64 string is broken
+ * (is not encoded in base64 format) or one from certificate
+ * is broken (is not encoded in der format).
+ *
+ * This function will add new certificate to collection.
+ * This function DOES NOT clean collection.
+ */
+ bool load(const std::string &base64);
+
+ /*
+ * This function will return all certificates from
+ * collection encoded in base64 format.
+ */
+ std::string toBase64String() const;
+
+ /*
+ * This will return all certificate from collection.
+ */
+ CertificateList getCertificateList() const;
+
+ /*
+ * This function will return true if certificates
+ * in in this structure were sorted and create
+ * certificate chain.
+
+ * Note: You MUST sort certificates first.
+ */
+ bool isChain() const;
+
+ /*
+ * This function will return true if all certificate are
+ * able to create certificate chain.
+ *
+ * This function will sort certificates if collection
+ * is not sorted.
+ *
+ * Note: This function will make all iterators invalid.
+ */
+ bool sort();
+
+ /*
+ * This function will return Certificate chain.
+ *
+ * Note: You MUST sort certificates first and
+ * check if certificates creates proper chain.
+ */
+ CertificateList getChain() const;
+
+ /*
+ * It returns size of certificate collection.
+ */
+ inline size_t size() const
+ {
+ return m_certList.size();
+ }
+
+ /*
+ * Return true if collection is empty.
+ */
+ inline bool empty() const
+ {
+ return m_certList.empty();
+ }
+
+ /*
+ * This will return end iterator to internal collection.
+ *
+ * Note: this iterator will lose validity if you call non const
+ * method on CertificateCollection class.
+ */
+ inline const_iterator begin() const
+ {
+ return m_certList.begin();
+ }
+
+ /*
+ * This will return end iterator to internal collection.
+ *
+ * Note: this iterator will lose validity if you call non const
+ * method on CertificateCollection class.
+ */
+ inline const_iterator end() const
+ {
+ return m_certList.end();
+ }
+
+ /*
+ * This function will return the last certificate from collection.
+ *
+ * Note: There is no point to call this function if certificate
+ * collection is not sorted!
+ */
+ inline CertificatePtr back() const
+ {
+ return m_certList.back();
+ }
+
+ protected:
+ void sortCollection(void);
+
+ enum CollectionStatus
+ {
+ // Certificate collection are not sorted in any way
+ COLLECTION_UNSORTED,
+ // Certificate collection creates certificate chain
+ COLLECTION_SORTED,
+ // Cerfificate collection is not able to create certificate chain
+ COLLECTION_CHAIN_BROKEN,
+ };
+
+ CollectionStatus m_collectionStatus;
+ CertificateList m_certList;
+};
+
+typedef std::list<CertificateCollection> CertificateCollectionList;
+} // namespace ValidationCore
+
+#endif // _WRT_ENGINE_SRC_VALIDATION_CORE_CERTIFICATECHAIN_H_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file
+ * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 1.0
+ * @brief
+ */
+#include "CertificateConfigReader.h"
+
+#include <cstdlib>
+
+#include <dpl/assert.h>
+
+namespace {
+const std::string XML_EMPTY_NAMESPACE = "";
+
+const std::string TOKEN_CERTIFICATE_SET = "CertificateSet";
+const std::string TOKEN_CERTIFICATE_DOMAIN = "CertificateDomain";
+const std::string TOKEN_FINGERPRINT_SHA1 = "FingerprintSHA1";
+
+const std::string TOKEN_ATTR_NAME = "name";
+const std::string TOKEN_VALUE_WAC_ROOT = "wacroot";
+const std::string TOKEN_VALUE_WAC_PUBLISHER = "wacpublisher";
+const std::string TOKEN_VALUE_WAC_MEMBER = "wacmember";
+const std::string TOKEN_VALUE_DEVELOPER = "developer";
+
+int hexCharToInt(char c)
+{
+ if (c >= 'a' && c <= 'f') {
+ return 10 + static_cast<int>(c) - 'a';
+ }
+ if (c >= 'A' && c <= 'F') {
+ return 10 + static_cast<int>(c) - 'A';
+ }
+ if (c >= '0' && c <= '9') {
+ return static_cast<int>(c) - '0';
+ }
+ return c;
+}
+} // anonymous namespace
+
+namespace ValidationCore {
+CertificateConfigReader::CertificateConfigReader() :
+ m_certificateDomain(0),
+ m_parserSchema(this)
+{
+ m_parserSchema.addBeginTagCallback(
+ TOKEN_CERTIFICATE_SET,
+ XML_EMPTY_NAMESPACE,
+ &CertificateConfigReader::blankFunction);
+
+ m_parserSchema.addBeginTagCallback(
+ TOKEN_CERTIFICATE_DOMAIN,
+ XML_EMPTY_NAMESPACE,
+ &CertificateConfigReader::tokenCertificateDomain);
+
+ m_parserSchema.addBeginTagCallback(
+ TOKEN_FINGERPRINT_SHA1,
+ XML_EMPTY_NAMESPACE,
+ &CertificateConfigReader::blankFunction);
+
+ m_parserSchema.addEndTagCallback(
+ TOKEN_CERTIFICATE_SET,
+ XML_EMPTY_NAMESPACE,
+ &CertificateConfigReader::blankFunction);
+
+ m_parserSchema.addEndTagCallback(
+ TOKEN_CERTIFICATE_DOMAIN,
+ XML_EMPTY_NAMESPACE,
+ &CertificateConfigReader::blankFunction);
+
+ m_parserSchema.addEndTagCallback(
+ TOKEN_FINGERPRINT_SHA1,
+ XML_EMPTY_NAMESPACE,
+ &CertificateConfigReader::tokenEndFingerprintSHA1);
+}
+
+void CertificateConfigReader::tokenCertificateDomain(CertificateIdentifier &)
+{
+ std::string name = m_parserSchema.getReader().
+ attribute(TOKEN_ATTR_NAME, SaxReader::THROW_DISABLE);
+
+ if (name.empty()) {
+ LogWarning("Invalid fingerprint file. Domain name is mandatory");
+ ThrowMsg(Exception::InvalidFile,
+ "Invalid fingerprint file. Domain name is mandatory");
+ } else if (name == TOKEN_VALUE_DEVELOPER) {
+ m_certificateDomain = CertStoreId::DEVELOPER;
+ } else if (name == TOKEN_VALUE_WAC_ROOT) {
+ m_certificateDomain = CertStoreId::WAC_ROOT;
+ } else if (name == TOKEN_VALUE_WAC_PUBLISHER) {
+ m_certificateDomain = CertStoreId::WAC_PUBLISHER;
+ } else if (name == TOKEN_VALUE_WAC_MEMBER) {
+ m_certificateDomain = CertStoreId::WAC_MEMBER;
+ }
+}
+
+void CertificateConfigReader::tokenEndFingerprintSHA1(
+ CertificateIdentifier &identificator)
+{
+ std::string text = m_parserSchema.getText();
+ text += ":"; // add guard at the end of fingerprint
+ Certificate::Fingerprint fingerprint;
+ int s = 0;
+ int byteDescLen = 0;
+ for (size_t i = 0; i < text.size(); ++i) {
+ if (isxdigit(text[i])) {
+ s <<= 4;
+ s += hexCharToInt(text[i]);
+ byteDescLen++;
+ if (byteDescLen > 2) {
+ Assert(0 && "Unsupported fingerprint format in xml file.");
+ }
+ } else if (text[i] == ':') {
+ fingerprint.push_back(static_cast<unsigned char>(s));
+ s = 0;
+ byteDescLen = 0;
+ } else {
+ Assert(0 && "Unussported fingerprint format in xml file.");
+ }
+ }
+ identificator.add(fingerprint, m_certificateDomain);
+}
+} // namespace ValidationCore
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file
+ * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 1.0
+ * @brief
+ */
+#ifndef \
+ _WRT_ENGINE_SRC_INSTALLER_CORE_VALIDATION_CORE_CERTIFICATE_CONFIG_READER_H_
+#define \
+ _WRT_ENGINE_SRC_INSTALLER_CORE_VALIDATION_CORE_CERTIFICATE_CONFIG_READER_H_
+
+#include <string>
+#include <dpl/exception.h>
+
+#include "CertificateIdentifier.h"
+#include "CertStoreType.h"
+#include "ParserSchema.h"
+
+namespace ValidationCore {
+class CertificateConfigReader
+{
+ public:
+ class Exception
+ {
+ public:
+ DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+ DECLARE_EXCEPTION_TYPE(Base, InvalidFile)
+ };
+ CertificateConfigReader();
+
+ void initialize(const std::string &file,
+ const std::string &scheme)
+ {
+ m_parserSchema.initialize(file, true, SaxReader::VALIDATION_XMLSCHEME,
+ scheme);
+ }
+
+ void read(CertificateIdentifier &identificator)
+ {
+ m_parserSchema.read(identificator);
+ }
+
+ private:
+ void blankFunction(CertificateIdentifier &)
+ {
+ }
+ void tokenCertificateDomain(CertificateIdentifier &identificator);
+ void tokenEndFingerprintSHA1(CertificateIdentifier &identificator);
+
+ CertStoreId::Type m_certificateDomain;
+ ParserSchema<CertificateConfigReader, CertificateIdentifier>
+ m_parserSchema;
+};
+} // namespace ValidationCore
+
+#endif // _WRT_ENGINE_SRC_INSTALLER_CORE_VALIDATION_CORE_CERTIFICATE_CONFIG_READER_H_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file
+ * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 1.0
+ * @brief
+ */
+#ifndef \
+ _WRT_ENGINE_SRC_INSTALLER_CORE_VALIDATION_CORE_CERTIFICATEIDENTIFICATOR_H_
+#define \
+ _WRT_ENGINE_SRC_INSTALLER_CORE_VALIDATION_CORE_CERTIFICATEIDENTIFICATOR_H_
+
+#include <map>
+
+#include <dpl/noncopyable.h>
+
+#include "Certificate.h"
+#include "CertStoreType.h"
+
+namespace ValidationCore {
+class CertificateIdentifier : public DPL::Noncopyable
+{
+ public:
+ typedef std::map<Certificate::Fingerprint, CertStoreId::Set> FingerPrintMap;
+
+ CertificateIdentifier()
+ {
+ }
+ ~CertificateIdentifier()
+ {
+ }
+
+ void add(const Certificate::Fingerprint &fingerprint,
+ CertStoreId::Type domain)
+ {
+ fingerPrintMap[fingerprint].add(domain);
+ }
+
+ CertStoreId::Set find(const Certificate::Fingerprint &fingerprint) const
+ {
+ FingerPrintMap::const_iterator iter = fingerPrintMap.find(fingerprint);
+ if (iter == fingerPrintMap.end()) {
+ return CertStoreId::Set();
+ }
+ return iter->second;
+ }
+
+ CertStoreId::Set find(const CertificatePtr &certificate) const
+ {
+ return
+ find(certificate->getFingerprint(Certificate::FINGERPRINT_SHA1));
+ }
+
+ private:
+ FingerPrintMap fingerPrintMap;
+};
+} // namespace ValidationCore
+
+#endif // _WRT_ENGINE_SRC_INSTALLER_CORE_VALIDATION_CORE_CERTIFICATEIDENTIFICATOR_H_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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/assert.h>
+#include <openssl/x509v3.h>
+#include <dpl/log/log.h>
+#include <dpl/noncopyable.h>
+#include <openssl/ecdsa.h>
+#include <openssl/evp.h>
+
+#include "Base64.h"
+#include "CertificateLoader.h"
+#include "SSLContainers.h"
+
+namespace {
+const int MIN_RSA_KEY_LENGTH = 1024;
+//const char *OID_CURVE_SECP256R1 = "urn:oid:1.2.840.10045.3.1.7";
+} // namespace anonymous
+
+namespace ValidationCore {
+//// COMPARATOR CLASS START ////
+
+//class CertificateLoaderECDSA : public CertificateLoader::CertificateLoaderComparator, DPL::Noncopyable {
+//public:
+// CertificateLoaderECDSA(const std::string &publicKey)
+// : m_ecPublicKey(NULL)
+// , m_searchKey(NULL)
+// {
+// m_bnCtx = BN_CTX_new(); // if fails we can continue anyway
+// m_tmpPoint = BN_new(); // if fails we can continue anyway
+// m_initialized = CertificateLoader::convertBase64NodeToBigNum(publicKey, &m_searchKey);
+//
+// if(!m_initialized)
+// LogError("Init failed!");
+// }
+//
+// virtual bool compare(X509 *x509cert){
+// if(!m_initialized)
+// return false;
+//
+// EVP_PKEY_free(m_ecPublicKey);
+//
+// m_ecPublicKey = X509_get_pubkey(x509cert);
+//
+// if(m_ecPublicKey == NULL)
+// return false;
+//
+// if(m_ecPublicKey->type != EVP_PKEY_EC){
+// LogError("ecPublicKey has wrong type!");
+// return false;
+// }
+//
+// // Pointer to internal data of ecPublicKey. Do not free!
+// EC_KEY *eckey = m_ecPublicKey->pkey.ec;
+//
+// const EC_POINT *ecpoint = EC_KEY_get0_public_key(eckey);
+// const EC_GROUP *ecgroup = EC_KEY_get0_group(eckey);
+//
+// m_tmpPoint = EC_POINT_point2bn(ecgroup, ecpoint, POINT_CONVERSION_UNCOMPRESSED, m_tmpPoint, m_bnCtx);
+//
+// if(BN_cmp(m_tmpPoint, m_searchKey) == 0)
+// return true;
+//
+// return false;
+// }
+//
+// ~CertificateLoaderECDSA(){
+// BN_CTX_free(m_bnCtx);
+// EVP_PKEY_free(m_ecPublicKey);
+// BN_free(m_searchKey);
+// BN_free(m_tmpPoint);
+// }
+//
+//private:
+// bool m_initialized;
+// EVP_PKEY *m_ecPublicKey;
+// BN_CTX *m_bnCtx;
+// BIGNUM *m_searchKey;
+// BIGNUM *m_tmpPoint;
+//};
+
+///// COMPARETORS CLASS END /////
+
+//// COMPARATOR RSA CLASS START ////
+
+//class CertificateLoaderRSA : public CertificateLoader::CertificateLoaderComparator, DPL::Noncopyable {
+//public:
+// CertificateLoaderRSA(const std::string &m_modulus,const std::string &m_exponent )
+// : m_rsaPublicKey(NULL)
+// , m_modulus_bn(NULL)
+// , m_exponent_bn(NULL)
+// {
+//
+// m_initialized_modulus = CertificateLoader::convertBase64NodeToBigNum(m_modulus, &m_modulus_bn);
+// m_initialized_exponent = CertificateLoader::convertBase64NodeToBigNum(m_exponent, &m_exponent_bn);
+//
+// if(!m_initialized_modulus || !m_initialized_exponent)
+// LogError("Init failed!");
+// }
+//
+// virtual bool compare(X509 *x509cert){
+//
+// if(!m_initialized_modulus || !m_initialized_exponent)
+// return false;
+//
+// EVP_PKEY_free(m_rsaPublicKey);
+// m_rsaPublicKey = X509_get_pubkey(x509cert);
+//
+// if(m_rsaPublicKey == NULL)
+// return false;
+//
+// if(m_rsaPublicKey->type != EVP_PKEY_RSA){
+// LogInfo("rsaPublicKey has wrong type!");
+// return false;
+// }
+//
+// RSA *rsa = NULL;
+// rsa = m_rsaPublicKey->pkey.rsa;
+//
+// if (BN_cmp(m_modulus_bn, rsa->n) == 0 &&
+// BN_cmp(m_exponent_bn, rsa->e) == 0 ){
+// LogError ("Compare TRUE");
+// return true;
+// }
+// return false;
+// }
+//
+// ~CertificateLoaderRSA(){
+// EVP_PKEY_free(m_rsaPublicKey);
+// BN_free(m_modulus_bn);
+// BN_free(m_exponent_bn);
+//
+// }
+//
+//private:
+// bool m_initialized_modulus;
+// bool m_initialized_exponent;
+// EVP_PKEY *m_rsaPublicKey;
+// BIGNUM *m_modulus_bn;
+// BIGNUM *m_exponent_bn;
+//};
+
+///// COMPARETORS RSA CLASS END /////
+
+CertificateLoader::CertificateLoaderResult CertificateLoader::
+ loadCertificateBasedOnExponentAndModulus(const std::string &m_modulus,
+ const std::string &m_exponent)
+{
+ (void) m_modulus;
+ (void) m_exponent;
+ LogError("Not implemented.");
+ return UNKNOWN_ERROR;
+ // if (m_exponent.empty() || m_modulus.empty())
+ // return WRONG_ARGUMENTS;
+ //
+ // CertificateLoaderRSA comparator(m_modulus,m_exponent);
+ //
+ // CertificateLoaderResult result = NO_ERROR;
+ // for(int i=0; storeId[i]; ++i){
+ // result = loadCertificate(std::string(storeId[i]), &comparator);
+ //
+ // if(result == ERR_NO_MORE_CERTIFICATES)
+ // continue;
+ //
+ // return result;
+ // }
+ //
+ // return result;
+}
+
+CertificateLoader::CertificateLoaderResult CertificateLoader::loadCertificate(
+ const std::string &storageName,
+ CertificateLoader::CertificateLoaderComparator *cmp)
+{
+ (void) storageName;
+ (void) cmp;
+ LogError("Not Implemented");
+ return UNKNOWN_ERROR;
+ // long int result = OPERATION_SUCCESS;
+ //
+ // char storeId[CERTMGR_MAX_PLUGIN_ID_SIZE];
+ // char type[CERTMGR_MAX_CERT_TYPE_SIZE];
+ // certmgr_cert_id certId;
+ // certmgr_ctx context;
+ // certmgr_mem_buff certRetrieved;
+ // unsigned char buffer[CERTMGR_MAX_BUFFER_SIZE];
+ //
+ // certmgr_cert_descriptor descriptor;
+ //
+ // certRetrieved.data = buffer;
+ // certRetrieved.firstFree = 0;
+ // certRetrieved.size = CERTMGR_MAX_BUFFER_SIZE;
+ // certId.storeId = storeId;
+ // certId.type = type;
+ //
+ // CERTMGR_INIT_CONTEXT((&context), (sizeof(context)))
+ //
+ // strncpy(context.storeId, storageName.c_str(), storageName.size());
+ //
+ // for(certRetrieved.firstFree = 0;
+ // OPERATION_SUCCESS == (result = certmgr_retrieve_certificate_from_store(&context, &certRetrieved, &certId));
+ // certRetrieved.firstFree = 0)
+ // {
+ //
+ // if(OPERATION_SUCCESS!=certmgr_extract_certificate_data(&certRetrieved, &descriptor)){
+ // LogError("Extracting Certificate Data failed \n");
+ // continue;
+ // }
+ //
+ // const unsigned char *ptr = certRetrieved.data;
+ //
+ // X509 *x509cert = d2i_X509(NULL, &ptr, certRetrieved.size);
+ // if(x509cert == NULL){
+ // certmgr_release_certificate_data(&descriptor);
+ // LogError("Error extracting certificate (d2i_X509).");
+ // return UNKNOWN_ERROR;
+ // }
+ //
+ // LogDebug("The subject of this certificate is " << descriptor.mandatory.subject);
+ // if(cmp->compare(x509cert)){
+ // LogDebug("Found match. Coping bytes: " << certRetrieved.size);
+ // m_certificatePtr = CertificatePtr(new Certificate(certRetrieved));
+ // certmgr_release_certificate_data(&descriptor);
+ // X509_free(x509cert);
+ // break;
+ // }
+ //
+ // LogDebug("Release");
+ // X509_free(x509cert);
+ // certmgr_release_certificate_data(&descriptor);
+ // }
+ //
+ // if(ERR_NO_MORE_CERTIFICATES == result){
+ // LogError("Certificates for given DN not found\n");
+ // return CERTIFICATE_NOT_FOUND;
+ // }
+ //
+ // if(result!= OPERATION_SUCCESS){
+ // LogError("Certificate Manager Error\n");
+ // return UNKNOWN_ERROR;
+ // }
+ //
+ // LogDebug("Exit");
+ // return NO_ERROR;
+}
+
+// TODO
+CertificateLoader::CertificateLoaderResult CertificateLoader::
+ loadCertificateBasedOnSubjectName(const std::string &subjectName)
+{
+ (void) subjectName;
+ LogError("Not implemented.");
+ return UNKNOWN_ERROR;
+ // if(subjectName.empty())
+ // {
+ // return WRONG_ARGUMENTS;
+ // }
+ //
+ // long int result = OPERATION_SUCCESS;
+ //
+ // char storeId[CERTMGR_MAX_PLUGIN_ID_SIZE];
+ // char type[CERTMGR_MAX_CERT_TYPE_SIZE];
+ // certmgr_cert_id certId;
+ // certmgr_ctx context;
+ // certmgr_mem_buff certRetrieved;
+ // unsigned char buffer[CERTMGR_MAX_BUFFER_SIZE];
+ //
+ // certmgr_cert_descriptor descriptor;
+ //
+ // certRetrieved.data = buffer;
+ // certRetrieved.firstFree = 0;
+ // certRetrieved.size = CERTMGR_MAX_BUFFER_SIZE;
+ // certId.storeId = storeId;
+ // certId.type = type;
+ //
+ // CERTMGR_INIT_CONTEXT((&context), (sizeof(context)))
+ //
+ // for(certRetrieved.firstFree = 0;
+ // OPERATION_SUCCESS == (result = certmgr_retrieve_certificate_from_store(&context, &certRetrieved, &certId));
+ // certRetrieved.firstFree = 0)
+ // {
+ //
+ // if(OPERATION_SUCCESS!=certmgr_extract_certificate_data(&certRetrieved, &descriptor)){
+ // LogError("Extracting Certificate Data failed \n");
+ // continue;
+ // }
+ //
+ // if(!strcmp(subjectName.c_str(), descriptor.mandatory.subject)){
+ // LogDebug("The subject of this certificate is " << descriptor.mandatory.subject);
+ // m_certificatePtr = CertificatePtr(new Certificate(certRetrieved));
+ // certmgr_release_certificate_data(&descriptor);
+ // break;
+ // }
+ // LogDebug("Release");
+ // certmgr_release_certificate_data(&descriptor);
+ // }
+ //
+ // if(ERR_NO_MORE_CERTIFICATES == result) {
+ // LogError("Certificates for given DN not found\n");
+ // return CERTIFICATE_NOT_FOUND;
+ // }
+ // if(result!= OPERATION_SUCCESS){
+ // LogError("Certificate Manager Error\n");
+ // return UNKNOWN_ERROR;
+ // }
+ // LogDebug("Exit");
+ // return NO_ERROR;
+}
+
+// KW CertificateLoader::CertificateLoaderResult CertificateLoader::loadCertificateBasedOnIssuerName(const std::string &issuerName, const std::string &serialNumber)
+// KW {
+// KW if(issuerName.empty() || serialNumber.empty())
+// KW {
+// KW return WRONG_ARGUMENTS;
+// KW }
+// KW
+// KW if(m_cmBuff.data){
+// KW delete[] m_cmBuff.data;
+// KW memset(&m_cmBuff, 0, sizeof(certmgr_mem_buff));
+// KW }
+// KW
+// KW LogDebug("IssuerName: " << issuerName << " serialNumber: " << serialNumber);
+// KW
+// KW //used to check status of retrieved certificate
+// KW long int result = OPERATION_SUCCESS;
+// KW char storeId[CERTMGR_MAX_PLUGIN_ID_SIZE];
+// KW char type[CERTMGR_MAX_CERT_TYPE_SIZE];
+// KW certmgr_cert_id certId;
+// KW certmgr_ctx context;
+// KW certmgr_mem_buff certRetrieved;
+// KW unsigned char buffer[CERTMGR_MAX_BUFFER_SIZE];
+// KW
+// KW certmgr_cert_descriptor descriptor;
+// KW
+// KW certRetrieved.data = buffer;
+// KW certRetrieved.firstFree = 0;
+// KW certRetrieved.size = CERTMGR_MAX_BUFFER_SIZE;
+// KW certId.storeId = storeId;
+// KW certId.type = type;
+// KW
+// KW CERTMGR_INIT_CONTEXT((&context), (sizeof(context)))
+// KW
+// KW for(certRetrieved.firstFree = 0;
+// KW OPERATION_SUCCESS == (result = certmgr_retrieve_certificate_from_store(&context, &certRetrieved, &certId));
+// KW certRetrieved.firstFree = 0)
+// KW {
+// KW
+// KW LogDebug("Extracting certificate from CertMgr");
+// KW
+// KW if( OPERATION_SUCCESS != certmgr_extract_certificate_data(&certRetrieved, &descriptor) ){
+// KW LogError("Extracting Certificate Data failed \n");
+// KW continue;
+// KW }
+// KW
+// KW LogDebug("Issuer: " << descriptor.mandatory.issuer);
+// KW
+// KW const unsigned char *ptr = certRetrieved.data;
+// KW char *tmp;
+// KW
+// KW X509 *x509cert = d2i_X509(NULL, &ptr, certRetrieved.size);
+// KW std::string serialNO = std::string(tmp = i2s_ASN1_INTEGER(NULL, X509_get_serialNumber(x509cert)));
+// KW OPENSSL_free(tmp);
+// KW X509_free(x509cert);
+// KW
+// KW LogInfo("Certificate number found: " << serialNO);
+// KW LogInfo("Certificate number looking for: " << serialNumber);
+// KW
+// KW if(!strcmp(issuerName.c_str(), descriptor.mandatory.issuer)
+// KW && serialNumber == serialNO)
+// KW {
+// KW LogError("The issuer of this certificate is " << descriptor.mandatory.issuer);
+// KW
+// KW m_cmBuff.data = new unsigned char[certRetrieved.size];
+// KW m_cmBuff.firstFree = m_cmBuff.size = certRetrieved.size;
+// KW memcpy(m_cmBuff.data, certRetrieved.data, certRetrieved.size);
+// KW certmgr_release_certificate_data(&descriptor);
+// KW break;
+// KW }
+// KW certmgr_release_certificate_data(&descriptor);
+// KW }
+// KW
+// KW if(ERR_NO_MORE_CERTIFICATES == result) {
+// KW LogError("Certificates not found");
+// KW return CERTIFICATE_NOT_FOUND;
+// KW }
+// KW if(result != OPERATION_SUCCESS){
+// KW LogError("Certificate Manager Error");
+// KW return UNKNOWN_ERROR;
+// KW }
+// KW return NO_ERROR;
+// KW }
+
+CertificateLoader::CertificateLoaderResult CertificateLoader::
+ loadCertificateWithECKEY(const std::string &curveName,
+ const std::string &publicKey)
+{
+ (void) curveName;
+ (void) publicKey;
+ LogError("Not implemented.");
+ return UNKNOWN_ERROR;
+ // if(curveName != OID_CURVE_SECP256R1){
+ // LogError("Found field id: " << curveName << " Expected: " << OID_CURVE_SECP256R1);
+ // return UNSUPPORTED_CERTIFICATE_FIELD;
+ // }
+ //
+ // CertificateLoaderECDSA comparator(publicKey);
+ //
+ // CertificateLoaderResult result = NO_ERROR;
+ // for(int i=0; storeId[i]; ++i){
+ // result = loadCertificate(std::string(storeId[i]), &comparator);
+ //
+ // if(result == ERR_NO_MORE_CERTIFICATES)
+ // continue;
+ //
+ // return result;
+ // }
+ //
+ // return result;
+}
+
+CertificateLoader::CertificateLoaderResult CertificateLoader::
+ loadCertificateFromRawData(const std::string &rawData)
+{
+ Try {
+ Base64Decoder base;
+ base.reset();
+ base.append(rawData);
+ if (!base.finalize()) {
+ LogWarning("Certificate format is broken.");
+ return UNKNOWN_ERROR;
+ }
+ std::string derCert = base.get();
+ m_certificatePtr = CertificatePtr(new Certificate(derCert));
+ } Catch(Certificate::Exception::Base) {
+ LogWarning("Error reading certificate by openssl.");
+ return UNKNOWN_ERROR;
+ }
+
+ // Check the key length if sig algorithm is RSA
+ EVP_PKEY *pKey = X509_get_pubkey(m_certificatePtr->getX509());
+
+ if (pKey->type == EVP_PKEY_RSA) {
+ RSA* pRSA = pKey->pkey.rsa;
+
+ if (pRSA) {
+ int keyLength = RSA_size(pRSA);
+
+ // key Length (modulus) is in bytes
+ keyLength <<= 3;
+ LogDebug("RSA key length: " << keyLength << " bits");
+
+ if (keyLength < MIN_RSA_KEY_LENGTH) {
+ LogError(
+ "RSA key too short!" << "Has only " << keyLength << " bits");
+ return CERTIFICATE_SECURITY_ERROR;
+ }
+ }
+ }
+
+ return NO_ERROR;
+}
+
+// DEPRACETED FUNCTION
+//CertificateLoader::CertificateLoaderResult CertificateLoader::loadCertificateFromRawData(const std::string &rawData)
+//{
+// certmgr_mem_buff cmBuff = {0,0,0};
+//
+// long int size;
+// cmBuff.data = certmgr_util_base64_decode(const_cast<void*>(static_cast<const void*>(rawData.c_str())), rawData.size(), &size);
+//
+// cmBuff.firstFree = cmBuff.size = size;
+//
+// certmgr_cert_descriptor descriptor;
+//
+// long int result = certmgr_extract_certificate_data(&cmBuff, &descriptor);
+//
+// if (result != OPERATION_SUCCESS)
+// {
+// LogError("Unable to load certificate");
+// return UNKNOWN_ERROR;
+// }
+//
+// certmgr_release_certificate_data(&descriptor);
+//
+// m_certificatePtr = CertificatePtr(new Certificate(cmBuff));
+//
+// // we have to use temp pointer cause d2i_x509 modifies its input
+// const unsigned char* tmpPtr = cmBuff.data;
+// X509* pCertificate = d2i_X509(NULL, &tmpPtr, cmBuff.size);
+//
+// if (pCertificate)
+// {
+// SSLSmartContainer<X509> pX509(pCertificate);
+//
+// // Check the key length if sig algorithm is RSA
+// EVP_PKEY *pKey = X509_get_pubkey(pX509);
+//
+// if (pKey->type == EVP_PKEY_RSA)
+// {
+// RSA* pRSA = pKey->pkey.rsa;
+//
+// if (pRSA)
+// {
+// int keyLength = RSA_size(pRSA);
+//
+// // key Length (modulus) is in bytes
+// keyLength <<= 3;
+// LogDebug("RSA key length: " << keyLength << " bits");
+//
+// if (keyLength < MIN_RSA_KEY_LENGTH)
+// {
+// LogError("RSA key too short!" << "Has only " << keyLength << " bits");
+// return CERTIFICATE_SECURITY_ERROR;
+// }
+// }
+// }
+// }
+//
+// return NO_ERROR;
+//}
+
+CertificateLoader::CertificateLoaderResult CertificateLoader::
+ loadCertificateBasedOnDSAComponents(const std::string& strP,
+ const std::string& strQ,
+ const std::string& strG,
+ const std::string& strY,
+ const std::string& strJ,
+ const std::string& strSeed,
+ const std::string& strPGenCounter)
+{
+ (void) strP;
+ (void) strQ;
+ (void) strG;
+ (void) strY;
+ (void) strJ;
+ (void) strSeed;
+ (void) strPGenCounter;
+ LogError("Not implemented.");
+ return UNKNOWN_ERROR;
+ // (void)strY;
+ // (void)strJ;
+ // (void)strSeed;
+ // (void)strPGenCounter;
+ //
+ // long int result = UNKNOWN_ERROR;
+ //
+ // char storeId[CERTMGR_MAX_PLUGIN_ID_SIZE];
+ // char type[CERTMGR_MAX_CERT_TYPE_SIZE];
+ // certmgr_cert_id certId;
+ // certmgr_ctx context;
+ // certmgr_mem_buff certRetrieved;
+ //
+ // unsigned char buffer[CERTMGR_MAX_BUFFER_SIZE];
+ //
+ // certmgr_cert_descriptor descriptor;
+ //
+ // certRetrieved.data = buffer;
+ // certRetrieved.firstFree = 0;
+ // certRetrieved.size = CERTMGR_MAX_BUFFER_SIZE;
+ // certId.storeId = storeId;
+ // certId.type = type;
+ //
+ // CERTMGR_INIT_CONTEXT((&context), (sizeof(context)))
+ // std::string strStoreType("Operator");
+ // strncpy(context.storeId, strStoreType.c_str(), strStoreType.length());
+ //
+ // for (certRetrieved.firstFree = 0;
+ // OPERATION_SUCCESS == (result = certmgr_retrieve_certificate_from_store(&context, &certRetrieved, &certId));
+ // certRetrieved.firstFree = 0)
+ // {
+ //
+ // if (OPERATION_SUCCESS != certmgr_extract_certificate_data(&certRetrieved, &descriptor))
+ // {
+ // LogDebug("unable to retrieve cert from storage");
+ // continue;
+ // }
+ //
+ // X509* pCertificate = d2i_X509(NULL, (const unsigned char**) &(certRetrieved.data), certRetrieved.size);
+ //
+ // if (pCertificate)
+ // {
+ // EVP_PKEY *pKey = X509_get_pubkey(pCertificate);
+ //
+ // if (pKey->type == EVP_PKEY_DSA)
+ // {
+ // DSA* pDSA = pKey->pkey.dsa;
+ //
+ // if (pDSA)
+ // {
+ // BIGNUM *pDSApBigNum = NULL, *pDSAqBigNum = NULL, *pDSAgBigNum = NULL;
+ //
+ // convertBase64NodeToBigNum(strP, &pDSApBigNum);
+ // convertBase64NodeToBigNum(strQ, &pDSAqBigNum);
+ // convertBase64NodeToBigNum(strG, &pDSAgBigNum);
+ //
+ // if (pDSApBigNum && pDSAqBigNum && pDSAgBigNum &&
+ // BN_cmp(pDSApBigNum, pDSA->p) == 0 &&
+ // BN_cmp(pDSAqBigNum, pDSA->q) == 0 &&
+ // BN_cmp(pDSAgBigNum, pDSA->g) == 0)
+ // {
+ // LogInfo("DSA Certificate found");
+ // /* TODO load this certificate to m_cmBuff value */
+ // LogError("Not implemented!");
+ //
+ // EVP_PKEY_free(pKey);
+ // X509_free(pCertificate);
+ //
+ // BN_free(pDSApBigNum);
+ // BN_free(pDSAqBigNum);
+ // BN_free(pDSAgBigNum);
+ //
+ // certmgr_release_certificate_data(&descriptor);
+ // return NO_ERROR;
+ // }
+ //
+ // if (pDSApBigNum)
+ // {
+ // BN_free(pDSApBigNum);
+ // }
+ // if (pDSAqBigNum)
+ // {
+ // BN_free(pDSAqBigNum);
+ // }
+ // if (pDSAgBigNum)
+ // {
+ // BN_free(pDSAgBigNum);
+ // }
+ //
+ // }
+ // EVP_PKEY_free(pKey);
+ // }
+ // X509_free(pCertificate);
+ // }
+ // else
+ // LogError("Unable to load certificate");
+ //
+ // certmgr_release_certificate_data(&descriptor);
+ // }
+ //
+ // LogError("No DSA certificate with given parameters");
+ //
+ // return CERTIFICATE_NOT_FOUND;
+}
+
+bool CertificateLoader::convertBase64NodeToBigNum(const std::string& strNode,
+ BIGNUM** ppBigNum)
+{
+ (void) strNode;
+ (void) ppBigNum;
+ LogError("Not implemented.");
+ return false;
+ // if (!ppBigNum || *ppBigNum != NULL)
+ // {
+ // LogError("Ptr variable not initialized properly!");
+ // return false;
+ // }
+ //
+ // // decode base64 to binary
+ // long int binBuffLength = 0;
+ // unsigned char* binBuff = NULL;
+ //
+ // binBuff = certmgr_util_base64_decode(const_cast<char*> (strNode.c_str()), strNode.length(), &binBuffLength);
+ //
+ // if (!binBuff)
+ // {
+ // LogError("base64 decode failed");
+ // return false;
+ // }
+ //
+ // // convert binary to bignum
+ // *ppBigNum = BN_bin2bn(binBuff, binBuffLength, *ppBigNum);
+ //
+ // free(binBuff);
+ //
+ // if (!(*ppBigNum))
+ // {
+ // LogError("Conversion from node to bignum failed");
+ // return false;
+ // }
+ //
+ // return true;
+}
+
+// KW bool CertificateLoader::convertBigNumToBase64Node(const BIGNUM* pBigNum, std::string& strNode)
+// KW {
+// KW if (!pBigNum)
+// KW {
+// KW LogError("null ptr");
+// KW return false;
+// KW }
+// KW
+// KW int nNumLength = BN_num_bytes(pBigNum);
+// KW unsigned char* buffer = new unsigned char[nNumLength + 1];
+// KW
+// KW // convert bignum to binary format
+// KW if (BN_bn2bin(pBigNum, buffer) < 0)
+// KW {
+// KW LogError("Conversion from bignum to binary failed");
+// KW delete []buffer;
+// KW return false;
+// KW }
+// KW
+// KW char* pBase64Node = NULL;
+// KW unsigned long int buffLen = 0;
+// KW certmgr_util_base64_encode(buffer, (unsigned long int) nNumLength, &pBase64Node, &buffLen);
+// KW
+// KW strNode.assign(pBase64Node, buffLen);
+// KW
+// KW delete []buffer;
+// KW return true;
+// KW }
+} // namespace ValidationCore
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 _CERTIFICATELOADER_H_
+#define _CERTIFICATELOADER_H_
+
+#include <string>
+#include <string.h>
+
+#include <dpl/noncopyable.h>
+#include <openssl/ssl.h>
+
+#include <cert-service.h>
+
+#include "Certificate.h"
+
+namespace ValidationCore {
+class CertificateLoader : public DPL::Noncopyable
+{
+ public:
+ class CertificateLoaderComparator
+ {
+ public:
+ virtual bool compare(X509 *x509cert) = 0;
+ virtual ~CertificateLoaderComparator()
+ {
+ }
+ };
+
+ enum CertificateLoaderResult
+ {
+ NO_ERROR,
+ CERTIFICATE_NOT_FOUND,
+ UNSUPPORTED_CERTIFICATE_FIELD,
+ WRONG_ARGUMENTS,
+ CERTIFICATE_SECURITY_ERROR, //!< there are some issues with certificate security (i.e. key too short)
+ UNKNOWN_ERROR
+ };
+
+ CertificateLoader()
+ {
+ }
+
+ virtual ~CertificateLoader()
+ {
+ }
+
+ CertificateLoaderResult loadCertificate(const std::string& storage,
+ CertificateLoaderComparator *cmp);
+
+ CertificateLoaderResult loadCertificateBasedOnSubjectName(
+ const std::string &subjectName);
+ CertificateLoaderResult loadCertificateBasedOnExponentAndModulus(
+ const std::string &m_modulus,
+ const std::string &m_exponent);
+ // KW CertificateLoaderResult loadCertificateBasedOnIssuerName(const std::string &isserName,
+ // KW const std::string &serialNumber);
+
+ CertificateLoaderResult loadCertificateFromRawData(
+ const std::string &rawData);
+
+ CertificateLoaderResult loadCertificateBasedOnDSAComponents(
+ const std::string& strP,
+ const std::string& strQ,
+ const std::string& strG,
+ const std::string& strY,
+ const std::string& strJ,
+ const std::string& strSeed,
+ const std::string& strPGenCounter);
+
+ CertificateLoaderResult loadCertificateWithECKEY(
+ const std::string &curveName,
+ const std::string &publicKey);
+
+ /**
+ * converts base64 encoded node to SSL bignum
+ * allocates mem on *ppBigNum, don't forget to free it later with BN_free!
+ * returns conversion status
+ */
+ static bool convertBase64NodeToBigNum(const std::string& strNode,
+ BIGNUM** ppBigNum);
+
+ /*
+ * encodes SSL bignum into base64 octstring
+ * returns conversion status
+ */
+ // KW static bool convertBigNumToBase64Node(const BIGNUM* pBigNum, std::string& strNode);
+
+ CertificatePtr getCertificatePtr() const
+ {
+ return m_certificatePtr;
+ }
+ private:
+ CertificatePtr m_certificatePtr;
+};
+} // namespace ValidationCore
+
+#endif // _CERTIFICATELOADER_H_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 VCORE_SRC_VCORE_CERTIFICATESTORAGE_H
+#define VCORE_SRC_VCORE_CERTIFICATESTORAGE_H
+
+#include <list>
+#include <openssl/x509.h>
+
+namespace ValidationCore {
+typedef std::list < X509* > X509CertificatesList;
+}
+
+#endif // VCORE_SRC_VCORE_CERTIFICATESTORAGE_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 Bartlomiej Grzelewski (b.grzelewski@gmail.com)
+ * @version 0.1
+ * @file CertificateVerifier.cpp
+ * @brief This class integrates OCSP and CRL.
+ */
+#include "CertificateVerifier.h"
+
+#include <dpl/assert.h>
+#include <dpl/foreach.h>
+#include <dpl/log/log.h>
+
+namespace ValidationCore {
+
+CertificateVerifier::CertificateVerifier(bool enableOcsp, bool enableCrl)
+: m_enableOcsp(enableOcsp)
+, m_enableCrl(enableCrl)
+{}
+
+VerificationStatus CertificateVerifier::check(
+ CertificateCollection &certCollection) const
+{
+ LogDebug("== Certificate collection validation start ==");
+ Assert(certCollection.isChain() && "Collection must form chain.");
+
+ VerificationStatus statusOcsp;
+ VerificationStatus statusCrl;
+
+ if (m_enableOcsp) {
+ statusOcsp = obtainOcspStatus(certCollection);
+ } else {
+ statusOcsp = VERIFICATION_STATUS_GOOD;
+ }
+
+ if (m_enableCrl) {
+ statusCrl = obtainCrlStatus(certCollection);
+ } else {
+ statusCrl = VERIFICATION_STATUS_GOOD;
+ }
+ LogDebug("== Certificate collection validation end ==");
+ return getStatus(statusOcsp, statusCrl);
+}
+
+VerificationStatus CertificateVerifier::obtainOcspStatus(
+ const CertificateCollection &chain) const
+{
+ LogDebug("== Obtain ocsp status ==");
+ CachedOCSP ocsp;
+ return ocsp.check(chain);
+}
+
+VerificationStatus CertificateVerifier::obtainCrlStatus(
+ const CertificateCollection &chain) const
+{
+ LogDebug("== Obtain crl status ==");
+ CachedCRL crl;
+ return crl.check(chain);
+}
+
+VerificationStatus CertificateVerifier::getStatus(
+ VerificationStatus ocsp,
+ VerificationStatus crl) const
+{
+ if (ocsp == VERIFICATION_STATUS_REVOKED ||
+ crl == VERIFICATION_STATUS_REVOKED)
+ {
+ LogDebug("Return status: REVOKED");
+ return VERIFICATION_STATUS_REVOKED;
+ }
+
+ if (ocsp == VERIFICATION_STATUS_GOOD) {
+ LogDebug("Return status: GOOD");
+ return VERIFICATION_STATUS_GOOD;
+ }
+
+ if (ocsp == VERIFICATION_STATUS_UNKNOWN) {
+ LogDebug("Return status: UNKNOWN");
+ return VERIFICATION_STATUS_UNKNOWN;
+ }
+
+ if (ocsp == VERIFICATION_STATUS_NOT_SUPPORT) {
+ LogDebug("Return status: NOT_SUPPORT");
+ return VERIFICATION_STATUS_GOOD;
+ }
+
+ LogDebug("Return status: ERROR");
+ return VERIFICATION_STATUS_ERROR;
+}
+
+VerificationStatus CertificateVerifier::checkEndEntity(
+ CertificateCollectionList &collectionList) const
+{
+ VerificationStatusSet statusOcsp;
+ VerificationStatusSet statusCrl;
+
+ if (m_enableOcsp) {
+ CachedOCSP ocsp;
+ FOREACH(it, collectionList){
+ statusOcsp.add(ocsp.checkEndEntity(*it));
+ }
+ } else {
+ statusOcsp.add(VERIFICATION_STATUS_GOOD);
+ }
+
+ if (m_enableCrl) {
+ CachedCRL crl;
+ FOREACH(it, collectionList){
+ statusCrl.add(crl.checkEndEntity(*it));
+ }
+ } else {
+ statusCrl.add(VERIFICATION_STATUS_GOOD);
+ }
+ LogDebug("== Certificate collection validateion end ==");
+ return getStatus(statusOcsp.convertToStatus(), statusCrl.convertToStatus());
+}
+
+} // namespace ValidationCore
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 Bartlomiej Grzelewski (b.grzelewski@gmail.com)
+ * @version 0.1
+ * @file CertificateVerifier.h
+ * @brief This class integrates OCSP and CRL into one module.
+ */
+#ifndef _SRC_VALIDATION_CORE_CERTIFICATE_VERIFIER_H_
+#define _SRC_VALIDATION_CORE_CERTIFICATE_VERIFIER_H_
+
+#include "Certificate.h"
+#include "CertificateCollection.h"
+#include "CachedCRL.h"
+#include "CachedOCSP.h"
+#include "VerificationStatus.h"
+
+namespace ValidationCore {
+
+class CertificateVerifier {
+ public:
+ explicit CertificateVerifier(bool enableOcsp, bool enableCrl);
+ ~CertificateVerifier(){}
+
+ /*
+ * Run OCSP and CRL for all certificates in collection.
+ * Collection must represent chain.
+ *
+ * Evaluate status. This function converts ocsp status set
+ * into one status - the most restricted. This one ocsp status
+ * and status from crl is evaluated to end result.
+ *
+ * Algorithm to evaluate result is represented in table:
+ *
+ * +--------------+-------+-------+-------+------------+---------+
+ * | OCSP |Good |Revoked|Unknown|Undetermined|Not |
+ * | | | | | |supported|
+ * | CRL | | | | | |
+ * +--------------+-------+-------+-------+------------+---------+
+ * | GOOD |GOOD |Revoked|Unknown|Undetermined|Good |
+ * +--------------+-------+-------+-------+------------+---------+
+ * | REVOKED |Revoked|Revoked|Revoked|Revoked |Revoked |
+ * +--------------+-------+-------+-------+------------+---------+
+ * | UNDETERMINED |Good |Revoked|Unknown|Undetermined|Good |
+ * +--------------+-------+-------+-------+------------+---------+
+ * | Not supported|Good |Revoked|Unknown|Undetermined|Good |
+ * +--------------+-------+-------+-------+------------+---------+
+ *
+ * As Undetermind function returns VERIFICATION_STATUS_ERROR.
+ */
+
+ VerificationStatus check(CertificateCollection &certCollection) const;
+
+ VerificationStatus checkEndEntity(
+ CertificateCollectionList &certCollectionList) const;
+
+ private:
+ VerificationStatus obtainOcspStatus(
+ const CertificateCollection &chain) const;
+ VerificationStatus obtainCrlStatus(
+ const CertificateCollection &chain) const;
+ VerificationStatus getStatus(VerificationStatus ocsp,
+ VerificationStatus crl) const;
+
+ bool m_enableOcsp;
+ bool m_enableCrl;
+};
+
+} // namespace ValidationCore
+
+#endif // _SRC_VALIDATION_CORE_CERTIFICATE_VERIFIER_H_
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "Config.h"
+
+#include <dpl/singleton_impl.h>
+IMPLEMENT_SINGLETON(ValidationCore::Config)
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 _SRC_VALIDATION_CORE_VALIDATION_CORE_CONFIG_H_
+#define _SRC_VALIDATION_CORE_VALIDATION_CORE_CONFIG_H_
+
+#include <string>
+
+#include <dpl/singleton.h>
+
+namespace ValidationCore {
+class Config {
+public:
+ /*
+ * Set path to config file with certificate description.
+ */
+ bool setXMLConfigPath(const std::string& path) {
+ if (!m_certificateXMLConfigPath.empty()) {
+ return false;
+ }
+ m_certificateXMLConfigPath = path;
+ return true;
+ }
+
+ /*
+ * Set path to schema of config file.
+ */
+ bool setXMLSchemaPath(const std::string& path) {
+ if (!m_certificateXMLSchemaPath.empty()) {
+ return false;
+ }
+ m_certificateXMLSchemaPath = path;
+ return true;
+ }
+
+ /*
+ * Set path to database with OCSP/CRL Cache.
+ */
+ bool setDatabasePath(const std::string& path) {
+ if (!m_databasePath.empty()) {
+ return false;
+ }
+ m_databasePath = path;
+ return true;
+ }
+
+ /*
+ * Get path to config file with certificate description.
+ */
+ std::string getXMLConfigPath() {
+ return m_certificateXMLConfigPath;
+ }
+
+ /*
+ * Get path to schema of config file.
+ */
+ std::string getXMLSchemaPath() {
+ return m_certificateXMLSchemaPath;
+ }
+
+ /*
+ * Get path to database with OCSP/CRL Cache.
+ */
+ std::string getDatabasePath() {
+ return m_databasePath;
+ }
+
+private:
+ std::string m_certificateXMLConfigPath;
+ std::string m_certificateXMLSchemaPath;
+ std::string m_databasePath;
+};
+
+typedef DPL::Singleton<Config> ConfigSingleton;
+
+} // namespace ValidationCore
+
+#endif // _SRC_VALIDATION_CORE_VALIDATION_CORE_CONFIG_H_
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "Database.h"
+
+#include <string>
+#include <dpl/log/log.h>
+#include <dpl/db/sql_connection.h>
+
+#include "Config.h"
+
+const char* VCoreDatabaseConnectionTraits::Address()
+{
+ /* This function should be fixed but some changes in
+ * dpl are required.
+ */
+// return ValidationCore::VCConfigSingleton::Instance().
+// getDatabasePath().c_str();
+
+ LogWarning(
+ "VCore will use hardcoded path for database: /opt/dbspace/.vcore.db");
+ return "/opt/dbspace/.vcore.db";
+}
+
+DPL::Mutex g_vcoreDbQueriesMutex;
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 VCORE_SRC_VCORE_DATABASE_H
+#define VCORE_SRC_VCORE_DATABASE_H
+
+#include <dpl/db/thread_database_support.h>
+#include <dpl/db/sql_connection.h>
+#include <dpl/mutex.h>
+#include <dpl/thread.h>
+
+struct VCoreDatabaseConnectionTraits
+{
+ static const char *Address();
+
+ static DPL::DB::SqlConnection::Flag::Type Flags()
+ {
+ return DPL::DB::SqlConnection::Flag::UseLucene;
+ }
+};
+
+extern DPL::Mutex g_vcoreDbQueriesMutex;
+
+#define VCORE_DB_INTERNAL(tlsCommand, InternalType, interface) \
+ static DPL::ThreadLocalVariable<InternalType> *tlsCommand ## Ptr = NULL; \
+ { \
+ DPL::Mutex::ScopedLock lock(&g_vcoreDbQueriesMutex); \
+ if (!tlsCommand ## Ptr) { \
+ static DPL::ThreadLocalVariable<InternalType> tmp; \
+ tlsCommand ## Ptr = &tmp; \
+ } \
+ } \
+ DPL::ThreadLocalVariable<InternalType> &tlsCommand = *tlsCommand ## Ptr; \
+ if (tlsCommand.IsNull()) { tlsCommand = InternalType(interface); }
+
+#define VCORE_DB_SELECT(name, type, interface) \
+ VCORE_DB_INTERNAL(name, type::Select, interface)
+
+#define VCORE_DB_INSERT(name, type, interface) \
+ VCORE_DB_INTERNAL(name, type::Insert, interface)
+
+#define VCORE_DB_UPDATE(name, type, interface) \
+ VCORE_DB_INTERNAL(name, type::Update, interface)
+
+#define VCORE_DB_DELETE(name, type, interface) \
+ VCORE_DB_INTERNAL(name, type::Delete, interface)
+
+#endif // define VCORE_SRC_VCORE_DATABASE_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file DeveloperModeValidator.cpp
+ * @author Bartosz Janiak (b.janiak@samsung.com)
+ * @version 1.0
+ * @brief DeveloperModeValidatorValidator - implementing WAC 2.0 spec, including TargetRestriction
+ */
+
+#include "DeveloperModeValidator.h"
+#include <algorithm>
+#include <vconf.h>
+#include <ITapiMisc.h>
+#include <dpl/log/log.h>
+#include <dpl/scoped_free.h>
+
+namespace ValidationCore {
+
+DeveloperModeValidator::DeveloperModeValidator(bool complianceMode,
+ const std::string& fakeIMEI,
+ const std::string& fakeMEID):
+ m_complianceModeEnabled(complianceMode),
+ m_fakeIMEI(fakeIMEI),
+ m_fakeMEID(fakeMEID)
+{
+}
+
+void DeveloperModeValidator::check(const SignatureData &data)
+{
+ LogDebug("entered");
+ const SignatureData::IMEIList& IMEIList = data.getIMEIList();
+ const SignatureData::MEIDList& MEIDList = data.getMEIDList();
+
+ if (IMEIList.empty() && MEIDList.empty()) {
+ LogDebug("No TargetRestriction in signature.");
+ return;
+ }
+
+ if (!IMEIList.empty()) {
+ std::string phoneIMEIString = m_fakeIMEI;
+ if (!m_complianceModeEnabled) {
+ LogDebug("Compilance Mode is not enabled");
+ DPL::ScopedFree<char> phoneIMEI(
+ vconf_get_str(VCONFKEY_TELEPHONY_IMEI));
+ if (!phoneIMEI.Get()) {
+ ThrowMsg(Exception::NoTargetRestrictionSatisfied,
+ "Unable to get phone IMEI from vconf.");
+ }
+ phoneIMEIString = phoneIMEI.Get();
+ }
+
+ LogDebug("Phone IMEI: " << phoneIMEIString);
+ if (IMEIList.end() ==
+ std::find(IMEIList.begin(), IMEIList.end(), phoneIMEIString))
+ {
+ Throw(Exception::NoTargetRestrictionSatisfied);
+ }
+ }
+
+ if (!MEIDList.empty()) {
+ std::string phoneMEIDString = m_fakeMEID;
+ if (!m_complianceModeEnabled)
+ {
+ TelMiscSNInformation phoneInfo;
+ if (TAPI_API_SUCCESS !=
+ tel_get_misc_me_sn(TAPI_MISC_ME_MEID, &phoneInfo))
+ {
+ ThrowMsg(Exception::NoTargetRestrictionSatisfied,
+ "Unable to get phone MEID from Tapi service.");
+ }
+ phoneMEIDString = reinterpret_cast<char*>(phoneInfo.szNumber);
+ }
+
+ LogDebug("Phone MEID: " << phoneMEIDString);
+ if (MEIDList.end() ==
+ std::find(MEIDList.begin(), MEIDList.end(), phoneMEIDString))
+ {
+ Throw(Exception::NoTargetRestrictionSatisfied);
+ }
+ }
+ LogDebug("exit: ok");
+}
+
+} //ValidationCore
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file DeveloperModeValidator.h
+ * @author Bartosz Janiak (b.janiak@samsung.com)
+ * @version 1.0
+ * @brief DeveloperModeValidatorValidator - implementing WAC 2.0 spec, including TargetRestriction
+ */
+
+#ifndef \
+ WRT_ENGINE_SRC_INSTALLER_CORE_VALIDATION_CORE_DEVELOPER_MODE_VALIDATOR_H
+#define \
+ WRT_ENGINE_SRC_INSTALLER_CORE_VALIDATION_CORE_DEVELOPER_MODE_VALIDATOR_H
+
+#include <string>
+#include <dpl/exception.h>
+#include "SignatureData.h"
+
+namespace ValidationCore {
+
+class DeveloperModeValidator
+{
+ public:
+ explicit DeveloperModeValidator(bool complianceMode = false,
+ const std::string &fakeIMEI = "",
+ const std::string &fakeMEID = "");
+
+ class Exception
+ {
+ public:
+ DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+ DECLARE_EXCEPTION_TYPE(Base, UnableToLoadTestCertificate)
+ DECLARE_EXCEPTION_TYPE(Base, NoTargetRestrictionSatisfied)
+ };
+
+ void check(const SignatureData &data);
+ private:
+ bool m_complianceModeEnabled;
+ std::string m_fakeIMEI;
+ std::string m_fakeMEID;
+};
+
+}
+#endif /* WRT_ENGINE_SRC_INSTALLER_CORE_VALIDATION_CORE_DEVELOPER_MODE_VALIDATOR_H */
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ *
+ *
+ * @file AbstractResponseCache.h
+ * @author Tomasz Swierczek (t.swierczek@samsung.com)
+ * @version 0.1
+ * @brief Common interface for OCSP/CRL caches
+ */
+
+#ifndef _SRC_VALIDATION_CORE_IABSTRACT_RESPONSE_CACHE_H_
+#define _SRC_VALIDATION_CORE_IABSTRACT_RESPONSE_CACHE_H_
+
+#include "Certificate.h"
+#include "CertificateCollection.h"
+#include "VerificationStatus.h"
+
+namespace ValidationCore {
+
+class IAbstractResponseCache {
+ public:
+ virtual VerificationStatus check(const CertificateCollection &certs) = 0;
+ virtual VerificationStatus checkEndEntity(CertificateCollection &certs) = 0;
+ virtual void updateCache() = 0;
+
+ virtual ~IAbstractResponseCache()
+ {
+ }
+};
+
+} // namespace ValidationCore
+
+#endif /* _SRC_VALIDATION_CORE_IABSTRACT_RESPONSE_CACHE_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 Tomasz Morawski(t.morawski@samsung.com)
+ * @author Michal Ciepielski(m.ciepielski@samsung.com)
+ * @author Piotr Marcinkiewicz(p.marcinkiew@samsung.com)
+ * @version 0.4
+ * @file OCPS.cpp
+ * @brief Routines for certificate validation over OCSP
+ */
+
+#include "OCSP.h"
+
+#include <string.h>
+#include <algorithm>
+
+#include <openssl/ssl.h>
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+#include <openssl/x509v3.h>
+
+#include <dpl/log/log.h>
+#include <dpl/assert.h>
+#include <dpl/foreach.h>
+#include <dpl/scoped_array.h>
+#include <dpl/scoped_free.h>
+
+#include <libsoup/soup.h>
+
+#include "Certificate.h"
+#include "SoupMessageSendSync.h"
+
+extern "C" {
+// This function is needed to fix "Invalid conversion from void*
+// to unsigned char*" C++ compiler error during calling
+// i2d_OCSP_REQUEST_bio macro
+ extern bool convertToBuffer(OCSP_REQUEST* req,
+ char** buf,
+ int* size);
+}
+
+namespace {
+const int ConnectionTimeoutInSeconds = 6;
+const int ConnectionRetryCount = 5;
+
+//! Maximum leeway in validity period in seconds: default 1 day
+//! (@see checkRevocationStatus function code)
+
+//! Maximum validity time for revocation status (1 day)
+const int MaxValidatyPeriodInSeconds = 24 * 60 * 60;
+
+//! Max age (@see checkRevocationStatus function code)
+const int MaxAge = -1;
+}
+
+namespace ValidationCore {
+
+const char* OCSP::DEFAULT_RESPONDER_URI_ENV = "OCSP_DEFAULT_RESPONDER_URI";
+
+OCSP::DigestAlgorithmMap createDigestAlgMap()
+{
+ OCSP::DigestAlgorithmMap mDigestAlg = OCSP::DigestAlgorithmMap();
+
+ mDigestAlg.insert(std::make_pair(OCSP::SHA1, EVP_sha1()));
+ mDigestAlg.insert(std::make_pair(OCSP::SHA224, EVP_sha224()));
+ mDigestAlg.insert(std::make_pair(OCSP::SHA256, EVP_sha256()));
+ mDigestAlg.insert(std::make_pair(OCSP::SHA384, EVP_sha384()));
+ mDigestAlg.insert(std::make_pair(OCSP::SHA512, EVP_sha512()));
+
+ return mDigestAlg;
+}
+
+OCSP::DigestAlgorithmMap OCSP::m_sDigestAlgMap = createDigestAlgMap();
+
+OCSP::OCSP() :
+ /* Upgrade of openssl is required to support sha256 */
+ // m_pCertIdDigestAlg(EVP_sha256()),
+ // m_pRequestDigestAlg(EVP_sha256()),
+ m_pCertIdDigestAlg(EVP_sha1()),
+ m_pRequestDigestAlg(EVP_sha1()),
+ m_bUseNonce(false),
+ m_bUseDefResponder(false),
+ m_bSignRequest(false),
+ m_pSignKey(0)
+{
+}
+
+SoupWrapper::SoupMessageSendBase::RequestStatus OCSP::sendOcspRequest(
+ OCSP_REQUEST* argRequest,
+ const DPL::OptionalString& argUri)
+{
+ using namespace SoupWrapper;
+ // convert OCSP_REQUEST to memory buffer
+ std::string url = DPL::ToUTF8String(*argUri);
+ char* requestBuffer;
+ int requestSizeInt;
+ if (!convertToBuffer(argRequest, &requestBuffer, &requestSizeInt)) {
+ ThrowMsg(OCSP::Exception::VerificationError,
+ "OCSP: failed to convert OCSP_REQUEST to mem buffer");
+ }
+
+ Assert(requestSizeInt >= 0);
+
+ SoupMessageSendBase::MessageBuffer buffer;
+ buffer.resize(requestSizeInt);
+ memcpy(&buffer[0], requestBuffer, requestSizeInt);
+ free(requestBuffer);
+
+ char *cport = 0,*chost = 0,*cpath = 0;
+ int use_ssl = 0;
+
+ if (!OCSP_parse_url(const_cast<char*>(url.c_str()),
+ &chost,
+ &cport,
+ &cpath,
+ &use_ssl))
+ {
+ LogWarning("Error in OCSP_parse_url");
+ return SoupMessageSendBase::REQUEST_STATUS_CONNECTION_ERROR;
+ }
+
+ std::string host = chost;
+
+ if (cport) {
+ host += ":";
+ host += cport;
+ }
+
+ free(cport);
+ free(chost);
+ free(cpath);
+
+ m_soupMessage.setHost(url);
+ m_soupMessage.setHeader("Host", host);
+ m_soupMessage.setRequest(std::string("application/ocsp-request"),
+ buffer);
+
+ return m_soupMessage.sendSync();
+}
+
+ValidationCore::VerificationStatusSet OCSP::validateCertificateList(
+ const CertificateList &certs)
+{
+ VerificationStatusSet statusSet;
+
+ if (certs.size() < 2) {
+ // no certificates to verify, just return a error
+ LogWarning("No validation will be proceed. OCSP require at"
+ " least 2 certificates in chain. Found only " <<
+ certs.size());
+ statusSet.add(VERIFICATION_STATUS_ERROR);
+ return statusSet;
+ }
+
+ CertificateList::const_iterator iter = certs.begin();
+ CertificateList::const_iterator parent = iter;
+
+ time_t minValidity = 0;
+ for (++parent; parent != certs.end(); ++iter, ++parent) {
+ LogDebug("Certificate validation (CN:" <<
+ (*iter)->getCommonName() << ")");
+ statusSet.add(validateCertificate(*iter, *parent));
+ if ((0 == minValidity || minValidity > m_responseValidity) &&
+ m_responseValidity > 0)
+ {
+ minValidity = m_responseValidity;
+ }
+ }
+ m_responseValidity = minValidity;
+
+ return statusSet;
+}
+
+VerificationStatus OCSP::checkEndEntity(
+ const CertificateCollection &chain)
+{
+ const char *defResponderURI = getenv(OCSP::DEFAULT_RESPONDER_URI_ENV);
+
+ VerificationStatusSet verSet;
+ if (defResponderURI) {
+ setUseDefaultResponder(true);
+ setDefaultResponder(defResponderURI);
+ }
+
+ // this is temporary fix. it must be rewriten
+ CertificateList clst;
+ if (chain.isChain() && chain.size() >= 2) {
+ CertificateList::const_iterator icert = chain.begin();
+ clst.push_back(*icert);
+ ++icert;
+ clst.push_back(*icert);
+ }
+ verSet += validateCertificateList(clst);
+
+ return verSet.convertToStatus();
+}
+
+VerificationStatus OCSP::validateCertificate(CertificatePtr argCert,
+ CertificatePtr argIssuer)
+{
+ using namespace SoupWrapper;
+
+ Assert(!!argCert);
+ Assert(!!argIssuer);
+
+ Try {
+ DPL::OptionalString uri;
+
+ if (!m_bUseDefResponder) {
+ uri = argCert->getOCSPURL();
+ if (!uri) {
+ return VERIFICATION_STATUS_NOT_SUPPORT;
+ }
+ } else {
+ if (m_strResponderURI.empty()) {
+ ThrowMsg(Exception::VerificationError,
+ "Default responder is not set");
+ }
+ LogWarning("Default responder will be used");
+
+ uri = m_strResponderURI;
+ }
+
+ // creates a request
+ CreateRequestResult newRequest = createRequest(argCert, argIssuer);
+ if (!newRequest.success) {
+ ThrowMsg(Exception::VerificationError, "Request creation failed");
+ }
+
+ // SSLSmartContainer <OCSP_CERTID> certIdCont(certId);
+ // this smart ptr is commented out in purpose. request
+ // manages certIdmemory (which was done in createRequest above)
+ SSLSmartContainer <OCSP_REQUEST> requestCont(newRequest.ocspRequest);
+
+ SoupMessageSendBase::RequestStatus requestStatus;
+ requestStatus = sendOcspRequest(requestCont, uri);
+
+ if (requestStatus != SoupMessageSendBase::REQUEST_STATUS_OK) {
+ return VERIFICATION_STATUS_CONNECTION_FAILED;
+ }
+
+ // Response is m_soupMessage, convert it to OCSP_RESPONSE
+ OcspResponse response = convertToResponse();
+
+ if (!response.first) {
+ ThrowMsg(OCSP::Exception::VerificationError,
+ "OCSP: failed to convert mem buffer to OCSP_RESPONSE");
+ }
+
+ SSLSmartContainer <OCSP_RESPONSE> responseCont(response.second);
+ // verify response eg. check response status,
+ // validate responder certificate
+ validateResponse(requestCont,
+ responseCont,
+ newRequest.ocspCertId);
+ } Catch(Exception::ConnectionError) {
+ LogWarning("OCSP: ConnectionError");
+ return VERIFICATION_STATUS_CONNECTION_FAILED;
+ } Catch(Exception::CertificateRevoked) {
+ LogWarning("OCSP: Revoked");
+ return VERIFICATION_STATUS_REVOKED;
+ } Catch(Exception::CertificateUnknown) {
+ LogWarning("OCSP: Unknown");
+ return VERIFICATION_STATUS_UNKNOWN;
+ } Catch(Exception::VerificationError) {
+ LogWarning("OCSP: Verification error");
+ return VERIFICATION_STATUS_VERIFICATION_ERROR;
+ } Catch(Exception::Base) {
+ LogWarning("OCSP: Error");
+ return VERIFICATION_STATUS_ERROR;
+ }
+ LogWarning("OCSP: Good");
+ return VERIFICATION_STATUS_GOOD;
+}
+
+OCSP::CreateRequestResult OCSP::createRequest(CertificatePtr argCert,
+ CertificatePtr argIssuer)
+{
+ OCSP_REQUEST* newRequest = OCSP_REQUEST_new();
+
+ if (!newRequest) {
+ LogWarning("OCSP: Failed to create a request");
+ return CreateRequestResult();
+ }
+
+ SSLSmartContainer <OCSP_REQUEST> requestCont(newRequest);
+
+ OCSP_CERTID* certId = addSerial(argCert, argIssuer);
+
+ if (!certId) {
+ LogWarning("OCSP: Unable to create a serial id");
+ return CreateRequestResult();
+ }
+ SSLSmartContainer <OCSP_CERTID> certIdCont(certId);
+
+ // Inserting certificate ID to request
+ if (!OCSP_request_add0_id(requestCont, certIdCont)) {
+ LogWarning("OCSP: Unable to create a certificate id");
+ return CreateRequestResult();
+ }
+
+ if (m_bUseNonce) {
+ OCSP_request_add1_nonce(requestCont, 0, -1);
+ }
+
+ if (m_bSignRequest) {
+ if (!m_pSignCert || !m_pSignKey) {
+ LogWarning("OCSP: Unable to sign request if "
+ "SignCert or SignKey was not set");
+ return CreateRequestResult();
+ }
+
+ if (!OCSP_request_sign(requestCont,
+ m_pSignCert->getX509(),
+ m_pSignKey,
+ m_pRequestDigestAlg,
+ 0,
+ 0))
+ {
+ LogWarning("OCSP: Unable to sign request");
+ return CreateRequestResult();
+ }
+ }
+ return CreateRequestResult(true,
+ requestCont.DetachPtr(),
+ certIdCont.DetachPtr());
+}
+
+OCSP_CERTID* OCSP::addSerial(CertificatePtr argCert,
+ CertificatePtr argIssuer)
+{
+ X509_NAME* iname = X509_get_subject_name(argIssuer->getX509());
+ ASN1_BIT_STRING* ikey = X509_get0_pubkey_bitstr(argIssuer->getX509());
+ ASN1_INTEGER* serial = X509_get_serialNumber(argCert->getX509());
+
+ return OCSP_cert_id_new(m_pCertIdDigestAlg, iname, ikey, serial);
+}
+
+void OCSP::setDigestAlgorithmForCertId(DigestAlgorithm alg)
+{
+ DigestAlgorithmMap::const_iterator cit = m_sDigestAlgMap.find(alg);
+
+ if (cit != m_sDigestAlgMap.end()) {
+ m_pCertIdDigestAlg = cit->second;
+ } else {
+ LogDebug("Request for unsupported CertId digest algorithm"
+ "ignored!");
+ }
+}
+
+void OCSP::setDigestAlgorithmForRequest(DigestAlgorithm alg)
+{
+ DigestAlgorithmMap::const_iterator cit = m_sDigestAlgMap.find(alg);
+
+ if (cit != m_sDigestAlgMap.end()) {
+ m_pRequestDigestAlg = cit->second;
+ } else {
+ LogDebug("Request for unsupported OCSP request digest algorithm"
+ "ignored!");
+ }
+}
+
+void OCSP::setTrustedStore(const CertificateList& certs)
+{
+ X509_STORE *store = X509_STORE_new();
+ m_pTrustedStore = store;
+ // create a trusted store basing on certificate chain from a signature
+ FOREACH(iter, certs) {
+ X509_STORE_add_cert(store, (*iter)->getX509());
+ }
+}
+
+void OCSP::validateResponse(OCSP_REQUEST* argRequest,
+ OCSP_RESPONSE* argResponse,
+ OCSP_CERTID* argCertId)
+{
+ int result = OCSP_response_status(argResponse);
+
+ if (result != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
+ handleInvalidResponse(result);
+ ThrowMsg(Exception::VerificationError, "OCSP_response_status failed");
+ }
+
+ // get response object
+ OCSP_BASICRESP* basic = OCSP_response_get1_basic(argResponse);
+ if (!basic) {
+ ThrowMsg(Exception::VerificationError,
+ "OCSP: Unable to get a BASICRESP object.");
+ }
+
+ SSLSmartContainer <OCSP_BASICRESP> basicRespCont(basic);
+ if (m_bUseNonce && OCSP_check_nonce(argRequest, basicRespCont) <= 0) {
+ ThrowMsg(Exception::VerificationError, "OCSP: Invalid nonce");
+ }
+
+ if (!verifyResponse(basic)) {
+ ThrowMsg(Exception::VerificationError,
+ "Unable to verify the OCSP responder's certificate");
+ }
+
+ checkRevocationStatus(basicRespCont, argCertId);
+}
+
+bool OCSP::verifyResponse(OCSP_BASICRESP* basic)
+{
+ Assert(m_pTrustedStore);
+ // verify ocsp response
+ int response = OCSP_basic_verify(basic, NULL, m_pTrustedStore, 0);
+ if (response <= 0) {
+ LogWarning("OCSP verification failed");
+ }
+
+ return response > 0;
+}
+
+void OCSP::checkRevocationStatus(OCSP_BASICRESP* basic,
+ OCSP_CERTID* id)
+{
+ ASN1_GENERALIZEDTIME* producedAt;
+ ASN1_GENERALIZEDTIME* thisUpdate;
+ ASN1_GENERALIZEDTIME* nextUpdate;
+ int reason;
+ int status;
+
+ m_responseValidity = 0;
+
+ if (!OCSP_resp_find_status(basic,
+ id,
+ &status,
+ &reason,
+ &producedAt,
+ &thisUpdate,
+ &nextUpdate))
+ {
+ ThrowMsg(Exception::VerificationError,
+ "OCSP: Failed to find certificate status.");
+ }
+
+ if (!OCSP_check_validity(thisUpdate,
+ nextUpdate,
+ MaxValidatyPeriodInSeconds,
+ MaxAge))
+ {
+ ThrowMsg(Exception::VerificationError,
+ "OCSP: Failed to check certificate validate.");
+ }
+
+ if (nextUpdate) {
+ asn1GeneralizedTimeToTimeT(nextUpdate,&m_responseValidity);
+ time_t now;
+ time(&now);
+ LogDebug("Time of next OCSP update got from server: " <<
+ m_responseValidity);
+ LogDebug("Expires in: " << (m_responseValidity - now));
+ LogDebug("Original: " << nextUpdate->data);
+ }
+
+ switch (status) {
+ case V_OCSP_CERTSTATUS_GOOD:
+ return;
+ case V_OCSP_CERTSTATUS_REVOKED:
+ ThrowMsg(Exception::CertificateRevoked, "Certificate is Revoked");
+ case V_OCSP_CERTSTATUS_UNKNOWN:
+ ThrowMsg(Exception::CertificateUnknown, "Certificate is Unknown");
+ default:
+ Assert(false && "Invalid status");
+ }
+}
+
+OCSP::OcspResponse OCSP::convertToResponse()
+{
+ using namespace SoupWrapper;
+
+ // convert memory buffer to ocsp response object
+ BUF_MEM res_bmem;
+ OCSP_RESPONSE* response;
+
+ SoupMessageSendBase::MessageBuffer buffer = m_soupMessage.getResponse();
+
+ res_bmem.length = buffer.size();
+ res_bmem.data = &buffer[0];
+ res_bmem.max = buffer.size();
+
+ BIO* res_mem_bio = BIO_new(BIO_s_mem());
+ BIO_set_mem_buf(res_mem_bio, &res_bmem, BIO_NOCLOSE);
+
+ response = d2i_OCSP_RESPONSE_bio(res_mem_bio, NULL);
+ BIO_free_all(res_mem_bio);
+
+ if (!response) {
+ LogWarning("OCSP: Failed to convert OCSP Response to DER format");
+ return std::make_pair(false, static_cast<OCSP_RESPONSE*>(NULL));
+ }
+
+ return std::make_pair(true, response);
+}
+
+void OCSP::handleInvalidResponse(int result)
+{
+ switch (result) {
+ case OCSP_RESPONSE_STATUS_MALFORMEDREQUEST:
+ LogWarning("OCSP: Server returns "
+ "OCSP_RESPONSE_STATUS_MALFORMEDREQUEST status");
+ break;
+ case OCSP_RESPONSE_STATUS_INTERNALERROR:
+ LogWarning("OCSP: Server returns "
+ "OCSP_RESPONSE_STATUS_INTERNALERROR status");
+ break;
+ case OCSP_RESPONSE_STATUS_TRYLATER:
+ LogWarning("OCSP: Server returns "
+ "OCSP_RESPONSE_STATUS_TRYLATER status");
+ break;
+ case OCSP_RESPONSE_STATUS_SIGREQUIRED:
+ LogWarning("OCSP: Server returns "
+ "OCSP_RESPONSE_STATUS_SIGREQUIRED status");
+ break;
+ case OCSP_RESPONSE_STATUS_UNAUTHORIZED:
+ LogWarning("OCSP: Server returns "
+ "OCSP_RESPONSE_STATUS_UNAUTHORIZED status");
+ break;
+ default:
+ Assert(false && "Invalid result value");
+ }
+}
+} // namespace ValidationCore
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 Tomasz Morawski(t.morawski@samsung.com)
+ * @author Michal Ciepielski(m.ciepielski@samsung.com)
+ * @author Piotr Marcinkiewicz(p.marcinkiew@samsung.com)
+ * @version 0.4
+ * @file OCPS.h
+ * @brief Routines for certificate validation over OCSP
+ */
+
+#ifndef WRT_ENGINE_SRC_VALIDATION_CORE_ENGINE_OCSP_H_
+#define WRT_ENGINE_SRC_VALIDATION_CORE_ENGINE_OCSP_H_
+
+#include <openssl/pem.h>
+#include <openssl/ocsp.h>
+#include <libsoup/soup.h>
+
+#include <string>
+#include <vector>
+#include <list>
+#include <utility>
+#include <map>
+
+#include <dpl/assert.h>
+#include <dpl/exception.h>
+#include <dpl/optional_typedefs.h>
+
+#include <vcore/scoped_gpointer.h>
+
+#include "OCSPCertMgrUtil.h"
+#include "CertificateCollection.h"
+#include "CertificateStorage.h"
+#include "VerificationStatus.h"
+#include "SSLContainers.h"
+
+#include "SoupMessageSendBase.h"
+#include "SoupMessageSendSync.h"
+/*
+ * The WRT MUST NOT allow installation of widgets with revoked signatures.
+ *
+ * The WRT MUST NOT allow use of widgets with revoked signatures.
+ *
+ * The WRT MUST support checking for revocation of widget signatures via
+ * OCSP [RFC 2560] at widget installation time, according to the following:
+ *
+ * At widget installation time, the WRT shall make several attempts
+ * (5 attempts at 6 seconds apart recommended) to establish contact with
+ * the OCSP server.
+ *
+ * If connectivity is successful and the application is validated, the
+ * installation process shall continue.
+ *
+ * If connectivity is successful and if the widget signature is
+ * determined to be revoked, the WRT shall issue a suitable error message
+ * and cancel installation.
+ *
+ * If connectivity is successful and revocation status is unknown or if
+ * connectivity is unsuccessful, the user must be notified that the
+ * widget was unable to be installed as trusted - the certification of
+ * the widget signature has not been validated -, and prompt the user to allow
+ * the user to install the widget as an untrusted application, or reject
+ * the installation.
+ *
+ * The WRT MUST support checking for revocation of widget signatures via OCSP
+ * [RFC 2560] at widget runtime.
+ *
+ * The WRT MUST support OCSP access policy.
+ */
+
+namespace ValidationCore {
+
+class OCSP
+// : public RevocationCheckerBase
+{
+ public:
+ static const char* DEFAULT_RESPONDER_URI_ENV;
+
+ VerificationStatus checkEndEntity(const CertificateCollection &certList);
+ OCSP();
+
+ enum DigestAlgorithm
+ {
+ SHA1,
+ SHA224,
+ SHA256,
+ SHA384,
+ SHA512
+ };
+ typedef std::map <DigestAlgorithm, const EVP_MD*> DigestAlgorithmMap;
+ /**
+ * Sets digest algorithm for certid in ocsp request
+ */
+ void setDigestAlgorithmForCertId(DigestAlgorithm alg);
+
+ /**
+ * Sets digest algorithm for certid in ocsp request
+ */
+ void setDigestAlgorithmForRequest(DigestAlgorithm alg);
+
+ void setTrustedStore(const CertificateList& certs);
+
+ VerificationStatusSet validateCertificateList(const CertificateList &certs);
+
+ VerificationStatus validateCertificate(CertificatePtr argCert,
+ CertificatePtr argIssuer);
+
+ void setDefaultResponder(const char* uri)
+ {
+ Assert(uri);
+ m_strResponderURI = DPL::FromUTF8String(uri);
+ }
+
+ void setUseDefaultResponder(bool value)
+ {
+ m_bUseDefResponder = value;
+ }
+
+ /**
+ * @return time when response will become invalid - for list of
+ * certificates, this is the minimum of all validities; value is
+ * valid only for not-revoked certificates (non error validation result)
+ */
+ time_t getResponseValidity()
+ {
+ return m_responseValidity;
+ }
+
+ private:
+ typedef WRT::ScopedGPointer<SoupSession> ScopedSoupSession;
+ typedef WRT::ScopedGPointer<SoupMessage> ScopedSoupMessage;
+
+ void handleInvalidResponse(int result);
+ void sendHTTPRequest(ScopedSoupSession& session,
+ ScopedSoupMessage& msg,
+ const char* host,
+ const char* port,
+ const char* path,
+ char* requestBuffer,
+ size_t reqestSize);
+ void sendRequest(const std::string& uri,
+ char* requestBuffer,
+ size_t requestSize,
+ char** responseBuffer,
+ size_t* responseSize);
+
+ class Exception
+ {
+ public:
+ DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+ DECLARE_EXCEPTION_TYPE(Base, ConnectionError)
+ DECLARE_EXCEPTION_TYPE(Base, CertificateRevoked)
+ DECLARE_EXCEPTION_TYPE(Base, CertificateUnknown)
+ DECLARE_EXCEPTION_TYPE(Base, VerificationError)
+ DECLARE_EXCEPTION_TYPE(Base, RetrieveCertFromStoreError)
+ DECLARE_EXCEPTION_TYPE(Base, VerificationNotSupport)
+ };
+
+ const EVP_MD* m_pCertIdDigestAlg;
+ const EVP_MD* m_pRequestDigestAlg;
+ static DigestAlgorithmMap m_sDigestAlgMap;
+
+ typedef std::pair<char*, size_t> HttpResponseBuffer;
+
+ SoupWrapper::SoupMessageSendBase::RequestStatus sendOcspRequest(
+ OCSP_REQUEST* argRequest,
+ const DPL::OptionalString& argUri);
+
+ //! Validates a single certificate
+ /*!
+ * @param cert The certificate to check
+ * @param issuer A certificate used to sign the certificate to check.
+ */
+
+ struct CreateRequestResult
+ {
+ bool success;
+ OCSP_REQUEST* ocspRequest;
+ OCSP_CERTID* ocspCertId;
+ CreateRequestResult(bool argSuccess = false,
+ OCSP_REQUEST* argOcspRequest = NULL,
+ OCSP_CERTID* argOcspCertId = NULL) :
+ success(argSuccess),
+ ocspRequest(argOcspRequest),
+ ocspCertId(argOcspCertId)
+ {
+ }
+ };
+
+ //! Creates a OCSP request
+ /*!
+ * @param request Returns created OCSP_REQUEST
+ * @param id Returns CertId that is used to find proper OCSP result in
+ * the OCSP response (@see checkRevocationStatus for more details).
+ *
+ */
+ CreateRequestResult createRequest(CertificatePtr argCert,
+ CertificatePtr argIssuer);
+
+ OCSP_CERTID* addSerial(CertificatePtr argCert,
+ CertificatePtr argIssuer);
+
+ void validateResponse(OCSP_REQUEST* argRequest,
+ OCSP_RESPONSE* argResponse,
+ OCSP_CERTID* argCertId);
+
+ //! Create a X509 store
+ bool verifyResponse(OCSP_BASICRESP* argResponse);
+
+ void checkRevocationStatus(OCSP_BASICRESP* argBasicResponse,
+ OCSP_CERTID* argCertId);
+
+ typedef std::pair<bool, OCSP_RESPONSE*> OcspResponse;
+
+ OcspResponse convertToResponse();
+
+ time_t m_responseValidity;
+ bool m_bUseNonce;
+ bool m_bUseDefResponder;
+ DPL::String m_strResponderURI;
+ bool m_bSignRequest;
+ EVP_PKEY* m_pSignKey;
+ CertificatePtr m_pSignCert;
+ SSLSmartContainer <X509_STORE> m_pTrustedStore;
+ SoupWrapper::SoupMessageSendSync m_soupMessage;
+};
+} // ValidationCore
+
+#endif //ifndef WRT_ENGINE_SRC_VALIDATION_CORE_ENGINE_OCSP_H_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 Michal Ciepielski(m.ciepielski@samsung.com)
+ * @version 0.3
+ * @brief
+ */
+
+#include "OCSPCertMgrUtil.h"
+#include "SSLContainers.h"
+
+#include <openssl/pem.h>
+#include <openssl/ocsp.h>
+#include <dpl/log/log.h>
+#include <dpl/scoped_resource.h>
+#include <string.h>
+#include <iostream>
+#include <string>
+
+#include <cert-service.h>
+
+namespace {
+const int MAX_BUF = 1024;
+
+struct ContextDeleter
+{
+ typedef CERT_CONTEXT* Type;
+ static Type NullValue()
+ {
+ return NULL;
+ }
+ static void Destroy(Type context)
+ {
+ if (context) {
+ cert_svc_cert_context_final(context);
+ }
+ }
+};
+}
+
+namespace ValidationCore {
+namespace OCSPCertMgrUtil {
+/*
+ * TODO This API function should be changed to:
+ * CertifiatePtr getCertFromStore(const std::string &subject);
+ *
+ * All of cert_svc function could return error because input
+ * data are corruped. That's why I dont want to throw exceptions
+ * in this function.
+ */
+void getCertFromStore(X509_NAME *subject,
+ X509 **xcert)
+{
+ if (!xcert || *xcert || !subject) {
+ LogError("Invalid input!");
+ return;
+ }
+
+ typedef DPL::ScopedResource<ContextDeleter> ScopedContext;
+
+ int result;
+ char buffer[MAX_BUF];
+ const unsigned char* ptr = NULL;
+ X509 *pCertificate = NULL;
+ cert_svc_filename_list *fileList = NULL;
+
+ X509_NAME_oneline(subject, buffer, MAX_BUF);
+
+ ScopedContext ctx(cert_svc_cert_context_init());
+ if (ctx.Get() == NULL) {
+ LogWarning("Error in cert_svc_cert_context_init.");
+ return;
+ }
+
+ LogDebug("Search certificate with subject: " << buffer);
+ result = cert_svc_search_certificate(ctx.Get(), SUBJECT_STR, buffer);
+ LogDebug("Search finished!");
+
+ if (CERT_SVC_ERR_NO_ERROR != result) {
+ LogWarning("Error during certificate search");
+ return;
+ }
+
+ fileList = ctx.Get()->fileNames;
+
+ if (fileList == NULL) {
+ LogDebug("No certificate found");
+ return;
+ }
+
+ if (fileList->filename == NULL) {
+ LogWarning("Empty filename");
+ return;
+ }
+
+ LogDebug("Found cert file: " << fileList->filename);
+ ScopedContext ctx2(cert_svc_cert_context_init());
+
+ if (ctx2.Get() == NULL) {
+ LogWarning("Error in cert_svc_cert_context_init.");
+ return;
+ }
+
+ // TODO add read_certifcate_from_file function to Certificate.h
+ if (CERT_SVC_ERR_NO_ERROR !=
+ cert_svc_load_file_to_context(ctx2.Get(), fileList->filename)) {
+ LogWarning("Error in cert_svc_load_file_to_context");
+ return;
+ }
+
+ ptr = ctx2.Get()->certBuf->data;
+ // create a certificate from mem buff
+ pCertificate = d2i_X509(NULL, &ptr, ctx2.Get()->certBuf->size);
+
+ if (pCertificate == NULL) {
+ LogWarning("Error during certificate conversion in d2i_X509");
+ return;
+ }
+
+ *xcert = pCertificate;
+ if (fileList->next != NULL) {
+ LogError("There is more then one certificate with same subject :/");
+ // TODO Implement me.
+ for (fileList = fileList->next;
+ fileList != NULL;
+ fileList = fileList->next) {
+ LogError(
+ "Additional certificate with same subject: " <<
+ fileList->filename);
+ }
+ }
+}
+
+CertificatePtr getParentFromStore(const CertificatePtr &certificate)
+{
+ Assert(certificate.Get());
+ X509* rawPtr = certificate->getX509();
+
+ /* TODO Add getIssuerName function to Certificate.h */
+ X509_NAME *name = X509_get_issuer_name(rawPtr);
+
+ X509* rawTemp = NULL;
+ getCertFromStore(name, &rawTemp);
+
+ if (rawTemp == NULL) {
+ return CertificatePtr();
+ }
+
+ SSLSmartContainer<X509> scope(rawTemp);
+ return CertificatePtr(new Certificate(rawTemp));
+}
+
+CertificateList completeCertificateChain(const CertificateList &certificateList)
+{
+ CertificateList result = certificateList;
+ CertificatePtr last = result.back();
+ if (last->isSignedBy(last)) {
+ return result;
+ }
+ CertificatePtr parent = getParentFromStore(last);
+ if (parent.Get()) {
+ result.push_back(parent);
+ }
+ return result;
+}
+} // namespace OCSPCertMgrUtil
+} // namespace ValidationCore
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 Tomasz Morawski(t.morawski@samsung.com)
+ * @author Michal Ciepielski(m.ciepielski@samsung.com)
+ * @version 0.2
+ * @brief
+ */
+
+#ifndef _WRT_OCSP_CERT_MGR_UTIL_H_
+#define _WRT_OCSP_CERT_MGR_UTIL_H_
+
+#include <openssl/x509.h>
+
+#include "Certificate.h"
+
+namespace ValidationCore {
+namespace OCSPCertMgrUtil {
+void getCertFromStore(X509_NAME *subject,
+ X509 **xcert);
+CertificatePtr getParentFromStore(const CertificatePtr &certificate);
+/*
+ * Look for "parent" certificate from store.
+ * It returns new certificate chain.
+ */
+CertificateList completeCertificateChain(const CertificateList &certList);
+} // namespace OCSPCertMgrUtil
+} // namespace ValidationCore
+#endif
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 Tomasz Morawski(t.morawski@samsung.com)
+ * @version 0.1
+ * @brief
+ */
+
+#include <openssl/ocsp.h>
+
+/*
+ * This function is needed to fix "Invalid conversion from void* to unsigned char*"
+ * C++ compiler error during calling i2d_OCSP_REQUEST_bio macro
+ */
+int convertToBuffer(OCSP_REQUEST *req, char **buf, int *size) {
+ BIO *req_mem_bio;
+ BUF_MEM req_bmem;
+
+ /*
+ * size and membuffer for request
+ */
+ *size = i2d_OCSP_REQUEST(req, NULL);
+ *buf = (char*) malloc(*size);
+
+ if (!*buf)
+ return 0;
+
+ /* copy request into buffer */
+ req_bmem.length = 0;
+ req_bmem.data = *buf;
+ req_bmem.max = *size;
+
+ /*
+ * create a new buffer using openssl
+ */
+ req_mem_bio = BIO_new(BIO_s_mem());
+
+ if (!req_mem_bio) {
+ /*
+ * creation failed, return
+ */
+ free(*buf);
+ *buf = NULL;
+ return 0;
+ }
+
+ BIO_set_mem_buf(req_mem_bio, &req_bmem, BIO_NOCLOSE);
+
+ /*
+ * prepare request
+ */
+ if (i2d_OCSP_REQUEST_bio(req_mem_bio, req) <= 0) {
+ free(*buf);
+ *buf = NULL;
+ BIO_free_all(req_mem_bio);
+ return 0;
+ }
+
+ /*
+ * check consistency
+ */
+ if (*size != ((int)req_bmem.length) || req_bmem.length != req_bmem.max)
+ {
+ free(*buf);
+ *buf = NULL;
+ BIO_free_all(req_mem_bio);
+ return 0;
+ }
+
+ /*
+ * free all reserved memory
+ */
+ BIO_free_all(req_mem_bio);
+
+ /*
+ * and return success
+ */
+ return 1;
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file ParserSchema.h
+ * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 1.0
+ * @brief
+ */
+#ifndef _PARSERSCHEMA_H_
+#define _PARSERSCHEMA_H_
+
+#include <map>
+#include <string>
+
+#include <dpl/log/log.h>
+
+#include "SaxReader.h"
+
+namespace ValidationCore {
+namespace ParserSchemaException {
+DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+DECLARE_EXCEPTION_TYPE(Base, XmlReaderError)
+DECLARE_EXCEPTION_TYPE(Base, CertificateLoaderError)
+DECLARE_EXCEPTION_TYPE(Base, UnsupportedAlgorithm)
+DECLARE_EXCEPTION_TYPE(Base, UnsupportedValue)
+}
+
+template<typename ParserType, typename DataType>
+class ParserSchema
+{
+ public:
+ struct TagDescription
+ {
+ TagDescription(const std::string &tag,
+ const std::string & xmlNamespace) :
+ tagName(tag),
+ namespaceUri(xmlNamespace)
+ {
+ }
+
+ std::string tagName;
+ std::string namespaceUri;
+
+ bool operator<(const TagDescription &second) const
+ {
+ if (tagName < second.tagName) {
+ return true;
+ }
+ if (tagName > second.tagName) {
+ return false;
+ }
+ if (namespaceUri < second.namespaceUri) {
+ return true;
+ }
+ return false;
+ }
+ };
+
+ ParserSchema(ParserType * parser) :
+ m_functions(parser)
+ {
+ }
+
+ virtual ~ParserSchema()
+ {
+ }
+
+ void initialize(const std::string &filename,
+ bool defaultArgs,
+ SaxReader::ValidationType valType,
+ const std::string &xmlschema)
+ {
+ Try
+ {
+ m_reader.initialize(filename, defaultArgs, valType, xmlschema);
+ }
+ Catch(SaxReader::Exception::Base)
+ {
+ ReThrowMsg(ParserSchemaException::XmlReaderError, "XmlReaderError");
+ }
+ }
+
+ void deinitialize()
+ {
+ m_reader.deinitialize();
+ }
+
+ void read(DataType &dataContainer)
+ {
+ Try {
+ while (m_reader.next()) {
+ switch (m_reader.type()) {
+ case SaxReader::NODE_BEGIN:
+ beginNode(dataContainer);
+ break;
+ case SaxReader::NODE_END:
+ endNode(dataContainer);
+ break;
+ case SaxReader::NODE_TEXT:
+ textNode(dataContainer);
+ break;
+ default:
+ // LogInfo("Unknown Type Node");
+ break;
+ }
+ }
+ }
+ Catch(SaxReader::Exception::Base)
+ {
+ ReThrowMsg(ParserSchemaException::XmlReaderError, "XmlReaderError");
+ }
+ }
+
+ typedef void (ParserType::*FunctionPtr)(DataType &data);
+ typedef std::map<TagDescription, FunctionPtr> FunctionMap;
+
+ void addBeginTagCallback(const std::string &tag,
+ const std::string &namespaceUri,
+ FunctionPtr function)
+ {
+ TagDescription desc(tag, namespaceUri);
+ m_beginFunctionMap[desc] = function;
+ }
+
+ void addEndTagCallback(const std::string &tag,
+ const std::string &namespaceUri,
+ FunctionPtr function)
+ {
+ TagDescription desc(tag, namespaceUri);
+ m_endFunctionMap[desc] = function;
+ }
+
+ SaxReader& getReader(void)
+ {
+ return m_reader;
+ }
+
+ std::string& getText(void)
+ {
+ return m_textNode;
+ }
+
+ protected:
+ void beginNode(DataType &dataContainer)
+ {
+ TagDescription desc(m_reader.name(), m_reader.namespaceURI());
+ FunctionPtr fun = m_beginFunctionMap[desc];
+
+ if (fun == 0) {
+ LogDebug("No function found for xml tag: " << m_reader.name());
+ return;
+ }
+
+ (m_functions->*fun)(dataContainer);
+ }
+
+ void endNode(DataType &dataContainer)
+ {
+ TagDescription desc(m_reader.name(), m_reader.namespaceURI());
+ FunctionPtr fun = m_endFunctionMap[desc];
+
+ if (fun == 0) {
+ LogDebug("No function found for xml tag: " << m_reader.name());
+ return;
+ }
+
+ (m_functions->*fun)(dataContainer);
+ }
+
+ void textNode(DataType &dataContainer)
+ {
+ (void)dataContainer;
+ m_textNode = m_reader.value();
+ }
+
+ ParserType *m_functions;
+
+ SaxReader m_reader;
+ FunctionMap m_beginFunctionMap;
+ FunctionMap m_endFunctionMap;
+
+ // temporary values require due parsing textNode
+ std::string m_textNode;
+};
+} // namespace ValidationCore
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <dirent.h>
+#include <errno.h>
+#include <fstream>
+#include <memory>
+
+#include <dpl/errno_string.h>
+#include <dpl/log/log.h>
+
+#include "Base64.h"
+#include "ReferenceValidator.h"
+
+namespace {
+const char *SPECIAL_SYMBOL_CURRENT_DIR = ".";
+const char *SPECIAL_SYMBOL_UPPER_DIR = "..";
+const char *SPECIAL_SYMBOL_AUTHOR_SIGNATURE_FILE = "author-signature.xml";
+const char *REGEXP_DISTRIBUTOR_SIGNATURE = "^signature[1-9][0-9]*\\.xml";
+} // namespace anonymous
+
+namespace ValidationCore {
+ReferenceValidator::ReferenceValidator(const std::string &dirpath) :
+ m_dirpath(dirpath),
+ m_signatureRegexp(REGEXP_DISTRIBUTOR_SIGNATURE)
+{
+}
+
+ReferenceValidator::Result ReferenceValidator::checkReferences(
+ const SignatureData &signatureData)
+{
+ return dfsCheckDirectories(signatureData, std::string());
+}
+
+ReferenceValidator::Result ReferenceValidator::dfsCheckDirectories(
+ const SignatureData &signatureData,
+ const std::string &directory)
+{
+ DIR *dp;
+ struct dirent *dirp;
+ std::string currentDir = m_dirpath + directory;
+
+ if ((dp = opendir(currentDir.c_str())) == NULL) {
+ LogError("Error opening directory: " << currentDir.c_str());
+ m_errorDescription = currentDir;
+ return ERROR_OPENING_DIR;
+ }
+
+ for (errno = 0; (dirp = readdir(dp)) != NULL; errno = 0) {
+ if (!strcmp(dirp->d_name, SPECIAL_SYMBOL_CURRENT_DIR)) {
+ continue;
+ }
+
+ if (!strcmp(dirp->d_name, SPECIAL_SYMBOL_UPPER_DIR)) {
+ continue;
+ }
+
+ if (currentDir == m_dirpath && dirp->d_type == DT_REG &&
+ !strcmp(dirp->d_name,
+ SPECIAL_SYMBOL_AUTHOR_SIGNATURE_FILE) &&
+ signatureData.isAuthorSignature()) {
+ continue;
+ }
+
+ if (currentDir == m_dirpath && dirp->d_type == DT_REG &&
+ isDistributorSignature(dirp->d_name)) {
+ continue;
+ }
+
+ if (dirp->d_type == DT_DIR) {
+ LogDebug("Open directory: " << (directory + dirp->d_name));
+ std::string tmp_directory = directory + dirp->d_name + "/";
+ Result result = dfsCheckDirectories(signatureData, tmp_directory);
+ if (result != NO_ERROR) {
+ closedir(dp);
+ return result;
+ }
+ } else if (dirp->d_type == DT_REG) {
+ LogDebug("Found file: " << (directory + dirp->d_name));
+ const ReferenceSet &referenceSet = signatureData.getReferenceSet();
+ if (referenceSet.end() ==
+ referenceSet.find(directory + dirp->d_name)) {
+ closedir(dp);
+ m_errorDescription = directory + dirp->d_name;
+ return ERROR_REFERENCE_NOT_FOUND;
+ }
+ } else {
+ LogError("Unknown file type.");
+ closedir(dp);
+ m_errorDescription = directory + dirp->d_name;
+ return ERROR_UNSUPPORTED_FILE_TYPE;
+ }
+ }
+
+ if (errno != 0) {
+ m_errorDescription = DPL::GetErrnoString();
+ LogError("readdir failed. Errno code: " << errno <<
+ " Description: " << m_errorDescription);
+ closedir(dp);
+ return ERROR_READING_DIR;
+ }
+
+ closedir(dp);
+
+ return NO_ERROR;
+}
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 _REFERENCEVALIDATOR_H_
+#define _REFERENCEVALIDATOR_H_
+
+#include <pcrecpp.h>
+
+#include "SignatureData.h"
+
+namespace ValidationCore {
+class ReferenceValidator
+{
+ public:
+ enum Result
+ {
+ NO_ERROR = 0,
+ ERROR_OPENING_DIR,
+ ERROR_READING_DIR,
+ ERROR_UNSUPPORTED_FILE_TYPE,
+ ERROR_REFERENCE_NOT_FOUND
+ };
+
+ ReferenceValidator(const std::string &dirpath);
+
+ virtual ~ReferenceValidator()
+ {
+ }
+
+ Result checkReferences(const SignatureData &signatureData);
+
+ private:
+
+ Result dfsCheckDirectories(const SignatureData &signatureData,
+ const std::string &directory);
+
+ inline bool isDistributorSignature(const char *cstring) const
+ {
+ return m_signatureRegexp.FullMatch(cstring);
+ }
+
+ std::string m_dirpath;
+ std::string m_errorDescription;
+ pcrecpp::RE m_signatureRegexp;
+};
+}
+
+#endif // _REFERENCEVALIDATOR_H_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 Piotr Marcinkiewicz(p.marcinkiew@samsung.com)
+ * @version 0.4
+ * @file CommonCertValidator.cpp
+ * @brief Common routines for certificate validation over OCSP and CRL
+ */
+
+#include "RevocationCheckerBase.h"
+
+#include <cstdlib>
+
+#include <openssl/pem.h>
+
+#include <dpl/scoped_fclose.h>
+
+#include "Certificate.h"
+#include "CertificateCollection.h"
+
+namespace {
+const char DefaultBundlePatch[] = "/opt/etc/ssl/certs/ca-certificates.crt";
+} //Anonymous name space
+
+namespace ValidationCore {
+CertificatePtr RevocationCheckerBase::loadPEMFile(const char* fileName)
+{
+ DPL::ScopedFClose fd(fopen(fileName, "rb"));
+
+ // no such file, return NULL
+ if (!fd.Get()) {
+ return CertificatePtr();
+ }
+
+ // create a new X509 certificate basing on file
+ CertificatePtr cert(new Certificate(PEM_read_X509(fd.Get(),
+ NULL,
+ NULL,
+ NULL)));
+ return cert;
+}
+
+bool RevocationCheckerBase::sortCertList(CertificateList &lCertificates)
+{
+ CertificateCollection collection;
+ collection.load(lCertificates);
+
+ if (collection.sort()) {
+ lCertificates = collection.getChain();
+ return true;
+ }
+ return false;
+}
+
+} // ValidationCore
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 Piotr Marcinkiewicz(p.marcinkiew@samsung.com)
+ * @version 0.4
+ * @file CommonCertValidator.h
+ * @brief Common routines for certificate validation over OCSP and CRL
+ */
+
+#ifndef WRT_ENGINE_SRC_VALIDATION_CORE_REVOCATIONCHECKERBASE_H_
+#define WRT_ENGINE_SRC_VALIDATION_CORE_REVOCATIONCHECKERBASE_H_
+
+#include <string>
+
+#include "Certificate.h"
+
+namespace ValidationCore {
+class RevocationCheckerBase
+{
+ public:
+ //! Loads a PEM file and returns X509 certificate object.
+ static CertificatePtr loadPEMFile(const char* path);
+
+ //! Sorts a list of certficates and verifies them if they form
+ //! a valid chain
+ static bool sortCertList(CertificateList &cert) __attribute__((deprecated));
+};
+} // ValidationCore
+
+#endif //ifndef WRT_ENGINE_SRC_VALIDATION_CORE_REVOCATIONCHECKERBASE_H_
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 _SSLCONTAINERS_H
+#define _SSLCONTAINERS_H
+
+#include <openssl/x509v3.h>
+#include <openssl/ocsp.h>
+
+/*
+ * default deleter functor with no overloaded operator()
+ */
+template <typename T>
+struct MySSLFree {};
+
+/*
+ * macro for defining custom deleters for openssl structs
+ * usage DECLARE_DELETER(OpenSSLType)
+ */
+#define DECLARE_DELETER(Type) template<> \
+ struct MySSLFree <Type> \
+ { \
+ void operator() (Type* p) \
+ { \
+ Type ## _free(p); \
+ } \
+ \
+ };
+
+/*
+ * declare custom deleter for X509 structs
+ */
+DECLARE_DELETER(X509)
+/*
+ * declare custom deleter for OCSP_REQUEST structs
+ */
+DECLARE_DELETER(OCSP_REQUEST)
+/*
+ * declare custom deleter for OCSP_RESPONSE structs
+ */
+DECLARE_DELETER(OCSP_RESPONSE)
+/*
+ * declare custom deleter for OCSP_CERTID structs
+ */
+DECLARE_DELETER(OCSP_CERTID)
+/*
+ * declare custom deleter for OCSP_BASICRESP structs
+ */
+DECLARE_DELETER(OCSP_BASICRESP)
+/*
+ * declare custom deleter for X509_STORE structs
+ */
+DECLARE_DELETER(X509_STORE)
+
+/*
+ * undef it, so anyone could use that macro name
+ */
+#undef DECLARE_DELETER
+
+/*
+ * OpenSSL smart container
+ * usage SSLSmartContainer <OpenSSLType> smartptr = ptrToOpenSSLType
+ * remember to add OpenSSLType to macro list few lines above
+ */
+template <typename T, typename deleter = MySSLFree<T> >
+class SSLSmartContainer
+{
+ public:
+ SSLSmartContainer() : m_pData(NULL)
+ {
+ }
+
+ /*
+ * explicit constructor, we don't want any auto casting
+ */
+ explicit SSLSmartContainer(T* pData)
+ {
+ m_pData = pData;
+ }
+
+ /*
+ * overloaded assignment operator
+ */
+ SSLSmartContainer & operator=(SSLSmartContainer& pContainer)
+ {
+ /*
+ * check if no assignment was done before
+ */
+ if (this != &pContainer) {
+ // if so, free internal data
+ deleter ssl_free;
+ ssl_free(m_pData);
+
+ // and assign new
+ m_pData = pContainer.m_pData;
+
+ pContainer.m_pData = NULL;
+ }
+
+ return *this;
+ }
+
+ SSLSmartContainer & operator=(T* pData)
+ {
+ /*
+ * check if no assignment was done before
+ */
+ if (m_pData != pData) {
+ // if so, free internal data
+ deleter ssl_free;
+ ssl_free(m_pData);
+
+ // and assign new
+ m_pData = pData;
+ }
+
+ return *this;
+ }
+
+ ~SSLSmartContainer()
+ {
+ deleter ssl_free;
+ ssl_free(m_pData);
+ }
+
+ /*
+ * overloaded operators for standardptr - like usage
+ */
+ SSLSmartContainer & operator*()
+ {
+ return *m_pData;
+ }
+ SSLSmartContainer* operator->()
+ {
+ return m_pData;
+ }
+
+ /*
+ * auto cast to T operator
+ */
+ operator T *() const { return m_pData;
+ }
+
+ /*
+ * detachs internal pointer from smart pointer
+ */
+ T* DetachPtr()
+ {
+ T* pData = m_pData;
+ m_pData = NULL;
+ return pData;
+ }
+
+ private:
+ /*
+ * blocked assignment from another types operator
+ */
+ template <typename S>
+ T & operator = (S& pContainer)
+ {
+ return *this;
+ }
+
+ /*
+ * internal data
+ */
+ T* m_pData;
+};
+
+#endif /* _SSLCONTAINERS_H */
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file SaxReader.cpp
+ * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 1.0
+ * @brief Simple c++ interface for libxml2.
+ */
+#include <dpl/assert.h>
+#include <dpl/exception.h>
+#include <dpl/log/log.h>
+
+#include "SaxReader.h"
+
+namespace ValidationCore {
+SaxReader::SaxReader() :
+ m_reader(0)
+{
+}
+
+SaxReader::~SaxReader()
+{
+ if (m_reader) {
+ deinitialize();
+ }
+}
+
+void SaxReader::initialize(const std::string &filename,
+ bool defaultArgs,
+ ValidationType validate,
+ const std::string &schema)
+{
+ Assert(m_reader == 0 && "Double initialization of SaxReader");
+
+ LogDebug("SaxReader opening file: " << filename);
+
+ /*
+ * create a new xml text reader
+ */
+ m_reader = xmlNewTextReaderFilename(filename.c_str());
+
+ if (m_reader == NULL) {
+ /*
+ * no such file, return
+ */
+ LogWarning("Error during opening file " << filename);
+ Throw(Exception::FileOpeningError);
+ }
+ if (validate == VALIDATION_XMLSCHEME &&
+ xmlTextReaderSchemaValidate(m_reader, schema.c_str())) {
+ /*
+ * unable to turn on schema validation
+ */
+ LogError("Turn on Schema validation failed.");
+ ThrowMsg(Exception::ParserInternalError,
+ "Turn on Scheme validation failed!");
+ }
+ // Path to DTD schema is taken from xml file.
+ if (validate == VALIDATION_DTD &&
+ xmlTextReaderSetParserProp(m_reader, XML_PARSER_VALIDATE, 1)) {
+ /*
+ * unable to turn on DTD validation
+ */
+ LogError("Turn on DTD validation failed!");
+ ThrowMsg(Exception::ParserInternalError,
+ "Turn on DTD validation failed!");
+ }
+ if (defaultArgs &&
+ xmlTextReaderSetParserProp(m_reader, XML_PARSER_DEFAULTATTRS, 1)) {
+ /*
+ * unable to turn on default arguments
+ */
+ LogError("Turn on default arguments failed");
+ ThrowMsg(Exception::ParserInternalError,
+ "Turn on Default Arguments failed!");
+ }
+}
+
+void SaxReader::deinitialize()
+{
+ xmlFreeTextReader(m_reader);
+ m_reader = 0;
+}
+
+bool SaxReader::next()
+{
+ int res = xmlTextReaderRead(m_reader);
+
+ if (0 == xmlTextReaderIsValid(m_reader)) {
+ LogWarning("Throw exception file not valid!");
+ Throw(Exception::FileNotValid);
+ }
+
+ if (res == 1) {
+ return true;
+ }
+
+ if (res == 0) {
+ return false;
+ }
+ LogError("ParserInternalError");
+ Throw(Exception::ParserInternalError);
+}
+
+void SaxReader::next(const std::string &token)
+{
+ xmlTextReaderRead(m_reader);
+ if (0 == xmlTextReaderIsValid(m_reader)) {
+ /*
+ * invalid file
+ */
+ LogWarning("Throw exception file not valid!");
+ Throw(Exception::FileNotValid);
+ }
+
+ xmlChar *name = xmlTextReaderName(m_reader);
+
+ if (name == NULL) {
+ /*
+ * invalid file
+ */
+ LogWarning("File not Valid");
+ Throw(Exception::FileNotValid);
+ }
+
+ if (token == reinterpret_cast<const char*>(name)) {
+ xmlFree(name);
+ } else {
+ /*
+ * we encountered wrong token
+ */
+ xmlFree(name);
+ LogWarning("Wrong Token");
+ Throw(Exception::WrongToken);
+ }
+}
+
+bool SaxReader::isEmpty(void)
+{
+ int ret = xmlTextReaderIsEmptyElement(m_reader);
+ if (-1 == ret) {
+ LogError("Parser Internal Error");
+ Throw(Exception::ParserInternalErrorInEmptyQuery);
+ }
+ return ret;
+}
+
+std::string SaxReader::attribute(const std::string &token,
+ ThrowType throwStatus)
+{
+ std::string value;
+ xmlChar *attr = xmlTextReaderGetAttribute(m_reader, BAD_CAST(token.c_str()));
+ if ((NULL == attr) && (throwStatus == THROW_DISABLE)) {
+ /*
+ * return empty string
+ */
+ //TODO why not DPL::Optional?
+ return std::string();
+ }
+ if (NULL == attr) {
+ /*
+ * error during read attribute
+ */
+ LogError("Error in reading attribute.");
+ Throw(Exception::ParserInternalErrorInReadingAttribute);
+ }
+
+ /*
+ * cast it to val and return it
+ */
+ value = reinterpret_cast<const char *>(attr);
+ xmlFree(attr);
+ return value;
+}
+
+// KW std::string SaxReader::fullName(){
+// KW std::string value;
+// KW xmlChar *name = xmlTextReaderName(m_reader);
+// KW if(NULL == name) {
+// KW LogError("Error in reading name.");
+// KW Throw(Exception::ErrorReadingName);
+// KW }
+// KW value = reinterpret_cast<const char *>(name);
+// KW xmlFree(name);
+// KW return value;
+// KW }
+
+std::string SaxReader::name()
+{
+ std::string value;
+ xmlChar *name = xmlTextReaderName(m_reader);
+ if (NULL == name) {
+ LogError("Error in reading name.");
+ Throw(Exception::ErrorReadingName);
+ }
+ value = reinterpret_cast<const char *>(name);
+ xmlFree(name);
+ size_t pos = value.find_last_of(":");
+ if (pos != std::string::npos) {
+ value.erase(0, pos + 1);
+ }
+ return value;
+}
+
+std::string SaxReader::namespaceURI()
+{
+ std::string value;
+ xmlChar *name = xmlTextReaderNamespaceUri(m_reader);
+ if (NULL != name) {
+ value = reinterpret_cast<const char *>(name);
+ xmlFree(name);
+ }
+ return value;
+}
+
+std::string SaxReader::value()
+{
+ std::string value;
+ /*
+ * get value of node
+ */
+ xmlChar *text = xmlTextReaderValue(m_reader);
+ if (NULL == text) {
+ LogError("Error in reading value");
+ Throw(Exception::ErrorReadingValue);
+ }
+ value = reinterpret_cast<const char*>(text);
+ /*
+ * free text and return the val
+ */
+ xmlFree(text);
+ return value;
+}
+
+SaxReader::NodeType SaxReader::type()
+{
+ xmlReaderTypes type =
+ static_cast<xmlReaderTypes>(xmlTextReaderNodeType(m_reader));
+ switch (type) {
+ case XML_READER_TYPE_ELEMENT:
+ return NODE_BEGIN;
+ case XML_READER_TYPE_END_ELEMENT:
+ return NODE_END;
+ case XML_READER_TYPE_TEXT:
+ return NODE_TEXT;
+ case XML_READER_TYPE_NONE:
+ case XML_READER_TYPE_ATTRIBUTE:
+ case XML_READER_TYPE_CDATA:
+ case XML_READER_TYPE_ENTITY_REFERENCE:
+ case XML_READER_TYPE_ENTITY:
+ case XML_READER_TYPE_PROCESSING_INSTRUCTION:
+ case XML_READER_TYPE_COMMENT:
+ case XML_READER_TYPE_DOCUMENT:
+ case XML_READER_TYPE_DOCUMENT_TYPE:
+ case XML_READER_TYPE_DOCUMENT_FRAGMENT:
+ case XML_READER_TYPE_NOTATION:
+ case XML_READER_TYPE_WHITESPACE:
+ case XML_READER_TYPE_SIGNIFICANT_WHITESPACE:
+ case XML_READER_TYPE_END_ENTITY:
+ case XML_READER_TYPE_XML_DECLARATION:
+ default:
+ return NODE_UNSUPPORTED;
+ }
+}
+
+void SaxReader::dumpNode(std::string &buffer)
+{
+ /*
+ * size of buffer
+ */
+ int size;
+ /*
+ * pointer to buffer
+ */
+ xmlBufferPtr buff = xmlBufferCreate();
+
+ xmlNodePtr node = xmlTextReaderExpand(m_reader);
+
+ if (node == NULL) {
+ /*
+ * internal parser error
+ */
+ xmlBufferFree(buff);
+ LogError("Parser Internal Error");
+ Throw(Exception::ParserInternalError);
+ }
+
+ /*
+ * get a size and fill in a buffer
+ */
+ size = xmlNodeDump(buff, node->doc, node, 0, 0);
+ buffer.insert(0, reinterpret_cast<char*>(buff->content), size);
+ xmlBufferFree(buff);
+}
+} // namespace ValidationCore
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file SaxReader.h
+ * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 1.0
+ * @brief Simple c++ interface for libxml2.
+ */
+#ifndef _SAXREADER_H_
+#define _SAXREADER_H_
+
+#include <string>
+#include <libxml/xmlreader.h>
+#include <dpl/exception.h>
+
+namespace ValidationCore {
+class SaxReader
+{
+ public:
+ SaxReader();
+ ~SaxReader();
+
+ /*
+ * custom exceptions
+ */
+ class Exception
+ {
+ public:
+ DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+ DECLARE_EXCEPTION_TYPE(Base, FileOpeningError)
+ DECLARE_EXCEPTION_TYPE(Base, FileNotValid)
+ DECLARE_EXCEPTION_TYPE(Base, ParserInternalError)
+ DECLARE_EXCEPTION_TYPE(Base, WrongToken)
+ DECLARE_EXCEPTION_TYPE(Base, ParserInternalErrorInReadingAttribute)
+ DECLARE_EXCEPTION_TYPE(Base, ParserInternalErrorInEmptyQuery)
+ DECLARE_EXCEPTION_TYPE(Base, ErrorReadingValue)
+ DECLARE_EXCEPTION_TYPE(Base, ErrorReadingName)
+ DECLARE_EXCEPTION_TYPE(Base, UnsupportedType)
+ };
+
+ enum NodeType
+ {
+ NODE_UNSUPPORTED,
+ NODE_BEGIN,
+ NODE_END,
+ NODE_TEXT
+ };
+
+ enum ThrowType
+ {
+ THROW_ENABLE = 0,
+ THROW_DISABLE
+ };
+
+ /*
+ * xml validation modes
+ */
+ enum ValidationType
+ {
+ VALIDATION_DISABLE,
+ VALIDATION_XMLSCHEME,
+ VALIDATION_DTD
+ };
+
+ /*
+ * initializes parser
+ */
+ void initialize(const std::string &filename,
+ bool defaultArgs = false,
+ ValidationType validation = VALIDATION_DISABLE,
+ const std::string &schema = std::string());
+ /*
+ * deinitializes parser
+ */
+ void deinitialize();
+
+ /**
+ * Move to next xml node.
+ */
+ bool next();
+
+ /**
+ * Move to next xml node. If next node name is differ from token the exception will
+ * be thrown.
+ */
+ void next(const std::string &token);
+
+ /**
+ * Check if xml tag is empty.
+ */
+ bool isEmpty(void);
+
+ /**
+ * Read attribute tag.
+ */
+ std::string attribute(const std::string &token,
+ ThrowType throwStatus = THROW_ENABLE);
+
+ /**
+ * Read xml tag name with namespace.
+ */
+ // KW std::string fullName();
+
+ /**
+ * Read xml tag name without namespace.
+ */
+ std::string name();
+
+ /**
+ * Read xml tag namespace URI
+ */
+ std::string namespaceURI();
+
+ /**
+ * Read xml tag value.
+ */
+ std::string value();
+
+ /**
+ * Return information about node type.
+ */
+ NodeType type();
+
+ /**
+ * Save all contonet of xml file which is between current tag and
+ * it's close tag into buffer.
+ */
+ void dumpNode(std::string &buffer);
+
+ private:
+ /*
+ * internal libxml text reader
+ */
+ xmlTextReaderPtr m_reader;
+};
+}
+
+#endif // _SAXREADER_H_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file SignatureData.cpp
+ * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 1.0
+ * @brief SignatureData is used to storage data parsed from digsig file.
+ */
+#ifndef _SIGNATUREDATA_H_
+#define _SIGNATUREDATA_H_
+
+#include <list>
+#include <set>
+#include <string>
+
+#include <dpl/log/log.h>
+#include <dpl/noncopyable.h>
+#include <dpl/string.h>
+
+#include "Certificate.h"
+#include "CertStoreType.h"
+#include "ValidatorCommon.h"
+
+/* TODO this class should not depend from OCSP headers */
+#include "OCSPCertMgrUtil.h"
+
+namespace ValidationCore {
+class SignatureData
+{
+ public:
+
+ SignatureData() :
+ m_signatureNumber(-1),
+ m_certificateSorted(false)
+ {
+ }
+
+ SignatureData(std::string fileName,
+ int fileNumber) :
+ m_signatureNumber(fileNumber),
+ m_fileName(fileName),
+ m_certificateSorted(false)
+ {
+ }
+
+ virtual ~SignatureData()
+ {
+ }
+ typedef std::list<std::string> IMEIList;
+ typedef std::list<std::string> MEIDList;
+
+ const ReferenceSet& getReferenceSet() const
+ {
+ return m_referenceSet;
+ }
+
+ void setReference(const ReferenceSet &referenceSet)
+ {
+ m_referenceSet = referenceSet;
+ }
+
+ CertificateList getCertList(void) const
+ {
+ return m_certList;
+ }
+
+ void setSortedCertificateList(const CertificateList &list)
+ {
+ m_certList = list;
+ m_certificateSorted = true;
+ }
+
+ bool isAuthorSignature(void) const
+ {
+ return m_signatureNumber == -1;
+ }
+
+ std::string getSignatureFileName(void) const
+ {
+ return m_fileName;
+ }
+
+ int getSignatureNumber() const
+ {
+ return m_signatureNumber;
+ }
+
+ std::string getRoleURI() const
+ {
+ return m_roleURI;
+ }
+
+ std::string getProfileURI() const
+ {
+ return m_profileURI;
+ }
+
+ bool containObjectReference(const std::string &ref) const
+ {
+ std::string rName = "#";
+ rName += ref;
+ return m_referenceSet.end() != m_referenceSet.find(rName);
+ }
+
+ ObjectList getObjectList() const
+ {
+ return m_objectList;
+ }
+
+ void setStorageType(const CertStoreId::Set &storeIdSet)
+ {
+ m_storeIdSet = storeIdSet;
+ }
+
+ const CertStoreId::Set& getStorageType(void) const
+ {
+ return m_storeIdSet;
+ }
+
+ const IMEIList& getIMEIList() const
+ {
+ return m_imeiList;
+ }
+
+ const MEIDList& getMEIDList() const
+ {
+ return m_meidList;
+ }
+
+ CertificatePtr getEndEntityCertificatePtr() const
+ {
+ if (m_certificateSorted) {
+ return m_certList.front();
+ }
+ return CertificatePtr();
+ }
+
+ CertificatePtr getRootCaCertificatePtr() const
+ {
+ if (m_certificateSorted) {
+ return m_certList.back();
+ }
+ return CertificatePtr();
+ }
+
+ friend class SignatureReader;
+ private:
+ ReferenceSet m_referenceSet;
+ CertificateList m_certList;
+
+ //TargetRestriction
+ IMEIList m_imeiList;
+ MEIDList m_meidList;
+
+ /*
+ * This number is taken from distributor signature file name.
+ * Author signature do not contain any number on the file name.
+ * Author signature should have signature number equal to -1.
+ */
+ int m_signatureNumber;
+ std::string m_fileName;
+ std::string m_roleURI;
+ std::string m_profileURI;
+ std::string m_identifier;
+ ObjectList m_objectList;
+ CertStoreId::Set m_storeIdSet;
+ bool m_certificateSorted;
+};
+
+typedef std::set<SignatureData> SignatureDataSet;
+}
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file SignatureFinder.cpp
+ * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 1.0
+ * @brief Search for author-signature.xml and signatureN.xml files.
+ */
+#include <dirent.h>
+#include <errno.h>
+#include <istream>
+
+#include <dpl/log/log.h>
+
+#include "SignatureFinder.h"
+
+namespace ValidationCore {
+static const char *SIGNATURE_AUTHOR = "author-signature.xml";
+static const char *REGEXP_DISTRIBUTOR_SIGNATURE =
+ "^(signature)([1-9][0-9]*)(\\.xml)";
+
+SignatureFinder::SignatureFinder(const std::string& dir) :
+ m_dir(dir),
+ m_signatureRegexp(REGEXP_DISTRIBUTOR_SIGNATURE)
+{
+}
+
+SignatureFinder::Result SignatureFinder::find(SignatureFileInfoSet &set)
+{
+ DIR *dp;
+ struct dirent *dirp;
+
+ /*
+ * find a dir
+ */
+ if ((dp = opendir(m_dir.c_str())) == NULL) {
+ LogError("Error opening directory:" << m_dir);
+ return ERROR_OPENING_DIR;
+ }
+
+ for (errno = 0; (dirp = readdir(dp)) != NULL; errno = 0) {
+ /**
+ * check if it's author signature
+ */
+ if (!strcmp(dirp->d_name, SIGNATURE_AUTHOR)) {
+ set.insert(SignatureFileInfo(std::string(dirp->d_name), -1));
+ continue;
+ }
+
+ std::string sig, num, xml;
+ if (m_signatureRegexp.FullMatch(dirp->d_name, &sig, &num, &xml)) {
+ std::istringstream stream(num);
+ int number;
+ stream >> number;
+
+ if (stream.fail()) {
+ closedir(dp);
+ return ERROR_ISTREAM;
+ }
+
+ set.insert(SignatureFileInfo(std::string(dirp->d_name), number));
+ }
+ }
+
+ if (errno != 0) {
+ LogError("Error in readdir");
+ closedir(dp);
+ return ERROR_READING_DIR;
+ }
+
+ closedir(dp);
+ return NO_ERROR;
+}
+} // namespace ValidationCore
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file SignatureFinder.h
+ * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 1.0
+ * @brief Search for author-signature.xml and signatureN.xml files.
+ */
+#ifndef _SIGNATUREFINDER_H_
+#define _SIGNATUREFINDER_H_
+
+#include <set>
+#include <string>
+
+#include <pcrecpp.h>
+
+#include "SignatureData.h"
+
+namespace ValidationCore {
+class SignatureFileInfo
+{
+ public:
+ SignatureFileInfo(const std::string &fileName,
+ int num) :
+ m_fileName(fileName),
+ m_fileNumber(num)
+ {
+ }
+
+ std::string getFileName() const
+ {
+ return m_fileName;
+ }
+
+ int getFileNumber() const
+ {
+ return m_fileNumber;
+ }
+
+ bool operator<(const SignatureFileInfo &second) const
+ {
+ return m_fileNumber < second.m_fileNumber;
+ }
+ private:
+ std::string m_fileName;
+ int m_fileNumber;
+};
+
+typedef std::set<SignatureFileInfo> SignatureFileInfoSet;
+
+class SignatureFinder
+{
+ public:
+ enum Result
+ {
+ NO_ERROR,
+ ERROR_OPENING_DIR,
+ ERROR_READING_DIR,
+ ERROR_ISTREAM
+ };
+
+ SignatureFinder(const std::string& dir);
+
+ Result find(SignatureFileInfoSet &set);
+
+ private:
+ std::string m_dir;
+ pcrecpp::RE m_signatureRegexp;
+};
+} // namespace ValidationCore
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file SignatureReader.cpp
+ * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 1.0
+ * @brief SignatureReader is used to parse widget digital signature.
+ */
+#include "SignatureReader.h"
+
+#include "CertificateLoader.h"
+
+namespace ValidationCore {
+static const std::string XML_NAMESPACE =
+ "http://www.w3.org/2000/09/xmldsig#";
+static const std::string XML_NAMESPACE_DIGITALSIG =
+ "http://wacapps.net/ns/digsig";
+static const std::string XML_OBJ_NS =
+ "http://www.w3.org/2009/xmldsig-properties";
+
+// TAG TOKENS
+static const std::string TOKEN_SIGNATURE = "Signature";
+static const std::string TOKEN_SIGNED_INFO = "SignedInfo";
+static const std::string TOKEN_CANONICALIZATION_METHOD =
+ "CanonicalizationMethod";
+static const std::string TOKEN_SIGNATURE_METHOD = "SignatureMethod";
+static const std::string TOKEN_REFERENCE = "Reference";
+static const std::string TOKEN_TRANSFORMS = "Transforms";
+static const std::string TOKEN_TRANSFORM = "Transform";
+static const std::string TOKEN_DIGEST_METHOD = "DigestMethod";
+static const std::string TOKEN_DIGEST_VALUE = "DigestValue";
+static const std::string TOKEN_SIGNATURE_VALUE = "SignatureValue";
+static const std::string TOKEN_KEY_INFO = "KeyInfo";
+static const std::string TOKEN_X509DATA = "X509Data";
+static const std::string TOKEN_X509CERTIFICATE = "X509Certificate";
+static const std::string TOKEN_KEY_VALUE = "KeyValue";
+static const std::string TOKEN_RSA_KEY_VALUE = "RSAKeyValue";
+static const std::string TOKEN_MODULUS_COMPONENT = "Modulus";
+static const std::string TOKEN_EXPONENT_COMPONENT = "Exponent";
+static const std::string TOKEN_ECKEY_VALUE = "ECKeyValue";
+static const std::string TOKEN_NAMED_CURVE = "NamedCurve";
+static const std::string TOKEN_PUBLIC_KEY = "PublicKey";
+static const std::string TOKEN_OBJECT = "Object";
+static const std::string TOKEN_SIGNATURE_PROPERTIES = "SignatureProperties";
+static const std::string TOKEN_SIGNATURE_PROPERTY = "SignatureProperty";
+static const std::string TOKEN_PROFILE = "Profile";
+static const std::string TOKEN_ROLE = "Role";
+static const std::string TOKEN_IDENTIFIER = "Identifier";
+static const std::string TOKEN_DSAKEYVALUE = "DSAKeyValue";
+static const std::string TOKEN_DSA_P_COMPONENT = "P";
+static const std::string TOKEN_DSA_Q_COMPONENT = "Q";
+static const std::string TOKEN_DSA_G_COMPONENT = "G";
+static const std::string TOKEN_DSA_Y_COMPONENT = "Y";
+static const std::string TOKEN_DSA_J_COMPONENT = "J";
+static const std::string TOKEN_DSA_SEED_COMPONENT = "Seed";
+static const std::string TOKEN_DSA_PGENCOUNTER_COMPONENT = "PgenCounter";
+static const std::string TOKEN_TARGET_RESTRICTION = "TargetRestriction";
+
+// ATTRIBUTTE TOKENS
+
+static const std::string TOKEN_ALGORITHM = "Algorithm";
+static const std::string TOKEN_URI = "URI";
+static const std::string TOKEN_ID = "Id";
+static const std::string TOKEN_TARGET = "Target";
+static const std::string TOKEN_IMEI = "IMEI";
+static const std::string TOKEN_MEID = "MEID";
+
+// ATTIRUBTE VALUES
+
+static const std::string TOKEN_ATTR_PROFILE = "profile";
+static const std::string TOKEN_ATTR_ROLE = "role";
+static const std::string TOKEN_ATTR_IDENTIFIER = "identifier";
+
+// ALGORITHMS
+
+//static const std::string TOKEN_ALGORITHM_XML_EXC_CAN =
+// "http://www.w3.org/2001/10/xml-exc-c14n#";
+//static const std::string TOKEN_ALGORITHM_RSA_SHA256 =
+// "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
+//static const std::string TOKEN_ALGORITHM_DSA_SHA1 =
+// "http://www.w3.org/2000/09/xmldsig#dsa-sha1";
+//static const std::string TOKEN_ALGORITHM_ECDSA_SHA256 =
+// "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256";
+//static const std::string TOKEN_ALGORITHM_SHA1 =
+// "http://www.w3.org/2000/09/xmldsig#sha1";
+//static const std::string TOKEN_ALGORITHM_SHA256 =
+// "http://www.w3.org/2001/04/xmlenc#sha256";
+//static const std::string TOKEN_ALGORITHM_SHA384 =
+// "http://www.w3.org/2001/04/xmldsig-more#sha384";
+//static const std::string TOKEN_ALGORITHM_SHA512 =
+// "http://www.w3.org/2001/04/xmlenc#sha512";
+
+SignatureReader::SignatureReader() :
+ m_signaturePropertiesCounter(0),
+ m_targetRestrictionObjectFound(false),
+ m_parserSchema(this)
+{
+ /**
+ * member func pointers map
+ */
+ m_parserSchema.addBeginTagCallback(TOKEN_SIGNATURE,
+ XML_NAMESPACE,
+ &SignatureReader::blankFunction);
+ m_parserSchema.addBeginTagCallback(TOKEN_SIGNED_INFO,
+ XML_NAMESPACE,
+ &SignatureReader::blankFunction);
+ m_parserSchema.addBeginTagCallback(TOKEN_CANONICALIZATION_METHOD,
+ XML_NAMESPACE,
+ &SignatureReader::blankFunction);
+ m_parserSchema.addBeginTagCallback(TOKEN_SIGNATURE_METHOD,
+ XML_NAMESPACE,
+ &SignatureReader::blankFunction);
+ m_parserSchema.addBeginTagCallback(TOKEN_REFERENCE,
+ XML_NAMESPACE,
+ &SignatureReader::blankFunction);
+ m_parserSchema.addBeginTagCallback(TOKEN_TRANSFORMS,
+ XML_NAMESPACE,
+ &SignatureReader::blankFunction);
+ m_parserSchema.addBeginTagCallback(TOKEN_TRANSFORM,
+ XML_NAMESPACE,
+ &SignatureReader::blankFunction);
+ m_parserSchema.addBeginTagCallback(TOKEN_DIGEST_METHOD,
+ XML_NAMESPACE,
+ &SignatureReader::blankFunction);
+ m_parserSchema.addBeginTagCallback(TOKEN_DIGEST_VALUE,
+ XML_NAMESPACE,
+ &SignatureReader::blankFunction);
+ m_parserSchema.addBeginTagCallback(TOKEN_SIGNATURE_VALUE,
+ XML_NAMESPACE,
+ &SignatureReader::blankFunction);
+ m_parserSchema.addBeginTagCallback(TOKEN_KEY_INFO,
+ XML_NAMESPACE,
+ &SignatureReader::tokenKeyInfo);
+ m_parserSchema.addBeginTagCallback(TOKEN_X509DATA,
+ XML_NAMESPACE,
+ &SignatureReader::tokenX509Data);
+ m_parserSchema.addBeginTagCallback(TOKEN_X509CERTIFICATE,
+ XML_NAMESPACE,
+ &SignatureReader::tokenX509Certificate);
+ m_parserSchema.addBeginTagCallback(TOKEN_ECKEY_VALUE,
+ XML_NAMESPACE,
+ &SignatureReader::blankFunction);
+ m_parserSchema.addBeginTagCallback(TOKEN_NAMED_CURVE,
+ XML_NAMESPACE,
+ &SignatureReader::tokenNamedCurve);
+ m_parserSchema.addBeginTagCallback(TOKEN_PUBLIC_KEY,
+ XML_NAMESPACE,
+ &SignatureReader::tokenPublicKey);
+ m_parserSchema.addBeginTagCallback(TOKEN_OBJECT,
+ XML_NAMESPACE,
+ &SignatureReader::tokenObject);
+ m_parserSchema.addBeginTagCallback(
+ TOKEN_SIGNATURE_PROPERTIES,
+ XML_NAMESPACE,
+ &SignatureReader::
+ tokenSignatureProperties);
+ m_parserSchema.addBeginTagCallback(TOKEN_SIGNATURE_PROPERTY,
+ XML_NAMESPACE,
+ &SignatureReader::blankFunction);
+ m_parserSchema.addBeginTagCallback(TOKEN_PROFILE,
+ XML_OBJ_NS,
+ &SignatureReader::tokenProfile);
+ m_parserSchema.addBeginTagCallback(TOKEN_ROLE,
+ XML_OBJ_NS,
+ &SignatureReader::tokenRole);
+ m_parserSchema.addBeginTagCallback(TOKEN_IDENTIFIER,
+ XML_OBJ_NS,
+ &SignatureReader::blankFunction);
+ m_parserSchema.addBeginTagCallback(TOKEN_KEY_VALUE,
+ XML_NAMESPACE,
+ &SignatureReader::blankFunction);
+ m_parserSchema.addBeginTagCallback(TOKEN_DSAKEYVALUE,
+ XML_NAMESPACE,
+ &SignatureReader::blankFunction);
+ m_parserSchema.addBeginTagCallback(TOKEN_DSA_P_COMPONENT,
+ XML_NAMESPACE,
+ &SignatureReader::blankFunction);
+ m_parserSchema.addBeginTagCallback(TOKEN_DSA_Q_COMPONENT,
+ XML_NAMESPACE,
+ &SignatureReader::blankFunction);
+ m_parserSchema.addBeginTagCallback(TOKEN_DSA_G_COMPONENT,
+ XML_NAMESPACE,
+ &SignatureReader::blankFunction);
+ m_parserSchema.addBeginTagCallback(TOKEN_DSA_Y_COMPONENT,
+ XML_NAMESPACE,
+ &SignatureReader::blankFunction);
+ m_parserSchema.addBeginTagCallback(TOKEN_DSA_J_COMPONENT,
+ XML_NAMESPACE,
+ &SignatureReader::blankFunction);
+ m_parserSchema.addBeginTagCallback(TOKEN_DSA_SEED_COMPONENT,
+ XML_NAMESPACE,
+ &SignatureReader::blankFunction);
+ m_parserSchema.addBeginTagCallback(TOKEN_DSA_PGENCOUNTER_COMPONENT,
+ XML_NAMESPACE,
+ &SignatureReader::blankFunction);
+ m_parserSchema.addBeginTagCallback(TOKEN_RSA_KEY_VALUE,
+ XML_NAMESPACE,
+ &SignatureReader::blankFunction);
+ m_parserSchema.addBeginTagCallback(TOKEN_MODULUS_COMPONENT,
+ XML_NAMESPACE,
+ &SignatureReader::blankFunction);
+ m_parserSchema.addBeginTagCallback(TOKEN_EXPONENT_COMPONENT,
+ XML_NAMESPACE,
+ &SignatureReader::blankFunction);
+ m_parserSchema.addBeginTagCallback(TOKEN_TARGET_RESTRICTION,
+ XML_NAMESPACE_DIGITALSIG,
+ &SignatureReader::tokenTargetRestriction);
+
+ m_parserSchema.addEndTagCallback(TOKEN_SIGNATURE,
+ XML_NAMESPACE,
+ &SignatureReader::blankFunction);
+ m_parserSchema.addEndTagCallback(TOKEN_SIGNED_INFO,
+ XML_NAMESPACE,
+ &SignatureReader::blankFunction);
+ m_parserSchema.addEndTagCallback(TOKEN_CANONICALIZATION_METHOD,
+ XML_NAMESPACE,
+ &SignatureReader::blankFunction);
+ m_parserSchema.addEndTagCallback(TOKEN_SIGNATURE_METHOD,
+ XML_NAMESPACE,
+ &SignatureReader::blankFunction);
+ m_parserSchema.addEndTagCallback(TOKEN_REFERENCE,
+ XML_NAMESPACE,
+ &SignatureReader::blankFunction);
+ m_parserSchema.addEndTagCallback(TOKEN_TRANSFORMS,
+ XML_NAMESPACE,
+ &SignatureReader::blankFunction);
+ m_parserSchema.addEndTagCallback(TOKEN_TRANSFORM,
+ XML_NAMESPACE,
+ &SignatureReader::blankFunction);
+ m_parserSchema.addEndTagCallback(TOKEN_DIGEST_METHOD,
+ XML_NAMESPACE,
+ &SignatureReader::blankFunction);
+ m_parserSchema.addEndTagCallback(TOKEN_DIGEST_VALUE,
+ XML_NAMESPACE,
+ &SignatureReader::blankFunction);
+ m_parserSchema.addEndTagCallback(TOKEN_SIGNATURE_VALUE,
+ XML_NAMESPACE,
+ &SignatureReader::blankFunction);
+ m_parserSchema.addEndTagCallback(TOKEN_KEY_INFO,
+ XML_NAMESPACE,
+ &SignatureReader::tokenEndKeyInfo);
+ m_parserSchema.addEndTagCallback(TOKEN_X509DATA,
+ XML_NAMESPACE,
+ &SignatureReader::tokenEndX509Data);
+ m_parserSchema.addEndTagCallback(TOKEN_X509CERTIFICATE,
+ XML_NAMESPACE,
+ &SignatureReader::tokenEndX509Certificate);
+ m_parserSchema.addEndTagCallback(TOKEN_ECKEY_VALUE,
+ XML_NAMESPACE,
+ &SignatureReader::tokenEndECKeyValue);
+ m_parserSchema.addEndTagCallback(TOKEN_PUBLIC_KEY,
+ XML_NAMESPACE,
+ &SignatureReader::tokenEndPublicKey);
+ m_parserSchema.addEndTagCallback(TOKEN_OBJECT,
+ XML_NAMESPACE,
+ &SignatureReader::tokenEndObject);
+ m_parserSchema.addEndTagCallback(TOKEN_SIGNATURE_PROPERTIES,
+ XML_NAMESPACE,
+ &SignatureReader::blankFunction);
+ m_parserSchema.addEndTagCallback(TOKEN_SIGNATURE_PROPERTY,
+ XML_NAMESPACE,
+ &SignatureReader::blankFunction);
+ m_parserSchema.addEndTagCallback(TOKEN_PROFILE,
+ XML_OBJ_NS,
+ &SignatureReader::blankFunction);
+ m_parserSchema.addEndTagCallback(TOKEN_ROLE,
+ XML_OBJ_NS,
+ &SignatureReader::blankFunction);
+ m_parserSchema.addEndTagCallback(TOKEN_IDENTIFIER,
+ XML_OBJ_NS,
+ &SignatureReader::tokenEndIdentifier);
+ m_parserSchema.addEndTagCallback(TOKEN_KEY_VALUE,
+ XML_NAMESPACE,
+ &SignatureReader::blankFunction);
+ m_parserSchema.addEndTagCallback(TOKEN_DSAKEYVALUE,
+ XML_NAMESPACE,
+ &SignatureReader::tokenEndDSAKeyValue);
+ m_parserSchema.addEndTagCallback(TOKEN_DSA_P_COMPONENT,
+ XML_NAMESPACE,
+ &SignatureReader::tokenEndDSAPComponent);
+ m_parserSchema.addEndTagCallback(TOKEN_DSA_Q_COMPONENT,
+ XML_NAMESPACE,
+ &SignatureReader::tokenEndDSAQComponent);
+ m_parserSchema.addEndTagCallback(TOKEN_DSA_G_COMPONENT,
+ XML_NAMESPACE,
+ &SignatureReader::tokenEndDSAGComponent);
+ m_parserSchema.addEndTagCallback(TOKEN_DSA_Y_COMPONENT,
+ XML_NAMESPACE,
+ &SignatureReader::tokenEndDSAYComponent);
+ m_parserSchema.addEndTagCallback(TOKEN_DSA_J_COMPONENT,
+ XML_NAMESPACE,
+ &SignatureReader::tokenEndDSAJComponent);
+ m_parserSchema.addEndTagCallback(TOKEN_DSA_SEED_COMPONENT,
+ XML_NAMESPACE,
+ &SignatureReader::tokenEndDSASeedComponent);
+ m_parserSchema.addEndTagCallback(
+ TOKEN_DSA_PGENCOUNTER_COMPONENT,
+ XML_NAMESPACE,
+ &SignatureReader::
+ tokenEndDSAPGenCounterComponent);
+ m_parserSchema.addEndTagCallback(TOKEN_RSA_KEY_VALUE,
+ XML_NAMESPACE,
+ &SignatureReader::tokenEndRSAKeyValue);
+ m_parserSchema.addEndTagCallback(TOKEN_MODULUS_COMPONENT,
+ XML_NAMESPACE,
+ &SignatureReader::tokenEndKeyModulus);
+ m_parserSchema.addEndTagCallback(TOKEN_EXPONENT_COMPONENT,
+ XML_NAMESPACE,
+ &SignatureReader::tokenEndKeyExponent);
+ m_parserSchema.addEndTagCallback(TOKEN_TARGET_RESTRICTION,
+ XML_NAMESPACE,
+ &SignatureReader::blankFunction);
+}
+
+void SignatureReader::tokenKeyInfo(SignatureData &signatureData)
+{
+ (void)signatureData;
+}
+void SignatureReader::tokenX509Data(SignatureData &signatureData)
+{
+ (void)signatureData;
+}
+void SignatureReader::tokenX509Certificate(SignatureData &signatureData)
+{
+ (void)signatureData;
+}
+void SignatureReader::tokenPublicKey(SignatureData &signatureData)
+{
+ (void)signatureData;
+}
+
+void SignatureReader::tokenNamedCurve(SignatureData &signatureData)
+{
+ (void)signatureData;
+ m_nameCurveURI = m_parserSchema.getReader().attribute(TOKEN_URI);
+}
+
+void SignatureReader::tokenTargetRestriction(SignatureData &signatureData)
+{
+ std::string IMEI = m_parserSchema.getReader().attribute(
+ TOKEN_IMEI,
+ SaxReader::
+ THROW_DISABLE);
+ std::string MEID = m_parserSchema.getReader().attribute(
+ TOKEN_MEID,
+ SaxReader::
+ THROW_DISABLE);
+
+ //less verbose way to say (IMEI && MEID) || (!IMEI && !MEID)
+ if (IMEI.empty() == MEID.empty()) {
+ //WAC 2.0 WR-4650 point 4
+ ThrowMsg(Exception::TargetRestrictionException,
+ "TargetRestriction should contain exactly one attribute.");
+ return;
+ }
+
+ if (!IMEI.empty()) {
+ signatureData.m_imeiList.push_back(IMEI);
+ }
+ if (!MEID.empty()) {
+ signatureData.m_meidList.push_back(MEID);
+ }
+}
+
+void SignatureReader::tokenEndKeyInfo(SignatureData &signatureData)
+{
+ (void)signatureData;
+}
+
+void SignatureReader::tokenEndX509Data(SignatureData &signatureData)
+{
+ (void)signatureData;
+}
+
+void SignatureReader::tokenEndX509Certificate(SignatureData &signatureData)
+{
+ CertificateLoader loader;
+ if (CertificateLoader::NO_ERROR !=
+ loader.loadCertificateFromRawData(m_parserSchema.getText())) {
+ LogWarning("Certificate could not be loaded!");
+ ThrowMsg(ParserSchemaException::CertificateLoaderError,
+ "Certificate could not be loaded.");
+ }
+ signatureData.m_certList.push_back(loader.getCertificatePtr());
+}
+// KW void SignatureReader::tokenEndKeyName(SignatureData &signatureData){
+// KW CertificateLoader loader;
+// KW if(CertificateLoader::NO_ERROR != loader.loadCertificateBasedOnSubjectName(m_parserSchema.getText())){
+// KW LogError("Certificate could not be loaded!");
+// KW ThrowMsg(ParserSchemaException::CertificateLoaderError, "Certificate could not be loaded.");
+// KW }
+// KW signatureData.m_certList.push_back(loader);
+// KW }
+
+void SignatureReader::tokenEndRSAKeyValue(SignatureData &signatureData)
+{
+ CertificateLoader loader;
+ if (CertificateLoader::NO_ERROR !=
+ loader.loadCertificateBasedOnExponentAndModulus(m_modulus,
+ m_exponent)) {
+ LogWarning("Certificate could not be loaded!");
+ ThrowMsg(ParserSchemaException::CertificateLoaderError,
+ "Certificate could not be loaded.");
+ }
+ signatureData.m_certList.push_back(loader.getCertificatePtr());
+}
+
+void SignatureReader::tokenEndKeyModulus(SignatureData &signatureData)
+{
+ (void)signatureData;
+ m_modulus = m_parserSchema.getText();
+}
+
+void SignatureReader::tokenEndKeyExponent(SignatureData &signatureData)
+{
+ (void)signatureData;
+ m_exponent = m_parserSchema.getText();
+}
+
+void SignatureReader::tokenEndPublicKey(SignatureData &signatureData)
+{
+ (void)signatureData;
+ m_publicKey = m_parserSchema.getText();
+}
+
+void SignatureReader::tokenEndECKeyValue(SignatureData &signatureData)
+{
+ CertificateLoader loader;
+ if (CertificateLoader::NO_ERROR !=
+ loader.loadCertificateWithECKEY(m_nameCurveURI, m_publicKey)) {
+ ThrowMsg(ParserSchemaException::CertificateLoaderError,
+ "Certificate could not be loaded.");
+ }
+ signatureData.m_certList.push_back(loader.getCertificatePtr());
+}
+
+void SignatureReader::tokenEndObject(SignatureData &signatureData)
+{
+ m_signaturePropertiesCounter = 0;
+
+ if (((!signatureData.m_imeiList.empty()) ||
+ (!signatureData.m_meidList.empty())) &&
+ m_targetRestrictionObjectFound) {
+ //WAC 2.0 WR-4650 point 1
+ ThrowMsg(
+ Exception::TargetRestrictionException,
+ "TargetRestriction should contain exactly one ds:Object containing zero or more wac:TargetRestriction children.");
+ return;
+ }
+ if ((!signatureData.m_imeiList.empty()) ||
+ (!signatureData.m_meidList.empty())) {
+ m_targetRestrictionObjectFound = true;
+ }
+}
+void SignatureReader::tokenEndDSAPComponent(SignatureData& signatureData)
+{
+ (void)signatureData;
+ m_dsaKeyPComponent = m_parserSchema.getText();
+}
+
+void SignatureReader::tokenEndDSAQComponent(SignatureData& signatureData)
+{
+ (void)signatureData;
+ m_dsaKeyQComponent = m_parserSchema.getText();
+}
+
+void SignatureReader::tokenEndDSAGComponent(SignatureData& signatureData)
+{
+ (void)signatureData;
+ m_dsaKeyGComponent = m_parserSchema.getText();
+}
+
+void SignatureReader::tokenEndDSAYComponent(SignatureData& signatureData)
+{
+ (void)signatureData;
+ m_dsaKeyYComponent = m_parserSchema.getText();
+}
+
+void SignatureReader::tokenEndDSAJComponent(SignatureData& signatureData)
+{
+ (void)signatureData;
+ m_dsaKeyJComponent = m_parserSchema.getText();
+}
+
+void SignatureReader::tokenEndDSASeedComponent(SignatureData& signatureData)
+{
+ (void)signatureData;
+ m_dsaKeySeedComponent = m_parserSchema.getText();
+}
+
+void SignatureReader::tokenEndDSAPGenCounterComponent(
+ SignatureData& signatureData)
+{
+ (void)signatureData;
+ m_dsaKeyPGenCounter = m_parserSchema.getText();
+}
+
+void SignatureReader::tokenEndDSAKeyValue(SignatureData& signatureData)
+{
+ CertificateLoader loader;
+
+ if (CertificateLoader::NO_ERROR !=
+ loader.loadCertificateBasedOnDSAComponents(m_dsaKeyPComponent,
+ m_dsaKeyQComponent,
+ m_dsaKeyGComponent,
+ m_dsaKeyYComponent,
+ m_dsaKeyJComponent,
+ m_dsaKeySeedComponent,
+ m_dsaKeyPGenCounter)) {
+ LogWarning("Certificate could not be loaded.");
+ ThrowMsg(ParserSchemaException::CertificateLoaderError,
+ "Certificate could not be loaded.");
+ }
+ signatureData.m_certList.push_back(loader.getCertificatePtr());
+}
+
+void SignatureReader::tokenRole(SignatureData &signatureData)
+{
+ if (!signatureData.m_roleURI.empty()) {
+ LogWarning("Multiple definition of Role is not allowed.");
+ ThrowMsg(ParserSchemaException::UnsupportedValue,
+ "Multiple definition of Role is not allowed.");
+ }
+ signatureData.m_roleURI = m_parserSchema.getReader().attribute(TOKEN_URI);
+}
+
+void SignatureReader::tokenProfile(SignatureData &signatureData)
+{
+ if (!signatureData.m_profileURI.empty()) {
+ LogWarning("Multiple definition of Profile is not allowed.");
+ ThrowMsg(ParserSchemaException::UnsupportedValue,
+ "Multiple definition of Profile is not allowed.");
+ }
+ signatureData.m_profileURI = m_parserSchema.getReader().attribute(TOKEN_URI);
+}
+
+void SignatureReader::tokenEndIdentifier(SignatureData &signatureData)
+{
+ if (!signatureData.m_identifier.empty()) {
+ LogWarning("Multiple definition of Identifier is not allowed.");
+ ThrowMsg(ParserSchemaException::UnsupportedValue,
+ "Multiple definition of Identifier is not allowed.");
+ }
+ signatureData.m_identifier = m_parserSchema.getText();
+}
+
+void SignatureReader::tokenObject(SignatureData &signatureData)
+{
+ std::string id = m_parserSchema.getReader().attribute(TOKEN_ID);
+
+ if (id.empty()) {
+ LogWarning("Unsupported value of Attribute Id in Object tag.");
+ ThrowMsg(ParserSchemaException::UnsupportedValue,
+ "Unsupported value of Attribute Id in Object tag.");
+ }
+
+ signatureData.m_objectList.push_back(id);
+}
+
+void SignatureReader::tokenSignatureProperties(SignatureData &signatureData)
+{
+ (void)signatureData;
+ if (++m_signaturePropertiesCounter > 1) {
+ LogWarning("Only one SignatureProperties tag is allowed in Object");
+ ThrowMsg(ParserSchemaException::UnsupportedValue,
+ "Only one SignatureProperties tag is allowed in Object");
+ }
+}
+} // namespace ValidationCore
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file SignatureReader.h
+ * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 1.0
+ * @brief SignatureReader is used to parse widget digital signature.
+ */
+#ifndef _SIGNATUREREADER_H_
+#define _SIGNATUREREADER_H_
+
+#include <map>
+#include <dpl/log/log.h>
+
+#include "SignatureData.h"
+#include "ParserSchema.h"
+
+namespace ValidationCore {
+class SignatureReader
+{
+ public:
+ class Exception
+ {
+ public:
+ DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+ DECLARE_EXCEPTION_TYPE(Base, TargetRestrictionException)
+ };
+
+ SignatureReader();
+
+ void initialize(SignatureData &data,
+ const std::string &xmlscheme)
+ {
+ m_parserSchema.initialize(
+ data.getSignatureFileName(), true, SaxReader::VALIDATION_XMLSCHEME,
+ xmlscheme);
+ }
+
+ void read(SignatureData &data)
+ {
+ m_parserSchema.read(data);
+ }
+
+ private:
+ void blankFunction(SignatureData &)
+ {
+ }
+
+ void tokenKeyInfo(SignatureData &signatureData);
+ void tokenKeyModulus(SignatureData &signatureData);
+ void tokenKeyExponent(SignatureData &signatureData);
+ void tokenX509Data(SignatureData &signatureData);
+ void tokenX509Certificate(SignatureData &signatureData);
+ void tokenPublicKey(SignatureData &signatureData);
+ void tokenNamedCurve(SignatureData &signatureData);
+ void tokenRole(SignatureData &signatureData);
+ void tokenProfile(SignatureData &signatureData);
+ void tokenObject(SignatureData &signatureData);
+ void tokenSignatureProperties(SignatureData &signatureData);
+ void tokenTargetRestriction(SignatureData &signatureData);
+
+ void tokenEndKeyInfo(SignatureData &signatureData);
+ // KW void tokenEndKeyName(SignatureData &signatureData);
+ void tokenEndRSAKeyValue(SignatureData &signatureData);
+ void tokenEndKeyModulus(SignatureData &signatureData);
+ void tokenEndKeyExponent(SignatureData &signatureData);
+ void tokenEndX509Data(SignatureData &signatureData);
+ void tokenEndX509Certificate(SignatureData &signatureData);
+ void tokenEndPublicKey(SignatureData &signatureData);
+ void tokenEndECKeyValue(SignatureData &signatureData);
+ void tokenEndIdentifier(SignatureData &signatureData);
+ void tokenEndObject(SignatureData &signatureData);
+
+ // DSA key components
+ void tokenEndDSAPComponent(SignatureData& signatureData);
+ void tokenEndDSAQComponent(SignatureData& signatureData);
+ void tokenEndDSAGComponent(SignatureData& signatureData);
+ void tokenEndDSAYComponent(SignatureData& signatureData);
+ void tokenEndDSAJComponent(SignatureData& signatureData);
+
+ void tokenEndDSAKeyValue(SignatureData& signatureData);
+
+ void tokenEndDSASeedComponent(SignatureData& signatureData);
+ void tokenEndDSAPGenCounterComponent(SignatureData& signatureData);
+
+ // temporary values required due reference parsing process
+ // optional parameters for dsa
+ std::string m_dsaKeyPComponent;
+ std::string m_dsaKeyQComponent;
+ std::string m_dsaKeyGComponent;
+ std::string m_dsaKeyYComponent;
+ std::string m_dsaKeyJComponent;
+ std::string m_dsaKeySeedComponent;
+ std::string m_dsaKeyPGenCounter;
+ // temporary values of ecdsa key
+ std::string m_publicKey;
+ std::string m_nameCurveURI;
+ std::string m_modulus;
+ std::string m_exponent;
+
+ // temporary values required due Object parsing
+ int m_signaturePropertiesCounter;
+ bool m_targetRestrictionObjectFound;
+
+ ParserSchema<SignatureReader, SignatureData> m_parserSchema;
+};
+}
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <libxml/parser.h>
+#include <libxml/c14n.h>
+#include <openssl/asn1.h>
+
+#include <dpl/log/log.h>
+
+#include "CertificateVerifier.h"
+#include "OCSPCertMgrUtil.h"
+#include "Certificate.h"
+#include "ReferenceValidator.h"
+#include "SignatureValidator.h"
+#include "SSLContainers.h"
+#include "ValidatorCommon.h"
+#include "ValidatorFactories.h"
+#include "XmlsecAdapter.h"
+
+namespace {
+const time_t TIMET_DAY = 60 * 60 * 24;
+
+const std::string TOKEN_ROLE_AUTHOR_URI =
+ "http://www.w3.org/ns/widgets-digsig#role-author";
+const std::string TOKEN_ROLE_DISTRIBUTOR_URI =
+ "http://www.w3.org/ns/widgets-digsig#role-distributor";
+const std::string TOKEN_PROFILE_URI =
+ "http://www.w3.org/ns/widgets-digsig#profile";
+} // namespace anonymouse
+
+namespace ValidationCore {
+
+SignatureValidator::SignatureValidator(bool ocspEnable,
+ bool crlEnable,
+ bool complianceMode) :
+ m_ocspEnable(ocspEnable),
+ m_crlEnable(crlEnable),
+ m_complianceModeEnabled(complianceMode)
+{
+}
+
+SignatureValidator::~SignatureValidator()
+{
+}
+
+bool SignatureValidator::checkRoleURI(const SignatureData &data)
+{
+ std::string roleURI = data.getRoleURI();
+
+ if (roleURI.empty()) {
+ LogWarning("URI attribute in Role tag couldn't be empty.");
+ return false;
+ }
+
+ if (roleURI != TOKEN_ROLE_AUTHOR_URI && data.isAuthorSignature()) {
+ LogWarning("URI attribute in Role tag does not "
+ "match with signature filename.");
+ return false;
+ }
+
+ if (roleURI != TOKEN_ROLE_DISTRIBUTOR_URI && !data.isAuthorSignature()) {
+ LogWarning("URI attribute in Role tag does not "
+ "match with signature filename.");
+ return false;
+ }
+ return true;
+}
+
+bool SignatureValidator::checkProfileURI(const SignatureData &data)
+{
+ if (TOKEN_PROFILE_URI != data.getProfileURI()) {
+ LogWarning(
+ "Profile tag contains unsupported value in URI attribute(" <<
+ data.getProfileURI() << ").");
+ return false;
+ }
+ return true;
+}
+
+bool SignatureValidator::checkObjectReferences(const SignatureData &data)
+{
+ ObjectList objectList = data.getObjectList();
+ ObjectList::const_iterator iter;
+ for (iter = objectList.begin(); iter != objectList.end(); ++iter) {
+ if (!data.containObjectReference(*iter)) {
+ LogWarning("Signature does not contain reference for object " <<
+ *iter);
+ return false;
+ }
+ }
+ return true;
+}
+
+SignatureValidator::Result SignatureValidator::check(
+ SignatureData &data,
+ const std::string &widgetContentPath)
+{
+ bool disregard = false;
+
+ if (!checkRoleURI(data)) {
+ return SIGNATURE_INVALID;
+ }
+
+ if (!checkProfileURI(data)) {
+ return SIGNATURE_INVALID;
+ }
+
+ // CertificateList sortedCertificateList = data.getCertList();
+
+ CertificateCollection collection;
+ collection.load(data.getCertList());
+
+ // First step - sort certificate
+ if (!collection.sort()) {
+ LogWarning("Certificates do not form valid chain.");
+ return SIGNATURE_INVALID;
+ }
+
+ // Check for error
+ if (collection.empty()) {
+ LogWarning("Certificate list in signature is empty.");
+ return SIGNATURE_INVALID;
+ }
+
+ CertificateList sortedCertificateList = collection.getChain();
+
+ // TODO move it to CertificateCollection
+ // Add root CA and CA certificates (if chain is incomplete)
+ sortedCertificateList =
+ OCSPCertMgrUtil::completeCertificateChain(sortedCertificateList);
+
+ CertificatePtr root = sortedCertificateList.back();
+
+ // Is Root CA certificate trusted?
+ CertStoreId::Set storeIdSet = createCertificateIdentifier().find(root);
+
+ // WAC chapter 3.2.1 - verified definition
+ if (data.isAuthorSignature()) {
+ if (!storeIdSet.contains(CertStoreId::WAC_PUBLISHER)) {
+ LogWarning("Author signature has got unrecognized Root CA "
+ "certificate. Signature will be disregarded.");
+ disregard = true;
+ }
+ LogDebug("Root CA for author signature is correct.");
+ } else {
+ if (!storeIdSet.contains(CertStoreId::DEVELOPER) &&
+ !storeIdSet.contains(CertStoreId::WAC_ROOT) &&
+ !storeIdSet.contains(CertStoreId::WAC_MEMBER))
+ {
+ LogWarning("Distiributor signature has got unrecognized Root CA "
+ "certificate. Signature will be disregarded.");
+ disregard = true;
+ }
+ LogDebug("Root CA for distributor signature is correct.");
+ }
+
+ data.setStorageType(storeIdSet);
+ data.setSortedCertificateList(sortedCertificateList);
+
+ // We add only Root CA certificate because WAC ensure that the rest
+ // of certificates are present in signature files ;-)
+ XmlSec::XmlSecContext context;
+ context.signatureFile = data.getSignatureFileName();
+ context.certificatePtr = root;
+
+ // Now we should have full certificate chain.
+ // If the end certificate is not ROOT CA we should disregard signature
+ // but still signature must be valid... Aaaaaa it's so stupid...
+ if (!(root->isSignedBy(root))) {
+ LogWarning("Root CA certificate not found. Chain is incomplete.");
+ context.allowBrokenChain = true;
+ }
+
+ // WAC 2.0 SP-2066 The wrt must not block widget installation
+ // due to expiration of the author certificate.
+ time_t notAfter = data.getEndEntityCertificatePtr()->getNotAfter();
+ bool expired = notAfter < time(NULL);
+ if (data.isAuthorSignature() && expired) {
+ context.validationTime = notAfter - TIMET_DAY;
+ }
+ // end
+
+ if (XmlSec::NO_ERROR != XmlSecSingleton::Instance().validate(&context)) {
+ LogWarning("Installation break - invalid package!");
+ return SIGNATURE_INVALID;
+ }
+
+ data.setReference(context.referenceSet);
+
+ if (!checkObjectReferences(data)) {
+ return SIGNATURE_INVALID;
+ }
+
+ ReferenceValidator fileValidator(widgetContentPath);
+ if (ReferenceValidator::NO_ERROR != fileValidator.checkReferences(data)) {
+ LogWarning("Invalid package - file references broken");
+ return SIGNATURE_INVALID;
+ }
+
+ // It is good time to do OCSP check
+ // ocspCheck will throw an exception on any error.
+ // TODO Probably we should catch this exception and add
+ // some information to SignatureData.
+ if (!m_complianceModeEnabled && !data.isAuthorSignature()) {
+ CertificateCollection coll;
+ coll.load(sortedCertificateList);
+
+ if (!coll.sort()) {
+ LogDebug("Collection does not contain chain!");
+ return SIGNATURE_INVALID;
+ }
+
+ CertificateVerifier verificator(m_ocspEnable, m_crlEnable);
+ VerificationStatus result = verificator.check(coll);
+
+ if (result == VERIFICATION_STATUS_REVOKED) {
+ return SIGNATURE_REVOKED;
+ }
+
+ if (result == VERIFICATION_STATUS_UNKNOWN ||
+ result == VERIFICATION_STATUS_ERROR)
+ {
+ disregard = true;
+ }
+ }
+
+ if (disregard) {
+ LogWarning("Signature is disregard.");
+ return SIGNATURE_DISREGARD;
+ }
+ return SIGNATURE_VERIFIED;
+}
+
+std::string SignatureValidator::FingerprintToColonHex(
+ const Certificate::Fingerprint &fingerprint)
+{
+ std::string outString;
+
+ char buff[8];
+
+ for (size_t i = 0; i < fingerprint.size(); ++i) {
+ snprintf(buff,
+ sizeof(buff),
+ "%02X:",
+ static_cast<unsigned int>(fingerprint[i]));
+ outString += buff;
+ }
+
+ // remove trailing ":"
+ outString.erase(outString.end() - 1);
+ return outString;
+}
+} // namespace ValidationCore
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 _SIGNATUREVALIDATOR_H_
+#define _SIGNATUREVALIDATOR_H_
+
+#include <dpl/singleton.h>
+
+#include "Certificate.h"
+#include "OCSPCertMgrUtil.h"
+#include "SignatureData.h"
+
+#include "ValidatorCommon.h"
+#include "VerificationStatus.h"
+
+namespace ValidationCore {
+// Todo nocopyable
+class SignatureValidator
+{
+ public:
+ enum Result
+ {
+ SIGNATURE_VALID,
+ SIGNATURE_INVALID,
+ SIGNATURE_VERIFIED,
+ SIGNATURE_DISREGARD, // no ocsp response or ocsp return unknown status
+ SIGNATURE_REVOKED
+ };
+
+ /**
+ * Validation of the signature.
+ * If falidation succeed SignatureData will contains:
+ * list of validated references
+ * set selfSigned value
+ * root ca certificate
+ * end entity certificate
+ */
+ Result check(SignatureData &data,
+ const std::string &widgetContentPath);
+
+ static std::string FingerprintToColonHex(
+ const Certificate::Fingerprint &fingerprint);
+
+ explicit SignatureValidator(bool ocspEnable,
+ bool crlEnable,
+ bool complianceMode);
+ virtual ~SignatureValidator();
+
+ private:
+ bool checkRoleURI(const SignatureData &data);
+ bool checkProfileURI(const SignatureData &data);
+ bool checkObjectReferences(const SignatureData &data);
+
+ bool m_ocspEnable;
+ bool m_crlEnable;
+ bool m_complianceModeEnabled;
+};
+
+} // namespace ValidationCore
+
+#endif // _SIGNATUREVALIDATOR_H_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 0.1
+ * @file SoupMessageSendAsync.h
+ * @brief Routines for certificate validation over OCSP
+ */
+#ifndef _SRC_VALIDATION_CORE_SOUP_MESSAGE_SEND_ASYNC_H_
+#define _SRC_VALIDATION_CORE_SOUP_MESSAGE_SEND_ASYNC_H_
+
+#include <map>
+#include <vector>
+
+#include <dpl/assert.h>
+
+#include <dpl/event/inter_context_delegate.h>
+
+#include "SoupMessageSendBase.h"
+
+namespace SoupWrapper {
+
+class SoupMessageSendAsync
+ : public SoupMessageSendBase
+ , public DPL::Event::ICDelegateSupport<SoupMessageSendAsync>
+{
+ typedef DPL::Event::ICDelegate<SoupSession*, SoupMessage*, void*> SoupDelegate;
+ public:
+ void sendAsync() {
+ Assert(m_status == STATUS_IDLE);
+ Assert(!m_soupSession);
+ Assert(!m_soupMessage);
+
+ m_status = STATUS_SEND_ASYNC;
+ m_tryLeft = m_tryCount;
+ m_mainContext = g_main_context_new();
+
+ if (!m_mainContext){
+ m_status = STATUS_IDLE;
+
+ // call the delegate to outside with error!
+ return;
+ }
+
+ m_soupSession = soup_session_async_new_with_options(
+ SOUP_SESSION_ASYNC_CONTEXT,
+ m_mainContext,
+ SOUP_SESSION_TIMEOUT,
+ m_timeout,
+ NULL);
+
+ if (!m_soupSession){
+ m_status = STATUS_IDLE;
+ g_object_unref(m_mainContext);
+ m_mainContext = 0;
+
+ // call the deletage to outside with error!
+ return;
+ }
+
+ m_soupMessage = createRequest();
+
+ if (!m_soupMessage){
+ m_status = STATUS_IDLE;
+ g_object_unref(m_soupSession);
+ m_soupSession = 0;
+ g_object_unref(m_mainContext);
+ m_mainContext = 0;
+
+ // call the delegate to outsize with error!
+ return;
+ }
+
+ sendAsyncIterationStart();
+ }
+
+ protected:
+
+ struct SoupDelegateOpaque {
+ SoupDelegate dlg;
+ };
+
+ void sendAsyncIterationStart(){
+ // ICDelegate could be called only once.
+ // We can set user data only once.
+ // We need nasty hack because we will call ICDelegate m_tryCount times.
+ SoupDelegateOpaque *opaq = new SoupDelegateOpaque;
+ opaq->dlg = makeICDelegate(&SoupMessageSendAsync::requestReceiver);
+
+ soup_session_queue_message(m_soupSession,
+ m_soupMessage,
+ soupSessionCallback,
+ reinterpret_cast<gpointer>(opaq));
+ }
+
+ void sendAsyncIteration(SoupDelegateOpaque *opaq){
+ // Replace used ICDelegate with new one without changing
+ // userdata ;-)
+ opaq->dlg = makeICDelegate(&SoupMessageSendAsync::requestReceiver);
+ soup_session_requeue_message(m_soupSession,
+ m_soupMessage);
+ }
+
+ void requestReceiver(SoupSession *session, SoupMessage *msg, void *opaque){
+ // We are in thread which called sendAsync function.
+ Assert(session == m_soupSession);
+ Assert(msg == m_soupMessage);
+ Assert(opaque != 0);
+ Assert(m_status == STATUS_SEND_ASYNC);
+
+ m_tryLeft--;
+
+ if (msg->status_code == SOUP_STATUS_OK) {
+ m_responseBuffer.resize(msg->response_body->length);
+ memcpy(&m_responseBuffer[0],
+ msg->response_body->data,
+ msg->response_body->length);
+ // We are done.
+ m_status = STATUS_IDLE;
+ delete static_cast<SoupDelegateOpaque*>(opaque);
+
+ // call the delegate to outside!
+ return;
+ }
+
+ // Error protocol //
+ if (m_tryLeft <= 0) {
+ m_status = STATUS_IDLE;
+ delete static_cast<SoupDelegateOpaque*>(opaque);
+
+ // call the delegate to outside with error!
+ return;
+ }
+
+ // create delegate and send the request once again.
+ sendAsyncIteration(reinterpret_cast<SoupDelegateOpaque*>(opaque));
+ }
+
+ static void soupSessionCallback(SoupSession *session,
+ SoupMessage *msg,
+ gpointer userdata)
+ {
+ // We are in main thread. We need to switch context.
+ // This delegate can switch context to dpl thread or main thread.
+ SoupDelegateOpaque *opaque;
+ opaque = reinterpret_cast<SoupDelegateOpaque*>(userdata);
+ opaque->dlg(session, msg, userdata);
+ }
+
+ int m_tryLeft;
+
+ GMainContext *m_mainContext;
+ SoupSession *m_soupSession;
+ SoupMessage *m_soupMessage;
+};
+
+} // namespace ValidationCore
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 0.1
+ * @file SoupMessageSendBase.cpp
+ * @brief Simple wrapper for soup.
+ */
+#include "SoupMessageSendBase.h"
+
+#include <dpl/assert.h>
+#include <dpl/foreach.h>
+#include <dpl/log/log.h>
+
+namespace SoupWrapper {
+
+SoupMessageSendBase::SoupMessageSendBase()
+ : m_status(STATUS_IDLE)
+ , m_timeout(30)
+ , m_tryCount(5)
+{}
+
+SoupMessageSendBase::~SoupMessageSendBase(){
+ Assert(m_status == STATUS_IDLE);
+}
+
+void SoupMessageSendBase::setHeader(const std::string &property, const std::string &value){
+ Assert(m_status == STATUS_IDLE);
+ m_headerMap[property] = value;
+}
+
+void SoupMessageSendBase::setHost(const std::string &host){
+ Assert(m_status == STATUS_IDLE);
+ m_host = host;
+}
+
+void SoupMessageSendBase::setRequest(const std::string &contentType, const MessageBuffer &message){
+ Assert(m_status == STATUS_IDLE);
+ m_requestType = contentType;
+ m_requestBuffer = message;
+}
+
+SoupMessageSendBase::MessageBuffer SoupMessageSendBase::getResponse() const {
+ Assert(m_status == STATUS_IDLE);
+ return m_responseBuffer;
+}
+
+void SoupMessageSendBase::setTimeout(int seconds) {
+ Assert(m_status == STATUS_IDLE);
+ Assert(seconds >= 0);
+ m_timeout = seconds;
+}
+
+void SoupMessageSendBase::setRetry(int retry) {
+ Assert(m_status == STATUS_IDLE);
+ Assert(retry >= 0);
+ m_tryCount = retry + 1;
+}
+
+
+SoupMessage* SoupMessageSendBase::createRequest(){
+ SoupMessage *message;
+
+ LogInfo("Soup message will be send to: " << m_host.c_str());
+
+ if (!m_requestBuffer.empty()) {
+ message = soup_message_new("POST", m_host.c_str());
+ } else {
+ message = soup_message_new("GET", m_host.c_str());
+ }
+
+ if (!message) {
+ LogError("Error creating request!");
+ return 0;
+ }
+
+ FOREACH(it, m_headerMap){
+ soup_message_headers_append(message->request_headers,
+ it->first.c_str(),
+ it->second.c_str());
+ }
+
+ if (!m_requestBuffer.empty()) {
+ soup_message_set_http_version(message, SOUP_HTTP_1_0);
+ soup_message_set_request(message,
+ m_requestType.c_str(),
+ SOUP_MEMORY_COPY,
+ &m_requestBuffer[0],
+ m_requestBuffer.size());
+ }
+ soup_message_set_flags(message, SOUP_MESSAGE_NO_REDIRECT);
+ return message;
+}
+
+} // namespace ValidationCore
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 0.1
+ * @file SoupMessageSendBase.h
+ * @brief Simple wrapper for soup.
+ */
+#ifndef _SRC_VALIDATION_CORE_SOUP_MESSAGE_SEND_BASE_H_
+#define _SRC_VALIDATION_CORE_SOUP_MESSAGE_SEND_BASE_H_
+
+#include <map>
+#include <vector>
+#include <string>
+
+#include <libsoup/soup.h>
+
+namespace SoupWrapper {
+
+class SoupMessageSendBase {
+ public:
+
+ typedef std::vector<char> MessageBuffer;
+ typedef std::map<std::string,std::string> HeaderMap;
+
+ enum RequestStatus {
+ REQUEST_STATUS_OK,
+ REQUEST_STATUS_CONNECTION_ERROR
+ };
+
+ SoupMessageSendBase();
+
+ virtual ~SoupMessageSendBase();
+
+ /**
+ * Add specific information to request header.
+ *
+ * @param[in] property property name (for example "Host")
+ * @param[in] value property value (for example "onet.pl:80")
+ */
+ void setHeader(const std::string &property,
+ const std::string &value);
+
+ /**
+ * Set request destination.
+ *
+ * @param[in] host - full path to source (http://onet.pl/index.html)
+ */
+ void setHost(const std::string &host);
+
+ /**
+ * Set body of request.
+ *
+ * @param[in] contentType (for example: "application/ocsp-request")
+ * @param[in] message body of reqeust
+ */
+ void setRequest(const std::string &contentType,
+ const MessageBuffer &message);
+
+ /**
+ * Set network timeout. Default is 30 seconds.
+ *
+ * @param[in] seconds timeout in seconds
+ */
+ void setTimeout(int seconds);
+
+ /**
+ * How many erros soup will accept before he will terminate connection.
+ * Default is 5.
+ *
+ * @param[in] retry number
+ */
+ void setRetry(int retry);
+
+ /**
+ * Get response from serwer.
+ */
+ MessageBuffer getResponse() const;
+
+ protected:
+
+ SoupMessage* createRequest();
+
+ enum Status {
+ STATUS_IDLE,
+ STATUS_SEND_SYNC,
+ STATUS_SEND_ASYNC
+ };
+
+ Status m_status;
+
+ int m_timeout;
+ int m_tryCount;
+
+ std::string m_host;
+ std::string m_requestType;
+ MessageBuffer m_requestBuffer;
+ MessageBuffer m_responseBuffer;
+ HeaderMap m_headerMap;
+};
+
+} // namespace ValidationCore
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 0.1
+ * @file SoupMessageSendSync.cpp
+ * @brief Implementation of soup synchronous interface.
+ */
+#include "SoupMessageSendSync.h"
+
+#include <memory>
+#include <functional>
+
+#include <vconf.h>
+
+#include <dpl/log/log.h>
+
+namespace SoupWrapper {
+
+SoupMessageSendBase::RequestStatus SoupMessageSendSync::sendSync()
+{
+ Assert(m_status == STATUS_IDLE);
+ m_status = STATUS_SEND_SYNC;
+
+ ScopedGMainContext context(g_main_context_new());
+
+ std::unique_ptr<char,std::function<void(void*)> >
+ proxy(vconf_get_str(VCONFKEY_NETWORK_PROXY), free);
+
+ std::unique_ptr <SoupURI, std::function<void(SoupURI*)> >
+ proxyURI(soup_uri_new (proxy.get()), soup_uri_free);
+
+ LogDebug("Proxy ptr:" << (void*)proxy.get() <<
+ " Proxy addr: " << proxy.get());
+
+ for(int tryCount = 0; tryCount < m_tryCount; ++ tryCount){
+ LogDebug("Try(" << tryCount << ") to download " << m_host);
+
+ ScopedSoupSession session(soup_session_async_new_with_options(
+ SOUP_SESSION_ASYNC_CONTEXT,
+ &*context,
+ SOUP_SESSION_TIMEOUT,
+ m_timeout,
+ SOUP_SESSION_PROXY_URI,
+ proxyURI.get(),
+ NULL));
+
+ ScopedSoupMessage msg;
+
+ msg.Reset(createRequest());
+
+ if (!msg) {
+ LogError("Unable to send HTTP request.");
+ m_status = STATUS_IDLE;
+ return REQUEST_STATUS_CONNECTION_ERROR;
+ }
+ soup_session_send_message(&*session, &*msg);
+
+ // if (SOUP_STATUS_IS_SUCCESSFUL(msg->status_code))
+
+ if (msg->status_code == SOUP_STATUS_OK) {
+ m_responseBuffer.resize(msg->response_body->length);
+ memcpy(&m_responseBuffer[0],
+ msg->response_body->data,
+ msg->response_body->length);
+ // We are done.
+ m_status = STATUS_IDLE;
+ return REQUEST_STATUS_OK;
+ } else {
+ LogWarning("Soup failed with code " << msg->status_code
+ << " message \n------------\n"
+ << msg->response_body->data
+ << "\n--------------\n");
+ }
+ }
+
+ m_status = STATUS_IDLE;
+ return REQUEST_STATUS_CONNECTION_ERROR;
+}
+
+} // namespave ValidationCore
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 0.1
+ * @file SoupMessageSendSync.h
+ * @brief Wrapper for soup synchronous interface.
+ */
+#ifndef _SRC_VALIDATION_CORE_SOUP_MESSAGE_SEND_SYNC_H_
+#define _SRC_VALIDATION_CORE_SOUP_MESSAGE_SEND_SYNC_H_
+
+#include "SoupMessageSendBase.h"
+
+#include <vcore/scoped_gpointer.h>
+
+namespace SoupWrapper {
+
+class SoupMessageSendSync : public SoupMessageSendBase {
+ public:
+ RequestStatus sendSync();
+ protected:
+ typedef WRT::ScopedGPointer<SoupMessage> ScopedSoupMessage;
+ typedef WRT::ScopedGPointer<SoupSession> ScopedSoupSession;
+ typedef WRT::ScopedGPointer<GMainContext> ScopedGMainContext;
+};
+
+} // namespace ValidationCore
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file VCore.cpp
+ * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @brief
+ */
+
+#include <vcore/VCorePrivate.h>
+#include <vcore/Config.h>
+#include <vcore/Database.h>
+#include <openssl/ssl.h>
+#include <database_checksum_vcore.h>
+#include <glib.h>
+#include <glib-object.h>
+
+namespace {
+DPL::DB::ThreadDatabaseSupport threadInterface(
+ VCoreDatabaseConnectionTraits::Address(),
+ VCoreDatabaseConnectionTraits::Flags());
+} // namespace anonymous
+
+namespace ValidationCore {
+
+void AttachToThread(void){
+ threadInterface.AttachToThread();
+}
+
+void DetachFromThread(void){
+ threadInterface.DetachFromThread();
+}
+
+DPL::DB::ThreadDatabaseSupport& ThreadInterface(void) {
+ return threadInterface;
+}
+
+bool VCoreInit(const std::string& configFilePath,
+ const std::string& configSchemaPath,
+ const std::string& databasePath)
+{
+ SSL_library_init();
+ g_thread_init(NULL);
+ g_type_init();
+
+ LogDebug("Initializing VCore");
+ Config &globalConfig = ConfigSingleton::Instance();
+ bool returnValue = globalConfig.setXMLConfigPath(configFilePath) &&
+ globalConfig.setXMLSchemaPath(configSchemaPath) &&
+ globalConfig.setDatabasePath(databasePath);
+
+ Assert(ThreadInterface().CheckTableExist(DB_CHECKSUM_STR) &&
+ "Not a valid vcore database version");
+
+ return returnValue;
+}
+
+} // namespace ValidationCore
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file VCore.h
+ * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 1.0
+ * @brief
+ */
+#ifndef _VCORE_SRC_VCORE_VCORE_H_
+#define _VCORE_SRC_VCORE_VCORE_H_
+
+#include <string>
+
+namespace ValidationCore {
+/*
+ * configFilePath - path to XML config file with certificates configuration
+ *
+ * configSchemaPath - XMLschema of config file
+ *
+ * databasePath - path to database with OCSP/CRL cache.
+ *
+ * This function could be run only once. If you call it twice it will
+ * return false and non data will be set.
+ *
+ */
+bool VCoreInit(const std::string& configFilePath,
+ const std::string& configSchemaPath,
+ const std::string& databasePath);
+
+/*
+ * All thread with are using OCSP/CRL must call AttachToThread function before
+ * it can call OCSP/CRL. More than one thread could be Attach with OCPS/CRL.
+ *
+ * You mast attach thread to OCSP/CRL because OCSP/CRL is using database
+ * CertificateCachedDAO. For each thread that will be using this database
+ * vcore must create internal structure (with connection info).
+ *
+ */
+void AttachToThread(void);
+void DetachFromThread(void);
+
+} // namespace ValidationCore
+
+#endif // _VCORE_SRC_VCORE_VCORE_H_
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file VCore.h
+ * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 1.0
+ * @brief
+ */
+#ifndef _VCORE_SRC_VCORE_VCOREPRIVATE_H_
+#define _VCORE_SRC_VCORE_VCOREPRIVATE_H_
+
+#include <string>
+#include <VCore.h>
+#include <database_checksum_vcore.h>
+#include <dpl/db/thread_database_support.h>
+
+namespace ValidationCore {
+DPL::DB::ThreadDatabaseSupport& ThreadInterface(void);
+} // namespace ValidationCore
+
+#endif // _VCORE_SRC_VCORE_VCORE_H_
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file ValidatorCommon.h
+ * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 1.0
+ * @brief This file contais definictions of common types used in ValidationCore.
+ */
+#ifndef _VALIDATORCOMMON_H_
+#define _VALIDATORCOMMON_H_
+
+#include <list>
+#include <set>
+#include <string>
+
+namespace ValidationCore {
+typedef std::set< std::string > ReferenceSet;
+typedef std::list< std::string > ObjectList;
+
+/*
+ * base deleter func
+ */
+template <typename T>
+struct ValidatorCoreUniversalFree {};
+
+// Template Specialization
+#define VC_DECLARE_DELETER(type, function) \
+ template <> \
+ struct ValidatorCoreUniversalFree <type> { \
+ void universal_free(type *ptr){ \
+ if (ptr) { \
+ function(ptr); } \
+ } \
+ };
+
+template <typename T>
+class AutoPtr
+{
+ public:
+ AutoPtr(T *ptr) :
+ m_data(ptr)
+ {
+ }
+
+ AutoPtr(const AutoPtr<T> &second)
+ {
+ m_data = second.m_data;
+ second.m_data = 0;
+ }
+
+ AutoPtr & operator=(const AutoPtr &second)
+ {
+ if (this != &second) {
+ ValidatorCoreUniversalFree<T> deleter;
+ deleter.universal_free(m_data);
+ m_data = second.m_data;
+ second.m_data = 0;
+ }
+ return *this;
+ }
+
+ /**
+ * overloaded -> operator, so smart ptr could act as ordinary ptr
+ */
+ T* operator->()
+ {
+ return m_data;
+ }
+
+ ~AutoPtr()
+ {
+ ValidatorCoreUniversalFree<T> deleter;
+ deleter.universal_free(m_data);
+ }
+
+ /**
+ * get internal pointer
+ */
+ T* get(void)
+ {
+ return m_data;
+ }
+
+ private:
+ mutable T *m_data;
+};
+} // namespace ValidationCore
+
+#endif // _VALIDATORCOMMON_H_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file
+ * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 1.0
+ * @brief
+ */
+#include <vcore/ValidatorFactories.h>
+
+#include <string>
+
+#include <vcore/Certificate.h>
+#include <vcore/CertificateConfigReader.h>
+#include <vcore/Config.h>
+
+namespace ValidationCore {
+
+const CertificateIdentifier& createCertificateIdentifier()
+{
+ static CertificateIdentifier certificateIdentifier;
+ static bool initialized = false;
+ if (!initialized) {
+ CertificateConfigReader reader;
+ std::string file =
+ ConfigSingleton::Instance().getXMLConfigPath();
+ std::string schema =
+ ConfigSingleton::Instance().getXMLSchemaPath();
+ reader.initialize(file, schema);
+ reader.read(certificateIdentifier);
+ initialized = true;
+ }
+ return certificateIdentifier;
+}
+
+} // namespace ValidationCore
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file
+ * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 1.0
+ * @brief
+ */
+#ifndef _WRT_ENGINE_SRC_INSTALLER_CORE_VALIDATION_CORE_VALIDATORFACTORY_H_
+#define _WRT_ENGINE_SRC_INSTALLER_CORE_VALIDATION_CORE_VALIDATORFACTORY_H_
+
+#include <CertificateIdentifier.h>
+
+namespace ValidationCore {
+// First use of CertificateIdentificator should initialized it.
+// We do not want to create cyclic dependencies between
+// CertificateConfigReader and CertificateIdentificator so
+// we are using factory method to create CertificateIdentificator.
+
+const CertificateIdentifier& createCertificateIdentifier();
+} // namespace ValidationCore
+
+#endif // _WRT_ENGINE_SRC_INSTALLER_CORE_VALIDATION_CORE_VALIDATORFACTORY_H_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "VerificationStatus.h"
+
+namespace ValidationCore {
+VerificationStatus VerificationStatusSet::convertToStatus() const
+{
+ if (m_verdictMap & VERIFICATION_STATUS_REVOKED) {
+ return VERIFICATION_STATUS_REVOKED;
+ }
+
+ if (m_verdictMap & VERIFICATION_STATUS_VERIFICATION_ERROR) {
+ return VERIFICATION_STATUS_VERIFICATION_ERROR;
+ }
+
+ if (m_verdictMap & VERIFICATION_STATUS_ERROR) {
+ return VERIFICATION_STATUS_ERROR;
+ }
+
+ if (m_verdictMap & VERIFICATION_STATUS_UNKNOWN) {
+ return VERIFICATION_STATUS_UNKNOWN;
+ }
+
+ if (m_verdictMap & VERIFICATION_STATUS_CONNECTION_FAILED) {
+ return VERIFICATION_STATUS_CONNECTION_FAILED;
+ }
+
+ if (m_verdictMap & VERIFICATION_STATUS_NOT_SUPPORT) {
+ return VERIFICATION_STATUS_NOT_SUPPORT;
+ }
+
+ if (m_verdictMap & VERIFICATION_STATUS_GOOD) {
+ return VERIFICATION_STATUS_GOOD;
+ }
+
+ return VERIFICATION_STATUS_ERROR;
+}
+} // namespace ValidationCore
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 _SRC_VALIDATION_CORE_VERIFICATION_STATUS_H_
+#define _SRC_VALIDATION_CORE_VERIFICATION_STATUS_H_
+
+namespace ValidationCore {
+enum VerificationStatus
+{
+ //! The certificate has not been revoked.
+ /*! Connection to OCSP responder was successful and the certificate
+ * has not been revoked.
+ */
+ VERIFICATION_STATUS_GOOD = 1,
+
+ //! The certificate has been revoked.
+ /*! Connection to OCSP responder was successful and the certificate
+ * has been revoked.
+ * RFC2560: "The "revoked" state indicates that the certificate has
+ * been revoked (either permanantly or temporarily
+ * (on hold))."
+ */
+ VERIFICATION_STATUS_REVOKED = 1 << 1,
+
+ //! The certificate status is unknown.
+ /*! Connection to OCSP responder was successful and the certificate
+ * has unknown status.
+ *
+ * RFC2560: "The "unknown" state indicates that the responder
+ * doesn't know about the certificate being requested."
+ */
+ VERIFICATION_STATUS_UNKNOWN = 1 << 2,
+
+ //! The certificate status was not figure out.
+ /*! The response from ocsp/crl server contains broken signature. */
+ VERIFICATION_STATUS_VERIFICATION_ERROR = 1 << 3,
+
+ //! The certificate status was not figure out.
+ /*! The certificate does not contain ocsp/crl extension. */
+ VERIFICATION_STATUS_NOT_SUPPORT = 1 << 4,
+
+ //! The certificate status was not figure out.
+ /*! The CertMgr could not connect to OCSP responder. */
+ VERIFICATION_STATUS_CONNECTION_FAILED = 1 << 5,
+
+ //! The certificate status is unknown due to internal error inside OCSP
+ VERIFICATION_STATUS_ERROR = 1 << 6
+};
+
+class VerificationStatusSet
+{
+ public:
+ VerificationStatusSet() : m_verdictMap(0)
+ {
+ }
+
+ inline void add(VerificationStatus status)
+ {
+ m_verdictMap |= status;
+ }
+
+ inline bool contains(VerificationStatus status) const
+ {
+ return m_verdictMap & status;
+ }
+
+ inline bool isEmpty() const
+ {
+ return 0 == m_verdictMap;
+ }
+
+ inline void operator+=(const VerificationStatusSet &second)
+ {
+ m_verdictMap |= second.m_verdictMap;
+ }
+
+ inline void reset()
+ {
+ m_verdictMap = 0;
+ }
+
+ VerificationStatus convertToStatus() const;
+
+ private:
+ unsigned int m_verdictMap;
+};
+
+/* TODO this status should be defined in wrt-engine sources */
+enum WidgetVerificationStatus
+{
+ // All certificate has been veficated and all certificates are good.
+ // Widget is able to be installed.
+ WIDGET_VERIFICATION_STATUS_GOOD,
+ // Some certificate has been revoked. Widget is not able to be installed.
+ WIDGET_VERIFICATION_STATUS_REVOKED,
+};
+} // namespace ValidationCore
+
+#endif // _SRC_VALIDATION_CORE_VERIFICATION_STATUS_H_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file
+ * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 1.0
+ * @brief
+ */
+#include "WacOrigin.h"
+
+#include <algorithm>
+#include <ctype.h>
+#include <idna.h>
+
+#include <<dpl/log/log.h>>
+
+#include <iri.h>
+#include "ValidatorCommon.h"
+
+namespace {
+const std::string SCHEME_HTTP = "http";
+const std::string SCHEME_HTTPS = "https";
+const int PORT_HTTP = 80;
+const int PORT_HTTPS = 443;
+}
+
+namespace ValidationCore {
+VC_DECLARE_DELETER(iri_struct, iri_destroy)
+
+WacOrigin::WacOrigin(const std::string &url) :
+ m_port(0),
+ m_parseFailed(false)
+{
+ parse(url.c_str());
+}
+
+WacOrigin::WacOrigin(const char *url) :
+ m_port(0),
+ m_parseFailed(false)
+{
+ parse(url);
+}
+
+bool WacOrigin::operator==(const WacOrigin &second) const
+{
+ if (m_parseFailed || second.m_parseFailed) {
+ return false;
+ }
+
+ return (m_scheme == second.m_scheme) &&
+ (m_host == second.m_host) &&
+ (m_port == second.m_port);
+}
+
+void WacOrigin::parse(const char *url)
+{
+ // Step are taken from algorihtm:
+ // http://www.w3.org/TR/html5/origin-0.html#origin-0
+
+ // Step 1
+ // Step 2
+ AutoPtr<iri_struct> iri(iri_parse(url));
+ if (!iri.get()) {
+ m_parseFailed = true;
+ return;
+ }
+
+ if (iri->scheme) {
+ m_scheme = iri->scheme;
+ } else {
+ m_parseFailed = true;
+ return;
+ }
+
+ // Step 3 - Skip this point.
+ // WAC 2.0 PRV - we are suport only "http" and "https" schemas.
+
+ // Step 4 - Todo
+
+ // Step 5
+ std::transform(m_scheme.begin(), m_scheme.end(), m_scheme.begin(), tolower);
+
+ // Step 6 - we only support "http" and "https" schemas
+ if ((m_scheme != SCHEME_HTTP) && (m_scheme != SCHEME_HTTPS)) {
+ m_parseFailed = true;
+ return;
+ }
+
+ // Step 7 - Skip. We do not support "file" schema.
+
+ // Step 8
+ if (iri->host) {
+ m_host = iri->host;
+ } else {
+ m_parseFailed = true;
+ return;
+ }
+
+ // Step 9
+ char *output = NULL;
+ if (IDNA_SUCCESS !=
+ idna_to_ascii_lz(m_host.c_str(), &output, IDNA_USE_STD3_ASCII_RULES)) {
+ LogError("libidn error");
+ m_parseFailed = true;
+ free(output);
+ return;
+ }
+ m_host = output;
+ free(output);
+
+ // Step 10
+ std::transform(m_host.begin(), m_host.end(), m_host.begin(), ::tolower);
+
+ // Step 11
+ if (iri->port) {
+ m_port = iri->port;
+ } else {
+ setPort();
+ }
+
+ // Step 12 - Skip it. We do not return anything.
+ // User should create geters if he need access to schema/host/port.
+}
+
+void WacOrigin::setPort()
+{
+ if (SCHEME_HTTP == m_scheme) {
+ m_port = PORT_HTTP;
+ return;
+ } else if (SCHEME_HTTPS == m_scheme) {
+ m_port = PORT_HTTPS;
+ return;
+ } else {
+ LogDebug("Scheme " << m_scheme << " is not support by WAC2.0");
+ m_parseFailed = true;
+ }
+}
+} // namespace ValidationCore
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file
+ * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 1.0
+ * @brief This is stub for HTML5Origin implementation.
+ * This implementation is compatible with WAC 2.0 PRV requirements
+ * and is _not_ full compatible with ORIGIN algorithm requirements
+ * defined in http://www.w3.org/TR/html5/origin-0.html#origin-0
+ */
+#ifndef _WRT_ENGINE_SRC_INSTALLER_CORE_VALIDATION_CORE_HTML5ORIGIN_H_
+#define _WRT_ENGINE_SRC_INSTALLER_CORE_VALIDATION_CORE_HTML5ORIGIN_H_
+
+#include <string>
+
+namespace ValidationCore {
+class WacOrigin
+{
+ public:
+
+ WacOrigin(const std::string &url);
+ WacOrigin(const char *url);
+
+ bool operator!=(const WacOrigin &second) const
+ {
+ return !(operator==(second));
+ }
+
+ bool operator==(const WacOrigin &second) const;
+
+ private:
+ void parse(const char *url);
+ void setPort();
+
+ std::string m_scheme;
+ std::string m_host;
+ int m_port;
+ bool m_parseFailed; // if parsing failed we should return unique identifier
+};
+} //namespace ValidationCore
+
+#endif // _WRT_ENGINE_SRC_INSTALLER_CORE_VALIDATION_CORE_HTML5ORIGIN_H_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file XmlsecAdapter.cpp
+ * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 1.0
+ * @brief
+ */
+
+/*
+ * Copyright (C) 2002-2003 Aleksey Sanin. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include <cstdlib>
+#include <cstring>
+
+#include <libxml/tree.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/parser.h>
+
+#ifndef XMLSEC_NO_XSLT
+#include <libxslt/xslt.h>
+#endif /* XMLSEC_NO_XSLT */
+
+#include <xmlsec/xmlsec.h>
+#include <xmlsec/xmltree.h>
+#include <xmlsec/xmldsig.h>
+#include <xmlsec/crypto.h>
+#include <xmlsec/io.h>
+#include <xmlsec/keyinfo.h>
+
+#include <dpl/assert.h>
+#include <dpl/log/log.h>
+
+#include "XmlsecAdapter.h"
+#include <dpl/singleton_impl.h>
+IMPLEMENT_SINGLETON(ValidationCore::XmlSec)
+
+namespace ValidationCore {
+VC_DECLARE_DELETER(xmlSecKeysMngr, xmlSecKeysMngrDestroy)
+
+static const char* DIGEST_MD5 = "md5";
+
+std::string XmlSec::s_prefixPath;
+
+int XmlSec::fileMatchCallback(const char *filename)
+{
+ std::string path = s_prefixPath + filename;
+ return xmlFileMatch(path.c_str());
+}
+
+void* XmlSec::fileOpenCallback(const char *filename)
+{
+ std::string path = s_prefixPath + filename;
+ LogDebug("Xmlsec opening: " << path);
+ return xmlFileOpen(path.c_str());
+}
+
+int XmlSec::fileReadCallback(void *context,
+ char *buffer,
+ int len)
+{
+ return xmlFileRead(context, buffer, len);
+}
+
+int XmlSec::fileCloseCallback(void *context)
+{
+ return xmlFileClose(context);
+}
+
+void XmlSec::fileExtractPrefix(XmlSecContext *context)
+{
+ if (!(context->workingDirectory.empty())) {
+ s_prefixPath = context->workingDirectory;
+ return;
+ }
+
+ s_prefixPath = context->signatureFile;
+ size_t pos = s_prefixPath.rfind('/');
+ if (pos == std::string::npos) {
+ s_prefixPath.clear();
+ } else {
+ s_prefixPath.erase(pos + 1, std::string::npos);
+ }
+}
+
+XmlSec::XmlSec() :
+ m_initialized(false)
+{
+ LIBXML_TEST_VERSION
+ xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
+ xmlSubstituteEntitiesDefault(1);
+#ifndef XMLSEC_NO_XSLT
+ xmlIndentTreeOutput = 1;
+#endif
+
+ if (xmlSecInit() < 0) {
+ LogError("Xmlsec initialization failed.");
+ ThrowMsg(Exception::InternalError, "Xmlsec initialization failed.");
+ }
+
+ if (xmlSecCheckVersion() != 1) {
+ xmlSecShutdown();
+ LogError("Loaded xmlsec library version is not compatible.");
+ ThrowMsg(Exception::InternalError,
+ "Loaded xmlsec library version is not compatible.");
+ }
+
+#ifdef XMLSEC_CRYPTO_DYNAMIC_LOADING
+ if (xmlSecCryptoDLLoadLibrary(BAD_CAST XMLSEC_CRYPTO) < 0) {
+ xmlSecShutdown();
+ LogError(
+ "Error: unable to load default xmlsec-crypto library. Make sure "
+ "that you have it installed and check shared libraries path "
+ "(LD_LIBRARY_PATH) envornment variable.");
+ ThrowMsg(Exception::InternalError,
+ "Unable to load default xmlsec-crypto library.");
+ }
+#endif
+
+ if (xmlSecCryptoAppInit(NULL) < 0) {
+ xmlSecShutdown();
+ LogError("Crypto initialization failed.");
+ ThrowMsg(Exception::InternalError, "Crypto initialization failed.");
+ }
+
+ if (xmlSecCryptoInit() < 0) {
+ xmlSecCryptoAppShutdown();
+ xmlSecShutdown();
+ LogError("Xmlsec-crypto initialization failed.");
+ ThrowMsg(Exception::InternalError,
+ "Xmlsec-crypto initialization failed.");
+ }
+
+ m_initialized = true;
+}
+
+void XmlSec::deinitialize(void)
+{
+ Assert(m_initialized);
+
+ /* Shutdown xmlsec-crypto library */
+ xmlSecCryptoShutdown();
+
+ /* Shutdown crypto library */
+ xmlSecCryptoAppShutdown();
+
+ /* Shutdown xmlsec library */
+ xmlSecShutdown();
+
+ /* Shutdown libxslt/libxml */
+#ifndef XMLSEC_NO_XSLT
+ xsltCleanupGlobals();
+#endif /* XMLSEC_NO_XSLT */
+
+ s_prefixPath.clear();
+ m_initialized = false;
+}
+
+XmlSec::~XmlSec()
+{
+ if (m_initialized) {
+ deinitialize();
+ }
+}
+
+XmlSec::Result XmlSec::validateFile(XmlSecContext *context,
+ xmlSecKeysMngrPtr mngr)
+{
+ xmlDocPtr doc = NULL;
+ xmlNodePtr node = NULL;
+ xmlSecDSigCtxPtr dsigCtx = NULL;
+ int size, res = -1;
+
+ fileExtractPrefix(context);
+ LogDebug("Prefix path: " << s_prefixPath);
+
+ xmlSecIOCleanupCallbacks();
+
+ xmlSecIORegisterCallbacks(
+ fileMatchCallback,
+ fileOpenCallback,
+ fileReadCallback,
+ fileCloseCallback);
+
+ /* load file */
+ doc = xmlParseFile(context->signatureFile.c_str());
+ if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL)) {
+ LogWarning("Unable to parse file " << context->signatureFile);
+ goto done;
+ }
+
+ /* find start node */
+ node = xmlSecFindNode(xmlDocGetRootElement(
+ doc), xmlSecNodeSignature, xmlSecDSigNs);
+ if (node == NULL) {
+ LogWarning("Start node not found in " << context->signatureFile);
+ goto done;
+ }
+
+ /* create signature context */
+ dsigCtx = xmlSecDSigCtxCreate(mngr);
+ if (dsigCtx == NULL) {
+ LogError("Failed to create signature context.");
+ goto done;
+ }
+
+ if (context->allowBrokenChain) {
+ dsigCtx->keyInfoReadCtx.flags |=
+ XMLSEC_KEYINFO_FLAGS_ALLOW_BROKEN_CHAIN;
+ }
+
+ if (context->validationTime) {
+ LogDebug("Setting validation time.");
+ dsigCtx->keyInfoReadCtx.certsVerificationTime = context->validationTime;
+ }
+
+ /* Verify signature */
+ if (xmlSecDSigCtxVerify(dsigCtx, node) < 0) {
+ LogWarning("Signature verify error.");
+ goto done;
+ }
+
+ if (dsigCtx->keyInfoReadCtx.flags2 &
+ XMLSEC_KEYINFO_ERROR_FLAGS_BROKEN_CHAIN) {
+ LogWarning("XMLSEC_KEYINFO_FLAGS_ALLOW_BROKEN_CHAIN was set to true!");
+ LogWarning("Signature contains broken chain!");
+ context->errorBrokenChain = true;
+ }
+
+ /* print verification result to stdout */
+ if (dsigCtx->status == xmlSecDSigStatusSucceeded) {
+ LogDebug("Signature is OK");
+ res = 0;
+ } else {
+ LogDebug("Signature is INVALID");
+ goto done;
+ }
+
+ if (dsigCtx->c14nMethod && dsigCtx->c14nMethod->id &&
+ dsigCtx->c14nMethod->id->name) {
+ LogInfo("Canonicalization method: " <<
+ reinterpret_cast<const char *>(dsigCtx->c14nMethod->id->name));
+ }
+
+ size = xmlSecPtrListGetSize(&(dsigCtx->signedInfoReferences));
+ for (int i = 0; i < size; ++i) {
+ xmlSecDSigReferenceCtxPtr dsigRefCtx =
+ (xmlSecDSigReferenceCtxPtr)xmlSecPtrListGetItem(&(dsigCtx->
+ signedInfoReferences),
+ i);
+ if (dsigRefCtx && dsigRefCtx->uri) {
+ if (dsigRefCtx->digestMethod && dsigRefCtx->digestMethod->id &&
+ dsigRefCtx->digestMethod->id->name) {
+ const char* pDigest =
+ reinterpret_cast<const char *>(dsigRefCtx->digestMethod->id
+ ->name);
+ std::string strDigest(pDigest);
+ LogInfo("reference digest method: " <<
+ reinterpret_cast<const char *>(dsigRefCtx->digestMethod
+ ->id
+ ->name));
+ if (strDigest == DIGEST_MD5) {
+ LogWarning("MD5 digest method used! Please use sha");
+ res = -1;
+ break;
+ }
+ }
+ context->referenceSet.insert(std::string(reinterpret_cast<char *>(
+ dsigRefCtx->uri)));
+ }
+ }
+
+done:
+ /* cleanup */
+ if (dsigCtx != NULL) {
+ xmlSecDSigCtxDestroy(dsigCtx);
+ }
+
+ if (doc != NULL) {
+ xmlFreeDoc(doc);
+ }
+
+ if (res) {
+ return ERROR_INVALID_SIGNATURE;
+ }
+ return NO_ERROR;
+}
+
+void XmlSec::loadDERCertificateMemory(XmlSecContext *context,
+ xmlSecKeysMngrPtr mngr)
+{
+ unsigned char *derCertificate = NULL;
+ int size = i2d_X509(context->certificatePtr->getX509(), &derCertificate);
+
+ if (!derCertificate) {
+ LogError("Failed during x509 conversion to der format.");
+ ThrowMsg(Exception::InternalError,
+ "Failed during x509 conversion to der format.");
+ }
+
+ if (xmlSecCryptoAppKeysMngrCertLoadMemory(mngr,
+ derCertificate,
+ size,
+ xmlSecKeyDataFormatDer,
+ xmlSecKeyDataTypeTrusted) < 0) {
+ OPENSSL_free(derCertificate);
+ LogError("Failed to load der certificate from memory.");
+ ThrowMsg(Exception::InternalError,
+ "Failed to load der certificate from memory.");
+ }
+
+ OPENSSL_free(derCertificate);
+}
+
+void XmlSec::loadPEMCertificateFile(XmlSecContext *context,
+ xmlSecKeysMngrPtr mngr)
+{
+ if (xmlSecCryptoAppKeysMngrCertLoad(mngr,
+ context->certificatePath.c_str(),
+ xmlSecKeyDataFormatPem,
+ xmlSecKeyDataTypeTrusted) < 0) {
+ LogError("Failed to load PEM certificate from file.");
+ ThrowMsg(Exception::InternalError,
+ "Failed to load PEM certificate from file.");
+ }
+}
+
+XmlSec::Result XmlSec::validate(XmlSecContext *context)
+{
+ Assert(context);
+ Assert(!(context->signatureFile.empty()));
+ Assert(context->certificatePtr.Get() || !(context->certificatePath.empty()));
+
+ if (!m_initialized) {
+ LogError("XmlSec is not initialized.");
+ ThrowMsg(Exception::InternalError, "XmlSec is not initialized");
+ }
+
+ AutoPtr<xmlSecKeysMngr> mngr(xmlSecKeysMngrCreate());
+
+ if (!mngr.get()) {
+ LogError("Failed to create keys manager.");
+ ThrowMsg(Exception::InternalError, "Failed to create keys manager.");
+ }
+
+ if (xmlSecCryptoAppDefaultKeysMngrInit(mngr.get()) < 0) {
+ LogError("Failed to initialize keys manager.");
+ ThrowMsg(Exception::InternalError, "Failed to initialize keys manager.");
+ }
+ context->referenceSet.clear();
+
+ if (context->certificatePtr.Get()) {
+ loadDERCertificateMemory(context, mngr.get());
+ }
+
+ if (!context->certificatePath.empty()) {
+ loadPEMCertificateFile(context, mngr.get());
+ }
+
+ return validateFile(context, mngr.get());
+}
+} // namespace ValidationCore
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file XmlSecAdapter.h
+ * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 1.0
+ * @brief
+ */
+#ifndef _XMLSECADAPTER_H_
+#define _XMLSECADAPTER_H_
+
+#include <xmlsec/keysmngr.h>
+
+#include <dpl/exception.h>
+#include <dpl/noncopyable.h>
+#include <dpl/singleton.h>
+
+#include "Certificate.h"
+#include "ValidatorCommon.h"
+
+namespace ValidationCore {
+class XmlSec : public DPL::Noncopyable
+{
+ public:
+
+ struct XmlSecContext
+ {
+ /* You _must_ set one of the value: certificatePath or certificate. */
+ XmlSecContext() :
+ validationTime(0),
+ allowBrokenChain(false),
+ errorBrokenChain(false)
+ {
+ }
+
+ /*
+ * Absolute path to signature file.
+ */
+ std::string signatureFile;
+ /*
+ * Direcotory with signed data.
+ * If you leave it empty xmlsec will use directory extracted
+ * from signatureFile.
+ */
+ std::string workingDirectory;
+ /*
+ * Path to trusted certificate.
+ */
+ std::string certificatePath;
+ /*
+ * Trusted certificate. In most cases it should be Root CA certificate.
+ */
+ CertificatePtr certificatePtr;
+ /*
+ * Validation date.
+ * 0 - uses current time.
+ */
+ time_t validationTime;
+ /*
+ * Input parameter.
+ * If true, signature validation will not be interrupted by chain error.
+ * If true and chain is broken then the value errorBrokenChain will be
+ * set to true.
+ */
+ bool allowBrokenChain;
+ /*
+ * Output parameter.
+ * This will be set if chain is incomplete or broken.
+ */
+ bool errorBrokenChain;
+ /*
+ * Output parameter.
+ * Reference checked by xmlsec
+ */
+ ReferenceSet referenceSet;
+ };
+
+ enum Result
+ {
+ NO_ERROR,
+ ERROR_INVALID_SIGNATURE
+ };
+
+ class Exception
+ {
+ public:
+ DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+ DECLARE_EXCEPTION_TYPE(Base, InternalError)
+ };
+
+ /*
+ * Context - input/output param.
+ */
+ Result validate(XmlSecContext *context);
+ protected:
+ XmlSec();
+ ~XmlSec();
+ private:
+ void deinitialize(void);
+
+ void loadDERCertificateMemory(XmlSecContext *context,
+ xmlSecKeysMngrPtr mngr);
+ void loadPEMCertificateFile(XmlSecContext *context,
+ xmlSecKeysMngrPtr mngr);
+ Result validateFile(XmlSecContext *context,
+ xmlSecKeysMngrPtr mngr);
+
+ bool m_initialized;
+
+ static std::string s_prefixPath;
+ static int fileMatchCallback(const char *filename);
+ static void* fileOpenCallback(const char *filename);
+ static int fileReadCallback(void *context,
+ char *buffer,
+ int len);
+ static int fileCloseCallback(void *context);
+ static void fileExtractPrefix(XmlSecContext *context);
+};
+
+typedef DPL::Singleton<XmlSec> XmlSecSingleton;
+} // namespace ValidationCore
+#endif // _XMLSECVERIFICATOR_H_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 WRT_ENGINE_SRC_COMMON_SCOPED_GPOINTER_H
+#define WRT_ENGINE_SRC_COMMON_SCOPED_GPOINTER_H
+
+#include <cstddef>
+#include <glib-object.h>
+
+#include <dpl/scoped_resource.h>
+#include <dpl/assert.h>
+
+namespace WRT {
+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);
+ }
+};
+} // namespace WRT
+
+#endif // WRT_ENGINE_SRC_COMMON_SCOPED_GPOINTER_H
--- /dev/null
+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
+ ${CMAKE_SOURCE_DIR}/modules/widget_dao/orm/iana_db
+ DEPENDS ${CMAKE_SOURCE_DIR}/modules/widget_dao/orm/wrt_db
+ ${CMAKE_SOURCE_DIR}/modules/widget_dao/orm/iana_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 ${PROJECT_SOURCE_DIR}/modules/widget_dao/orm/iana_db
+ )
+
+ADD_CUSTOM_COMMAND( OUTPUT .wrt.db-journal
+ COMMAND touch
+ ARGS ${CMAKE_CURRENT_BINARY_DIR}/.wrt.db-journal
+ )
+
+ADD_CUSTOM_TARGET(Sqlite3DbWRT 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
+ cert-svc
+ ecore
+ appcore-efl
+ libxml-2.0
+ openssl
+ REQUIRED)
+
+set(WRT_DAO_RO_SOURCES
+ dao/config_parser_data.cpp
+ dao/common_dao_types.cpp
+ dao/feature_dao_read_only.cpp
+ dao/global_dao_read_only.cpp
+ dao/global_config.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
+)
+
+set(WRT_DAO_RW_SOURCES
+ dao/feature_dao.cpp
+ dao/global_dao.cpp
+ dao/plugin_dao.cpp
+ dao/property_dao.cpp
+ dao/widget_dao.cpp
+)
+
+ADD_DEFINITIONS("-DSEPARATED_SINGLETON_IMPLEMENTATION")
+
+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
+ ${WRT_DAO_DEPS_INCLUDE_DIRS}
+ )
+
+INCLUDE_DIRECTORIES(${WRT_DAO_INCLUDE_DIRS})
+
+ADD_LIBRARY(${TARGET_WRT_DAO_RO_LIB} SHARED
+ ${WRT_DAO_RO_SOURCES}
+)
+SET_TARGET_PROPERTIES(${TARGET_WRT_DAO_RO_LIB} PROPERTIES
+ SOVERSION ${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_LIBRARY(${TARGET_WRT_DAO_RW_LIB} SHARED ${WRT_DAO_RW_SOURCES})
+
+SET_TARGET_PROPERTIES(${TARGET_WRT_DAO_RW_LIB} PROPERTIES
+ SOVERSION ${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})
+
+INSTALL(TARGETS ${TARGET_WRT_DAO_RO_LIB}
+ DESTINATION lib
+ PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
+ )
+
+INSTALL(TARGETS ${TARGET_WRT_DAO_RW_LIB}
+ DESTINATION lib
+ PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
+ )
+
+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/global_dao_read_only.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/WrtDatabase.h
+ DESTINATION include/dpl-efl/dpl/wrt-dao-ro
+ )
+
+INSTALL(FILES
+ include/dpl/wrt-dao-rw/feature_dao.h
+ include/dpl/wrt-dao-rw/global_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
+ )
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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/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::attachToThread()
+{
+ m_interface.AttachToThread();
+}
+
+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);
+}
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_to_dao.h
+ * @author Grzegorz Krawczyk (g.krawczyk@samsung.com)
+ * @version 1.0
+ * @brief
+ */
+
+#ifndef WRT_SRC_CONFIGURATION_BIND_TO_DAO_H_
+#define WRT_SRC_CONFIGURATION_BIND_TO_DAO_H_
+
+namespace WrtDB {
+
+/**
+ * @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::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::Model* obj)
+ {
+ ObjectType* instance = static_cast<ObjectType*>(obj);
+ ExtObject extObject((instance->*argGetter)());
+ return (extObject.*externalGetter)();
+ }
+};
+
+} // namespace WrtDB
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <dpl/wrt-dao-ro/common_dao_types.h>
+
+#include <dpl/log/log.h>
+
+namespace WrtDB {
+namespace Powder {
+
+Description::LevelEntry::LevelEntry(LevelEnum level) :
+ level(level)
+{
+}
+
+bool Description::LevelEntry::isContextValid(LevelEnum level,
+ const DPL::OptionalString& aContext) const
+{
+ if (!aContext) {
+ return level < level;
+ } else {
+ Context::const_iterator iter = context.find(*aContext);
+ if (iter != context.end()) {
+ return level < level;
+ } else {
+ return true;
+ }
+ }
+}
+
+bool Description::CategoryEntry::isCategoryValid(LevelEntry& aReason,
+ LevelEnum aLevel,
+ const DPL::OptionalString& aContext) const
+{
+ for (LevelsContainer::const_iterator iter = levels.begin();
+ iter != levels.end(); ++iter) {
+ if (!iter->isContextValid(aLevel, aContext)) {
+ aReason = *iter;
+ return false;
+ }
+ }
+ return true;
+}
+}
+
+namespace ChildProtection
+{
+
+PowderRules::CategoryRule::CategoryRule(const DPL::String& aCategory,
+ Powder::Description::LevelEnum aLevel,
+ const DPL::OptionalString& aContext) :
+ category(aCategory),
+ level(aLevel),
+ context(aContext)
+{
+}
+
+PowderRules::PowderResult::PowderResult(InvalidReason aReason,
+ const Powder::Description::LevelEntry& anInvalidDescription,
+ const CategoryRule& anInvalidRule) :
+ invalidDescription(anInvalidDescription),
+ invalidRule(anInvalidRule),
+ reason(aReason)
+{
+}
+
+//! Function checks if rule is fulfilled by description
+//! \param[in] rule checked rule
+//! \param[in] description
+//! \retval true rule is valid
+//! \retval false rule is invalid
+PowderRules::ResultPair PowderRules::isRuleValidForDescription(
+ const CategoryRule& aRule,
+ const Powder::Description& aDescription) const
+{
+ Powder::Description::CategoryEntries::const_iterator
+ iter = aDescription.categories.find(aRule.category);
+ if (iter != aDescription.categories.end()) {
+ Powder::Description::LevelEntry invalidDescription;
+ if (!iter->second.isCategoryValid(invalidDescription, aRule.level,
+ aRule.context)) {
+ LogWarning("Widget forbidden for children detected");
+ return std::make_pair(false,
+ PowderResult(PowderResult::InvalidRule,
+ invalidDescription,
+ aRule));
+ } else {
+ return std::make_pair(true, PowderResult());
+ }
+ } else {
+ return std::make_pair(true, PowderResult());
+ }
+}
+
+//! Function checks if age limit is fulfilled by description
+//! \param[in] description
+//! \retval true age is valid
+//! \retval false age is invalid
+PowderRules::ResultPair PowderRules::isAgeValidForDescription(
+ const Powder::Description& aDescription) const
+{
+ if (!ageLimit) {
+ return std::make_pair(true, PowderResult());
+ } else {
+ if (!!aDescription.ageRating) {
+ if (*aDescription.ageRating <= *ageLimit) {
+ return std::make_pair(true, PowderResult());
+ } else {
+ return std::make_pair(false,
+ PowderResult(PowderResult::InvalidAge));
+ }
+ } else {
+ if (!isAgeRatingRequired) {
+ return std::make_pair(true, PowderResult());
+ } else {
+ return std::make_pair(
+ false,
+ PowderResult(PowderResult::AgeRatingNotSet));
+ }
+ }
+ }
+}
+
+//! Function check if Widget description is valid for ChildProtection
+//! configuration
+//! \param description widget description
+//! \retval true widget is valid
+//! \retval false widget is invalid
+PowderRules::ResultPair PowderRules::isDescriptionValid(
+ const Powder::Description& aDescription) const
+{
+ ResultPair powderResult;
+ for (RulesContainer::const_iterator iter = rules.begin();
+ iter != rules.end(); ++iter) {
+ powderResult = isRuleValidForDescription(*iter, aDescription);
+ if (!powderResult.first) {
+ return powderResult;
+ }
+ }
+ return isAgeValidForDescription(aDescription);
+}
+
+}
+} // namespace WrtDB
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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)
+{
+ 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:
+ switch (*(str + 1)) {
+ case 0x85:
+ case 0xa0:
+ return true;
+
+ default:
+ 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;
+ }
+ 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)
+{
+ 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);
+ 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) {
+ 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);
+ }
+}
+
+bool ConfigParserData::Param::operator==(const Param& other) const
+{
+ return name == other.name && value == other.value;
+}
+
+bool ConfigParserData::Param::operator!=(const Param& other) const
+{
+ return name != other.name || value != other.value;
+}
+
+bool ConfigParserData::Param::operator >(const Param& other) const
+{
+ if (name == other.name) {
+ return value > other.value;
+ } else {
+ return name > other.name;
+ }
+}
+
+bool ConfigParserData::Param::operator>=(const Param& other) const
+{
+ if (name >= other.name) {
+ return true;
+ } else {
+ return value >= other.value;
+ }
+}
+
+bool ConfigParserData::Param::operator <(const Param& other) const
+{
+ if (name == other.name) {
+ return value < other.value;
+ } else {
+ return name < other.name;
+ }
+}
+
+bool ConfigParserData::Param::operator<=(const Param& other) const
+{
+ if (name <= other.name) {
+ return true;
+ } else {
+ return value <= other.value;
+ }
+}
+
+bool ConfigParserData::Feature::operator==(const Feature& other) const
+{
+ return name == other.name && paramsList == other.paramsList;
+}
+
+bool ConfigParserData::Feature::operator!=(const Feature& other) const
+{
+ return name != other.name || paramsList != other.paramsList;
+}
+
+bool ConfigParserData::Feature::operator >(const Feature& other) const
+{
+ if (name > other.name) {
+ return true;
+ }
+ if (name < other.name) {
+ return false;
+ }
+ return paramsList > other.paramsList;
+}
+
+bool ConfigParserData::Feature::operator>=(const Feature& other) const
+{
+ if (name > other.name) {
+ return true;
+ }
+ if (name < other.name) {
+ return false;
+ }
+ return paramsList >= other.paramsList;
+}
+
+bool ConfigParserData::Feature::operator <(const Feature& other) const
+{
+ if (name < other.name) {
+ return true;
+ }
+ if (name > other.name) {
+ return false;
+ }
+ return paramsList < other.paramsList;
+}
+
+bool ConfigParserData::Feature::operator<=(const Feature& other) const
+{
+ if (name < other.name) {
+ return true;
+ }
+ if (name > other.name) {
+ return false;
+ }
+ return paramsList <= other.paramsList;
+}
+
+bool ConfigParserData::Icon::operator==(const Icon& other) const
+{
+ return src == other.src;
+}
+
+bool ConfigParserData::Icon::operator!=(const Icon& other) const
+{
+ return src != other.src;
+}
+
+bool ConfigParserData::Icon::operator >(const Icon& other) const
+{
+ return src > other.src;
+}
+
+bool ConfigParserData::Icon::operator>=(const Icon& other) const
+{
+ return src >= other.src;
+}
+
+bool ConfigParserData::Icon::operator <(const Icon& other) const
+{
+ return src < other.src;
+}
+
+bool ConfigParserData::Icon::operator<=(const Icon& other) const
+{
+ return src <= other.src;
+}
+
+bool ConfigParserData::Preference::operator==(const Preference& other) const
+{
+ return name == other.name;
+}
+
+bool ConfigParserData::Preference::operator!=(const Preference& other) const
+{
+ return name != other.name;
+}
+
+bool ConfigParserData::Preference::operator >(const Preference& other) const
+{
+ return name > other.name;
+}
+
+bool ConfigParserData::Preference::operator>=(const Preference& other) const
+{
+ return name >= other.name;
+}
+
+bool ConfigParserData::Preference::operator <(const Preference& other) const
+{
+ return name < other.name;
+}
+
+bool ConfigParserData::Preference::operator<=(const Preference& other) const
+{
+ return name <= other.name;
+}
+
+bool ConfigParserData::AccessInfo::operator== (const AccessInfo& info) const
+{
+ return m_strIRI == info.m_strIRI && m_bSubDomainAccess ==
+ info.m_bSubDomainAccess;
+}
+
+bool ConfigParserData::AccessInfo::operator!= (const AccessInfo& info) const
+{
+ return m_strIRI != info.m_strIRI || m_bSubDomainAccess !=
+ info.m_bSubDomainAccess;
+}
+
+bool ConfigParserData::AccessInfo::operator <(const AccessInfo& info) const
+{
+ if (m_strIRI == info.m_strIRI) {
+ return m_bSubDomainAccess < info.m_bSubDomainAccess;
+ } else {
+ return m_strIRI < info.m_strIRI;
+ }
+}
+
+bool ConfigParserData::Setting::operator==(const Setting& other) const
+{
+ return m_name == other.m_name &&
+ m_value == other.m_value;
+}
+
+bool ConfigParserData::Setting::operator!=(const Setting& other) const
+{
+ return m_name != other.m_name ||
+ m_value != other.m_value;
+}
+
+bool ConfigParserData::Setting::operator >(const Setting& other) const
+{
+ return m_name > other.m_name;
+}
+
+bool ConfigParserData::Setting::operator>=(const Setting& other) const
+{
+ return m_name >= other.m_name;
+}
+
+bool ConfigParserData::Setting::operator <(const Setting& other) const
+{
+ return m_name < other.m_name;
+}
+
+bool ConfigParserData::Setting::operator<=(const Setting& other) const
+{
+ return m_name <= other.m_name;
+}
+
+bool ConfigParserData::ServiceInfo::operator== (const ServiceInfo& info) const
+{
+ return m_src == info.m_src &&
+ m_operation == info.m_operation &&
+ m_scheme == info.m_scheme &&
+ m_mime == info.m_mime;
+}
+
+bool ConfigParserData::ServiceInfo::operator!= (const ServiceInfo& info) const
+{
+ return m_src != info.m_src &&
+ m_operation != info.m_operation &&
+ m_scheme != info.m_scheme &&
+ m_mime != info.m_mime;
+}
+} // namespace WrtDB
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <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 {
+
+const int STRANGE_FEATURE_PROPERTIES_ID = 0;
+
+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
+ {
+ LogInfo(" |-- 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)) {
+ LogInfo(" | |--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 {
+ LogInfo(" | |--Register DeviceCap: " << *itdev);
+
+ DeviceCapabilities::Row row;
+ row.Set_DeviceCapName(DPL::FromUTF8String(*itdev));
+
+ WRT_DB_INSERT(insert, DeviceCapabilities, &WrtDatabase::interface())
+ insert->Values(row);
+ deviceCapID = 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");
+ }
+}
+
+FeatureHandle RegisterStrangeFeature(const std::string& featureName)
+{
+ Try
+ {
+ LogDebug("Registering Feature " << featureName);
+ DPL::DB::ORM::wrt::ScopedTransaction transaction(&WrtDatabase::interface());
+
+ if (FeatureDAOReadOnly::isFeatureInstalled(featureName)) {
+ LogError(" >> Feature " << featureName <<
+ " is already registered.");
+ transaction.Commit();
+ return -1;
+ }
+
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+
+ //register feature
+ LogInfo(" |-- Registering feature " << featureName);
+
+ FeaturesList::Row row;
+ row.Set_FeatureName(DPL::FromUTF8String(featureName));
+
+ // PluginPropertiesId '0' is not used as PluginPropertiesId for normal features(calendar, contact....).
+ // PluginPropertiesId for normal features start from '1'
+ row.Set_PluginPropertiesId(STRANGE_FEATURE_PROPERTIES_ID);
+
+ WRT_DB_INSERT(insert, FeaturesList, &WrtDatabase::interface())
+ insert->Values(row);
+ insert->Execute();
+
+ FeatureHandle featureHandle =
+ FeatureDAOReadOnly(featureName).GetFeatureHandle();
+
+ transaction.Commit();
+
+ return featureHandle;
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base){
+ ReThrowMsg(FeatureDAOReadOnly::Exception::DatabaseError,
+ "Failure during Registering Feature");
+ }
+}
+
+} // namespace FeatureDAO
+} // namespace WrtDB
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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::GetInstallURI() const
+{
+ GET_PLUGIN_DATA(getInstallURI)
+}
+
+std::string FeatureDAOReadOnly::GetKeyCn() const
+{
+ GET_PLUGIN_DATA(getKeyCn)
+}
+
+std::string FeatureDAOReadOnly::GetRootKey() const
+{
+ GET_PLUGIN_DATA(getRootKey)
+}
+
+std::string FeatureDAOReadOnly::GetRootKeyFingerprint() const
+{
+ GET_PLUGIN_DATA(getRootKeyFingerprint)
+}
+
+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");
+ }
+}
+
+} // namespace WrtDB
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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/wrt-dao-ro/global_config.h>
+
+#include <cstdlib>
+#include <cstring>
+
+namespace WrtDB {
+namespace GlobalConfig {
+bool IsOCSPEnabled()
+{
+ static const char *val = getenv("WRT_OCSP_ENABLE");
+ static bool enableOCSP = val && (strcmp(val, "1") == 0);
+ return enableOCSP;
+}
+
+bool IsCRLEnabled()
+{
+ static const char *val = getenv("WRT_CRL_ENABLE");
+ static bool enableOCSP = val && (strcmp(val, "1") == 0);
+ return enableOCSP;
+}
+
+} // namespace GlobalConfig
+} // namespace WrtDB
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_dao.cpp
+ * @author Pawel Sikorski (p.sikorski@samsung.com)
+ * @version 1.0
+ * @brief This file contains the definition of global dao class.
+ */
+
+#include <dpl/wrt-dao-rw/global_dao.h>
+#include <dpl/log/log.h>
+#include <dpl/string.h>
+#include <dpl/db/orm.h>
+#include <orm_generator_wrt.h>
+#include <dpl/wrt-dao-ro/webruntime_database.h>
+#include <dpl/wrt-dao-ro/WrtDatabase.h>
+
+namespace WrtDB {
+
+void GlobalDAO::AddAdultBlackListElement(const DPL::String &url)
+{
+ Try {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+
+ ScopedTransaction transaction(&WrtDatabase::interface());
+ if (IsElementOnAdultBlackList(url)) {
+ transaction.Commit();
+ return;
+ }
+
+ WRT_DB_INSERT(insert, ChildProtectionBlacklist, &WrtDatabase::interface())
+ ChildProtectionBlacklist::Row row;
+ row.Set_url(url);
+
+ insert->Values(row);
+ insert->Execute();
+ transaction.Commit();
+ } Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(GlobalDAO::Exception::DatabaseError,
+ "Failed to add element to AdultBlackList");
+ }
+}
+
+void GlobalDAO::RemoveAdultBlackListElement(const DPL::String &url)
+{
+ Try {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ WRT_DB_DELETE(deleteFrom, ChildProtectionBlacklist, &WrtDatabase::interface())
+
+ deleteFrom->Where(Equals<ChildProtectionBlacklist::url>(url));
+ deleteFrom->Execute();
+ } Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(GlobalDAO::Exception::DatabaseError,
+ "Failed to removed element from AdultBlackList");
+ }
+}
+
+void GlobalDAO::UpdateAdultBlackList(const DPL::String &oldUrl,
+ const DPL::String &newUrl)
+{
+ Try {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+
+ ScopedTransaction transaction(&WrtDatabase::interface());
+ if (IsElementOnAdultBlackList(newUrl)) {
+ transaction.Commit();
+ return;
+ }
+ WRT_DB_UPDATE(update, ChildProtectionBlacklist, &WrtDatabase::interface())
+ ChildProtectionBlacklist::Row row;
+ row.Set_url(newUrl);
+
+ update->Where(Equals<ChildProtectionBlacklist::url>(oldUrl));
+ update->Values(row);
+ update->Execute();
+ transaction.Commit();
+ } Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(GlobalDAO::Exception::DatabaseError,
+ "Failed to update an element in AdultBlackList");
+ }
+}
+
+void GlobalDAO::SetDeveloperMode(bool mode)
+{
+ LogDebug("updating Developer mode to:" << mode);
+ Try {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ GlobalProperties::Row row;
+ row.Set_developer_mode(mode);
+
+ WRT_DB_UPDATE(update, GlobalProperties, &WrtDatabase::interface())
+ update->Values(row);
+ update->Execute();
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base){
+ ReThrowMsg(GlobalDAO::Exception::DatabaseError,
+ "Failed to update Developer Mode");
+ }
+}
+
+void GlobalDAO::AddDefferedWidgetPackageInstallation(const DPL::String &path)
+{
+ LogDebug("Adding widget package as defered. Path: " << path);
+ Try {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ DefferedWidgetPackageInstallation::Row row;
+ row.Set_path(path);
+
+ WRT_DB_INSERT(insert, DefferedWidgetPackageInstallation, &WrtDatabase::interface())
+ insert->Values(row);
+ insert->Execute();
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base){
+ ReThrowMsg(GlobalDAO::Exception::DatabaseError,
+ "Failed to add defered widget package");
+ }
+}
+
+void GlobalDAO::RemoveDefferedWidgetPackageInstallation(const DPL::String &path)
+{
+ LogDebug("Remove widget package from differed list. Path: " << path);
+ Try {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ WRT_DB_DELETE(del, DefferedWidgetPackageInstallation, &WrtDatabase::interface())
+ del->Where(Equals<DefferedWidgetPackageInstallation::path>(path));
+ del->Execute();
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base){
+ ReThrowMsg(GlobalDAO::Exception::DatabaseError,
+ "Failed to remove defered widget package");
+ }
+}
+
+void GlobalDAO::SetParentalMode(bool parental_status)
+{
+ Try {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ GlobalProperties::Row row;
+ row.Set_parental_mode(parental_status);
+ WRT_DB_UPDATE(update, GlobalProperties, &WrtDatabase::interface())
+
+ update->Values(row);
+ update->Execute();
+ } Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(GlobalDAO::Exception::DatabaseError,
+ "Failed to update Parental Mode");
+ }
+}
+
+void GlobalDAO::SetParentalAllowedAge(const DPL::OptionalInt& age)
+{
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ Try {
+ typedef wrt::GlobalProperties::Row ParentalAllowedAgeRow;
+
+ ParentalAllowedAgeRow row;
+ row.Set_parental_allowed_age(age);
+ WRT_DB_UPDATE(update, GlobalProperties, &WrtDatabase::interface())
+ update->Values(row);
+ update->Execute();
+ } Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(GlobalDAO::Exception::DatabaseError,
+ "Failed to update Parental Mode");
+ }
+}
+
+void GlobalDAO::SetSecureByDefault(bool secure)
+{
+ //If secure == true -> widget does not need to be signed
+ Try {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ GlobalProperties::Row row;
+ row.Set_secure_by_default(secure);
+ WRT_DB_UPDATE(update, GlobalProperties, &WrtDatabase::interface())
+ update->Values(row);
+ update->Execute();
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(GlobalDAO::Exception::DatabaseError,
+ "Failed to update secureByDefault");
+ }
+}
+
+void GlobalDAO::setComplianceMode(bool mode)
+{
+ LogDebug("Updating compliance mode to:" << mode);
+ Try{
+ using namespace DPL::DB::ORM; using namespace DPL::DB::ORM::wrt;
+ GlobalProperties::Row row;
+ row.Set_compliance_mode(mode);
+
+ WRT_DB_UPDATE(update, GlobalProperties, &WrtDatabase::interface())
+ update->Values(row);
+ update->Execute();
+ }
+ Catch (DPL::DB::SqlConnection::Exception::Base){
+ ReThrowMsg(GlobalDAO::Exception::DatabaseError,
+ "Failed to update compliance mode");
+ }
+}
+
+void GlobalDAO::setComplianceFakeImei(const std::string &imei)
+{
+ LogDebug("Setting compliance fake IMEI: " << imei);
+ Try{
+ using namespace DPL::DB::ORM; using namespace DPL::DB::ORM::wrt;
+ GlobalProperties::Row row;
+ row.Set_compliance_fake_imei(DPL::FromASCIIString(imei));
+
+ WRT_DB_UPDATE(update, GlobalProperties, &WrtDatabase::interface())
+ update->Values(row);
+ update->Execute();
+ }
+ Catch (DPL::DB::SqlConnection::Exception::Base){
+ ReThrowMsg(GlobalDAO::Exception::DatabaseError,
+ "Failed to update compliance fake IMEI");
+ }
+}
+
+void GlobalDAO::setComplianceFakeMeid(const std::string &meid)
+{
+ LogDebug("Setting compliance fake MEID: " << meid);
+ Try{
+ using namespace DPL::DB::ORM; using namespace DPL::DB::ORM::wrt;
+ GlobalProperties::Row row;
+ row.Set_compliance_fake_meid(DPL::FromASCIIString(meid));
+
+ WRT_DB_UPDATE(update, GlobalProperties, &WrtDatabase::interface())
+ update->Values(row);
+ update->Execute();
+ }
+ Catch (DPL::DB::SqlConnection::Exception::Base){
+ ReThrowMsg(GlobalDAO::Exception::DatabaseError,
+ "Failed to update compliance fake MEID");
+ }
+}
+
+void GlobalDAO::AddCategoryRule(const ChildProtection::PowderRules::
+ CategoryRule& powder)
+{
+ Try {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ PowderRules::Row row;
+ row.Set_category(powder.category);
+ row.Set_level(powder.level);
+ row.Set_context(powder.context);
+
+ wrt::ScopedTransaction transaction(&WrtDatabase::interface());
+ if (IsPowderRulePresent(powder)) {
+ transaction.Commit();
+ return;
+ }
+ WRT_DB_INSERT(insert, PowderRules, &WrtDatabase::interface())
+
+ insert->Values(row);
+ insert->Execute();
+ transaction.Commit();
+ } Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(GlobalDAO::Exception::DatabaseError,
+ "Failed to add POWDER rules");
+ }
+}
+
+void GlobalDAO::RemoveCategoryRule(const ChildProtection::PowderRules::
+ CategoryRule& powder)
+{
+ Try {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+
+ if (!powder.context.IsNull()) {
+ WRT_DB_DELETE(delWithContext, PowderRules, &WrtDatabase::interface())
+
+ delWithContext->Where(
+ And(Equals<PowderRules::category>(powder.category),
+ And(Equals<PowderRules::level>(powder.level),
+ Equals<PowderRules::context>(powder.context))));
+ delWithContext->Execute();
+ } else {
+ WRT_DB_DELETE(delWithoutContext, PowderRules, &WrtDatabase::interface())
+ delWithoutContext->Where(
+ And(Equals<PowderRules::category>(powder.category),
+ And(Equals<PowderRules::level>(powder.level),
+ Is<PowderRules::context>(powder.context))));
+ delWithoutContext->Execute();
+ }
+ } Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(GlobalDAO::Exception::DatabaseError,
+ "Failed to remove POWDER rules");
+ }
+}
+
+void GlobalDAO::UpdateCategoryRule(
+ const ChildProtection::PowderRules::CategoryRule& oldRule,
+ const ChildProtection::PowderRules::CategoryRule& newRule)
+{
+ Try {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ PowderRules::Row row;
+ row.Set_category(newRule.category);
+ row.Set_level(newRule.level);
+ row.Set_context(newRule.context);
+
+ wrt::ScopedTransaction transaction(&WrtDatabase::interface());
+
+ if (IsPowderRulePresent(newRule)) {
+ transaction.Commit();
+ return;
+ }
+
+ if (!oldRule.context.IsNull()) {
+ WRT_DB_UPDATE(updateWithContext, PowderRules, &WrtDatabase::interface())
+ updateWithContext->Where(
+ And(Equals<PowderRules::category>(oldRule.category),
+ And(Equals<PowderRules::level>(oldRule.level),
+ Equals<PowderRules::context>(oldRule.context))));
+ updateWithContext->Values(row);
+ updateWithContext->Execute();
+ } else {
+ WRT_DB_UPDATE(updateWithoutContext, PowderRules, &WrtDatabase::interface())
+ updateWithoutContext->Where(
+ And(Equals<PowderRules::category>(oldRule.category),
+ And(Equals<PowderRules::level>(oldRule.level),
+ Is<PowderRules::context>(oldRule.context))));
+ updateWithoutContext->Values(row);
+ updateWithoutContext->Execute();
+ }
+ transaction.Commit();
+ } Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(GlobalDAO::Exception::DatabaseError,
+ "Failed to update POWDER rules");
+ }
+}
+
+void GlobalDAO::SetHomeNetworkDataUsage(GlobalDAO::NetworkAccessMode newMode)
+{
+ LogDebug("updating home network data usage to:" << newMode);
+ Try {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ GlobalProperties::Row row;
+ row.Set_home_network_data_usage(static_cast<int>(newMode));
+
+ WRT_DB_UPDATE(update, GlobalProperties, &WrtDatabase::interface())
+ update->Values(row);
+ update->Execute();
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base){
+ ReThrowMsg(GlobalDAO::Exception::DatabaseError,
+ "Failed to update home network data usage");
+ }
+}
+
+void GlobalDAO::SetRoamingDataUsage(GlobalDAO::NetworkAccessMode newMode)
+{
+ LogDebug("updating roaming network data usage to:" << newMode);
+ Try {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ GlobalProperties::Row row;
+ row.Set_roaming_data_usage(static_cast<int>(newMode));
+
+ WRT_DB_UPDATE(update, GlobalProperties, &WrtDatabase::interface())
+ update->Values(row);
+ update->Execute();
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base){
+ ReThrowMsg(GlobalDAO::Exception::DatabaseError,
+ "Failed to update roaming network data usage");
+ }
+}
+
+void GlobalDAO::SetAutoSaveIdPasswd(const DPL::String &url,
+ const AutoSaveData &saveData)
+{
+ Try {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ ScopedTransaction transaction(&WrtDatabase::interface());
+ AutoSaveIdPasswd::Row row;
+
+ row.Set_address(url);
+ row.Set_userId(saveData.userId);
+ row.Set_passwd(saveData.passwd);
+
+ DPL::Optional<GlobalDAO::AutoSaveData> savedData =
+ GetAutoSaveIdPasswd(url);
+
+ if (!savedData.IsNull()) {
+ WRT_DB_UPDATE(update, AutoSaveIdPasswd, &WrtDatabase::interface())
+
+ update->Where(Equals<AutoSaveIdPasswd::address>(url));
+ update->Values(row);
+ update->Execute();
+ } else {
+ WRT_DB_INSERT(insert, AutoSaveIdPasswd, &WrtDatabase::interface());
+ insert->Values(row);
+ insert->Execute();
+ }
+
+ transaction.Commit();
+ } Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(GlobalDAO::Exception::DatabaseError,
+ "Fail to register id, passwd for autosave");
+ }
+}
+
+void GlobalDAO::AddWhiteURI(const std::string &uri, bool subDomain)
+{
+ LogDebug("Add White URI : " << uri);
+ Try {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ WidgetWhiteURIList::Row row;
+ row.Set_uri(DPL::FromASCIIString(uri));
+ row.Set_subdomain_access(static_cast<int>(subDomain));
+ wrt::ScopedTransaction transaction(&WrtDatabase::interface());
+
+ WRT_DB_INSERT(insert, WidgetWhiteURIList, &WrtDatabase::interface())
+
+ insert->Values(row);
+ insert->Execute();
+ transaction.Commit();
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base){
+ ReThrowMsg(GlobalDAO::Exception::DatabaseError,
+ "Failed to add white URI");
+ }
+}
+
+void GlobalDAO::RemoveWhiteURI(const std::string &uri)
+{
+ LogDebug("Remove White URI : " << uri);
+ Try {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+
+ WRT_DB_DELETE(deleteFrom, WidgetWhiteURIList, &WrtDatabase::interface())
+ deleteFrom->Where(Equals<WidgetWhiteURIList::uri>(DPL::FromASCIIString(uri)));
+ deleteFrom->Execute();
+ } Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(GlobalDAO::Exception::DatabaseError,
+ "Failed to removed white URI from AdultBlackList");
+ }
+}
+
+} // namespace WrtDB
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_dao_read_only.cpp
+ * @author Pawel Sikorski (p.sikorski@samsung.com)
+ * @version 1.0
+ * @brief This file contains the definition of global dao class.
+ */
+
+#include <dpl/wrt-dao-ro/global_dao_read_only.h>
+
+#include <dpl/foreach.h>
+#include <dpl/log/log.h>
+#include <dpl/string.h>
+#include <dpl/db/orm.h>
+#include <orm_generator_wrt.h>
+#include <dpl/wrt-dao-ro/webruntime_database.h>
+#include <dpl/wrt-dao-ro/WrtDatabase.h>
+#include <dpl/wrt-dao-ro/common_dao_types.h>
+
+namespace WrtDB {
+
+ChildProtection::BlackList GlobalDAOReadOnly::GetAdultBlackList()
+{
+ LogDebug("Getting AdultBlackList");
+ Try {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ WRT_DB_SELECT(select, ChildProtectionBlacklist, &WrtDatabase::interface())
+ std::list<DPL::String> list =
+ select->GetValueList<ChildProtectionBlacklist::url>();
+ ChildProtection::BlackList blacklist(list.begin(), list.end());
+ return blacklist;
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base){
+ ReThrowMsg(GlobalDAOReadOnly::Exception::DatabaseError,
+ "Failed to get AdultBalckList");
+ }
+}
+
+bool GlobalDAOReadOnly::IsElementOnAdultBlackList(const DPL::String &url)
+{
+ Try {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ WRT_DB_SELECT(select, ChildProtectionBlacklist, &WrtDatabase::interface())
+ select->Where(Equals<ChildProtectionBlacklist::url>(url));
+
+ return !select->GetRowList().empty();
+ } Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(GlobalDAOReadOnly::Exception::DatabaseError,
+ "Failure during checking if url is on pwoder black list");
+ }
+}
+
+bool GlobalDAOReadOnly::GetDeveloperMode()
+{
+ LogDebug("Getting Developer mode");
+ Try {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ WRT_DB_SELECT(select, GlobalProperties, &WrtDatabase::interface())
+ return select->GetSingleValue<GlobalProperties::developer_mode>();
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base){
+ ReThrowMsg(GlobalDAOReadOnly::Exception::DatabaseError,
+ "Failed to get developer mode");
+ }
+}
+
+WidgetPackageList GlobalDAOReadOnly::GetDefferedWidgetPackageInstallationList()
+{
+ LogDebug("Getting widget packages list defered for installation");
+ Try {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ WRT_DB_SELECT(select, DefferedWidgetPackageInstallation, &WrtDatabase::interface())
+ return select->GetValueList<DefferedWidgetPackageInstallation::path>();
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base){
+ ReThrowMsg(GlobalDAOReadOnly::Exception::DatabaseError,
+ "Failed to get defered widget packages list");
+ }
+}
+
+bool GlobalDAOReadOnly::GetParentalMode()
+{
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ WRT_DB_SELECT(select, GlobalProperties, &WrtDatabase::interface())
+ return select->GetSingleValue<GlobalProperties::parental_mode>();
+}
+
+DPL::OptionalInt GlobalDAOReadOnly::GetParentalAllowedAge()
+{
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ WRT_DB_SELECT(select, GlobalProperties, &WrtDatabase::interface())
+ return select->GetSingleValue<GlobalProperties::parental_allowed_age>();
+}
+
+bool GlobalDAOReadOnly::GetSecureByDefault()
+{
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ WRT_DB_SELECT(select, GlobalProperties, &WrtDatabase::interface())
+ return select->GetSingleValue<GlobalProperties::secure_by_default>();
+}
+
+bool GlobalDAOReadOnly::getComplianceMode()
+{
+ LogDebug("Getting compliance mode");
+ Try{
+ using namespace DPL::DB::ORM; using namespace DPL::DB::ORM::wrt;
+ WRT_DB_SELECT(select, GlobalProperties, &WrtDatabase::interface())
+ return select->GetSingleValue<GlobalProperties::compliance_mode>();
+ }
+ Catch (DPL::DB::SqlConnection::Exception::Base){
+ ReThrowMsg(GlobalDAOReadOnly::Exception::DatabaseError,
+ "Failed to get compliance mode");
+ }
+}
+
+std::string GlobalDAOReadOnly::getComplianceFakeImei()
+{
+ LogDebug("Getting compliance fake IMEI");
+ Try{
+ using namespace DPL::DB::ORM; using namespace DPL::DB::ORM::wrt;
+ WRT_DB_SELECT(select, GlobalProperties, &WrtDatabase::interface())
+ DPL::Optional<DPL::String> result =
+ select->GetSingleValue<GlobalProperties::compliance_fake_imei>();
+ if (!result) {
+ return std::string();
+ }
+ return DPL::ToUTF8String(*result);
+ }
+ Catch (DPL::DB::SqlConnection::Exception::Base){
+ ReThrowMsg(GlobalDAOReadOnly::Exception::DatabaseError,
+ "Failed to get compliance fake IMEI");
+ }
+}
+
+std::string GlobalDAOReadOnly::getComplianceFakeMeid()
+{
+ LogDebug("Getting compliance fake MEID");
+ Try{
+ using namespace DPL::DB::ORM; using namespace DPL::DB::ORM::wrt;
+ WRT_DB_SELECT(select, GlobalProperties, &WrtDatabase::interface())
+ DPL::Optional<DPL::String> result =
+ select->GetSingleValue<GlobalProperties::compliance_fake_meid>();
+ if (!result) {
+ return std::string();
+ }
+ return DPL::ToUTF8String(*result);
+ }
+ Catch (DPL::DB::SqlConnection::Exception::Base){
+ ReThrowMsg(GlobalDAOReadOnly::Exception::DatabaseError,
+ "Failed to get compliance fake MEID");
+ }
+}
+
+bool GlobalDAOReadOnly::IsValidSubTag(const DPL::String& tag, int type)
+{
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ WRT_DB_SELECT(select, iana_records, &WrtDatabase::interface())
+ select->Where(Equals<iana_records::SUBTAG>(tag));
+ auto row = select->GetRowList();
+ if (row.size() == 0 || row.front().Get_TYPE() != type) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
+
+bool GlobalDAOReadOnly::IsPowderRulePresent(
+ const ChildProtection::PowderRules::CategoryRule& powder)
+{
+ Try {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+
+ if (!powder.context.IsNull()) {
+ WRT_DB_SELECT(selWithContext, PowderRules, &WrtDatabase::interface())
+
+ selWithContext->Where(
+ And(Equals<PowderRules::category>(powder.category),
+ And(Equals<PowderRules::level>(powder.level),
+ Equals<PowderRules::context>(powder.context))));
+ return !selWithContext->GetRowList().empty();
+ } else {
+ WRT_DB_SELECT(selWithoutContext, PowderRules, &WrtDatabase::interface())
+ selWithoutContext->Where(
+ And(Equals<PowderRules::category>(powder.category),
+ And(Equals<PowderRules::level>(powder.level),
+ Is<PowderRules::context>(powder.context))));
+ return !selWithoutContext->GetRowList().empty();
+ }
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(GlobalDAOReadOnly::Exception::DatabaseError,
+ "Failure during checking if rule is present");
+ }
+}
+
+ChildProtection::PowderRules GlobalDAOReadOnly::GetPowderRules()
+{
+ ChildProtection::PowderRules powder;
+ powder.ageLimit = GetParentalAllowedAge();
+
+ Try {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ typedef std::list<PowderRules::Row> PowderRulesList;
+ WRT_DB_SELECT(select, PowderRules, &WrtDatabase::interface())
+
+ PowderRulesList list = select->GetRowList();
+ FOREACH(it, list) {
+ using namespace Powder;
+ powder.rules.push_back(
+ ChildProtection::PowderRules::CategoryRule(
+ it->Get_category(),
+ static_cast<Description::LevelEnum>(it->Get_level()),
+ it->Get_context()));
+ }
+ return powder;
+ } Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(GlobalDAOReadOnly::Exception::DatabaseError,
+ "Failed to get POWDER rules");
+ }
+}
+
+GlobalDAOReadOnly::NetworkAccessMode
+ GlobalDAOReadOnly::GetHomeNetworkDataUsage()
+{
+ LogDebug("Getting home network data usage");
+ Try {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ WRT_DB_SELECT(select, GlobalProperties, &WrtDatabase::interface())
+ return static_cast<GlobalDAOReadOnly::NetworkAccessMode>(
+ select->GetSingleValue<
+ GlobalProperties::home_network_data_usage>());
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base){
+ ReThrowMsg(GlobalDAOReadOnly::Exception::DatabaseError,
+ "Failed to get home network data usage");
+ }
+}
+
+GlobalDAOReadOnly::NetworkAccessMode GlobalDAOReadOnly::GetRoamingDataUsage()
+{
+ LogDebug("Getting roaming network data usage");
+ Try {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ WRT_DB_SELECT(select, GlobalProperties, &WrtDatabase::interface())
+ return static_cast<GlobalDAOReadOnly::NetworkAccessMode>(
+ select->GetSingleValue<GlobalProperties::roaming_data_usage>());
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base){
+ ReThrowMsg(GlobalDAOReadOnly::Exception::DatabaseError,
+ "Failed to get roaming network data usage");
+ }
+}
+
+//user agent strings are stored in db...
+//and it is configurable for test in development.
+DPL::String GlobalDAOReadOnly::GetUserAgentValue(const DPL::String &key)
+{
+ LogDebug("Get User Agent Value : " << key);
+ Try {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ WRT_DB_SELECT(select, UserAgents, &WrtDatabase::interface())
+ select->Where(Equals<UserAgents::key_name>(key));
+ DPL::Optional<DPL::String> agent =
+ select->GetSingleValue<UserAgents::key_value>();
+ if (agent.IsNull()) {
+ return DPL::FromUTF8String("");
+ } else {
+ return *agent;
+ }
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base){
+ ReThrowMsg(GlobalDAOReadOnly::Exception::DatabaseError,
+ "Failed to get user agent string");
+ }
+}
+
+DeviceCapabilitySet GlobalDAOReadOnly::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(GlobalDAOReadOnly::Exception::DatabaseError,
+ "Failed to update roaming network data usage");
+ }
+}
+
+DPL::Optional<GlobalDAOReadOnly::AutoSaveData>
+ GlobalDAOReadOnly::GetAutoSaveIdPasswd(const DPL::String &url)
+{
+ Try{
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ WRT_DB_SELECT(select, AutoSaveIdPasswd, &WrtDatabase::interface());
+ select->Where(Equals<AutoSaveIdPasswd::address>(url));
+ AutoSaveIdPasswd::Select::RowList rows = select->GetRowList();
+
+ if (rows.empty()) {
+ return DPL::Optional<GlobalDAOReadOnly::AutoSaveData>::Null;
+ }
+
+ GlobalDAOReadOnly::AutoSaveData saveData;
+ saveData.userId = rows.front().Get_userId();
+ saveData.passwd = rows.front().Get_passwd();
+ return saveData;
+ } Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(GlobalDAOReadOnly::Exception::DatabaseError,
+ "Failed to get autosave data string");
+ }
+}
+
+WidgetAccessInfoList GlobalDAOReadOnly::GetWhiteURIList()
+{
+ LogDebug("Getting WhiteURIList.");
+ Try{
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ WRT_DB_SELECT(select, WidgetWhiteURIList, &WrtDatabase::interface())
+
+ WidgetAccessInfoList resultList;
+ typedef std::list<WidgetWhiteURIList::Row> RowList;
+ RowList list = select->GetRowList();
+
+ for (RowList::iterator i = list.begin(); i != list.end(); ++i) {
+ WidgetAccessInfo whiteURI;
+ whiteURI.strIRI = i->Get_uri();
+ whiteURI.bSubDomains = i->Get_subdomain_access();
+ resultList.push_back(whiteURI);
+ LogInfo("[uri] : " << whiteURI.strIRI <<
+ ", [subdomain] : " << whiteURI.bSubDomains);
+ }
+ return resultList;
+ } Catch(DPL::DB::SqlConnection::Exception::Base) {
+ ReThrowMsg(GlobalDAOReadOnly::Exception::DatabaseError,
+ "Failed to get whiteURI list");
+ }
+}
+
+} // namespace WrtDB
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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();
+ LogInfo(" >> 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));
+ row.Set_InstallURI(
+ DPL::FromUTF8String(metafile.m_featuresInstallURI));
+ row.Set_KeyCN(
+ DPL::FromUTF8String(metafile.m_featuresKeyCN));
+ row.Set_RootKeyCN(
+ DPL::FromUTF8String(metafile.m_featuresRootCN));
+ row.Set_RootKeyFingerprint(
+ DPL::FromUTF8String(metafile.m_featuresRootFingerprint));
+
+ WRT_DB_INSERT(insert, PluginProperties, &WrtDatabase::interface())
+ insert->Values(row);
+ handle = 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");
+ }
+}
+
+} // namespace WrtDB
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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");
+ }
+}
+
+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;
+}
+
+std::string PluginDAOReadOnly::getInstallURI() const
+{
+ LogDebug("Getting plugin install URI. Handle: " << m_pluginHandle);
+ PluginRow row = getPluginRow(m_pluginHandle);
+ RETURN_STD_STRING(row.Get_InstallURI(), "install URI")
+}
+
+std::string PluginDAOReadOnly::getKeyCn() const
+{
+ LogDebug("Getting plugin KeyCn. Handle: " << m_pluginHandle);
+ PluginRow row = getPluginRow(m_pluginHandle);
+ RETURN_STD_STRING(row.Get_KeyCN(), "keyCN")
+}
+
+std::string PluginDAOReadOnly::getRootKey() const
+{
+ LogDebug("Getting plugin rootKey. Handle: " << m_pluginHandle);
+ PluginRow row = getPluginRow(m_pluginHandle);
+ RETURN_STD_STRING(row.Get_RootKeyCN(), "rootKey")
+}
+
+std::string PluginDAOReadOnly::getRootKeyFingerprint() const
+{
+ LogDebug("Getting plugin rootKeyFingerprint. Handle: " << m_pluginHandle);
+ PluginRow row = getPluginRow(m_pluginHandle);
+ RETURN_STD_STRING(row.Get_RootKeyFingerprint(), "rootKeyFingerprint")
+}
+
+#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::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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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(DbWidgetHandle widgetHandle,
+ 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. Handle: " << widgetHandle << ", key: " << key);
+ Try {
+ DPL::DB::ORM::wrt::ScopedTransaction transaction(&WrtDatabase::interface());
+
+ DPL::OptionalInt readonly = PropertyDAOReadOnly::CheckPropertyReadFlag(
+ widgetHandle,
+ 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::app_id>(widgetHandle),
+ Equals<WidgetPreference::key_name>(key)));
+ del->Execute();
+
+ transaction.Commit();
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base){
+ ReThrowMsg(PropertyDAOReadOnly::Exception::DatabaseError,
+ "Failure during removing property");
+ }
+}
+
+void SetProperty(DbWidgetHandle widgetHandle,
+ const PropertyDAOReadOnly::WidgetPropertyKey &key,
+ const PropertyDAOReadOnly::WidgetPropertyValue &value,
+ bool readOnly)
+{
+ LogDebug("Setting/updating Property. Handle: " << widgetHandle <<
+ ", 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(
+ widgetHandle,
+ key);
+ if (!readonly.IsNull() && *readonly == 1) {
+ LogError("'" << key <<
+ "' key is readonly. Cannot remove property !");
+ ThrowMsg(PropertyDAOReadOnly::Exception::ReadOnlyProperty,
+ "Property is readonly");
+ }
+
+ if (readonly.IsNull()) {
+ WidgetPreference::Row row;
+ row.Set_app_id(widgetHandle);
+ 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::app_id>(widgetHandle),
+ 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,
+ const WidgetRegisterInfo ®Info)
+{
+ LogDebug("Registering proferences for widget. Handle: " << widgetHandle);
+
+ // 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_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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <dpl/wrt-dao-ro/property_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.app_id = it->Get_app_id();
+ 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);
+ }
+}
+
+
+}
+
+WidgetPropertyKeyList GetPropertyKeyList(DbWidgetHandle widgetHandle)
+{
+ LogDebug("Get PropertyKey list. Handle: " << widgetHandle);
+ Try {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ 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)
+{
+ LogDebug("Get Property list. Handle: " << 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");
+ }
+}
+
+WidgetPropertyValue GetPropertyValue(DbWidgetHandle widgetHandle,
+ const WidgetPropertyKey &key)
+{
+ LogDebug("Get Property value. Handle: " << widgetHandle <<
+ ", key: " << key);
+ Try {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ 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");
+ }
+}
+
+DPL::OptionalInt CheckPropertyReadFlag(DbWidgetHandle widgetHandle,
+ const WidgetPropertyKey &key)
+{
+ LogDebug("Checking Property flag. Handle: " << widgetHandle <<
+ ", key: " << key);
+ Try {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ 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");
+ }
+}
+
+} // namespace PropertyDAOReadOnly
+} // namespace WrtDB
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <dpl/wrt-dao-ro/webruntime_database.h>
+
+DPL::Mutex g_wrtDbQueriesMutex;
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <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); \
+ }
+
+#define CHECK_WIDGET_EXISTENCE(macro_transaction, macro_handle) \
+ if (!WidgetDAO::isWidgetInstalled(macro_handle)) \
+ { \
+ macro_transaction.Commit(); \
+ LogWarning("Cannot find widget. Handle: " << macro_handle); \
+ ThrowMsg(WidgetDAO::Exception::WidgetNotExist, \
+ "Cannot find widget. Handle: " << macro_handle); \
+ }
+
+
+WidgetDAO::WidgetDAO(DbWidgetHandle widgetHandle) :
+ WidgetDAOReadOnly(widgetHandle)
+{
+}
+
+WidgetDAO::WidgetDAO(DPL::OptionalString widgetGUID) :
+ WidgetDAOReadOnly(WidgetDAOReadOnly::getHandle(widgetGUID))
+{
+}
+
+WidgetDAO::~WidgetDAO()
+{
+}
+
+void WidgetDAO::removeProperty(
+ const PropertyDAOReadOnly::WidgetPropertyKey &key)
+{
+ Try {
+ PropertyDAO::RemoveProperty(m_widgetHandle, key);
+ }
+ Catch(PropertyDAOReadOnly::Exception::ReadOnlyProperty){
+ ReThrowMsg(WidgetDAO::Exception::DatabaseError,
+ "Failure during removing property");
+ }
+}
+
+void WidgetDAO::setProperty(
+ const PropertyDAOReadOnly::WidgetPropertyKey &key,
+ const PropertyDAOReadOnly::WidgetPropertyValue &value,
+ bool readOnly)
+{
+ Try {
+ PropertyDAO::SetProperty(m_widgetHandle, key, value, readOnly);
+ }
+ Catch(PropertyDAOReadOnly::Exception::ReadOnlyProperty){
+ ReThrowMsg(WidgetDAO::Exception::DatabaseError,
+ "Failure during setting/updating property");
+ }
+}
+
+void WidgetDAO::setPkgName(const DPL::OptionalString& pkgName)
+{
+ SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
+ {
+ using namespace DPL::DB::ORM;
+ wrt::ScopedTransaction transaction(&WrtDatabase::interface());
+
+ isWidgetInstalled(getHandle());
+
+ wrt::WidgetInfo::Row row;
+ row.Set_pkgname(pkgName);
+
+ 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")
+}
+
+DbWidgetHandle WidgetDAO::registerWidget(const WidgetRegisterInfo &widgetRegInfo,
+ const IWacSecurity &wacSecurity,
+ const LanguageTagsList& languageTags)
+{
+ LogDebug("Registering widget");
+ SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
+ {
+ DPL::DB::ORM::wrt::ScopedTransaction transaction(&WrtDatabase::interface());
+
+ //Register into WidgetInfo has to be first
+ //as all other tables depend upon that
+ DbWidgetHandle widgetHandle =
+ registerWidgetInfo(widgetRegInfo, wacSecurity);
+
+ registerWidgetExtendedInfo(widgetHandle, widgetRegInfo);
+
+ registerWidgetLocalizedInfo(widgetHandle, widgetRegInfo);
+
+ registerWidgetUserAgentLocales(
+ widgetHandle, widgetRegInfo, languageTags);
+
+ registerWidgetIcons(widgetHandle, widgetRegInfo);
+
+ registerWidgetStartFile(widgetHandle, widgetRegInfo);
+
+ PropertyDAO::RegisterProperties(widgetHandle, widgetRegInfo);
+
+ registerWidgetFeatures(widgetHandle, widgetRegInfo);
+
+ registerWidgetWindowModes(widgetHandle, widgetRegInfo);
+
+ registerWidgetWarpInfo(widgetHandle, widgetRegInfo);
+
+ registerWidgetCertificates(widgetHandle, wacSecurity);
+
+ CertificateChainList list;
+ wacSecurity.getCertificateChainList(list);
+ registerLaunchCertificates(widgetHandle,list);
+
+ registerWidgetPowderData(widgetHandle, widgetRegInfo);
+
+ registerWidgetSettings(widgetHandle, widgetRegInfo);
+
+ registerAppService(widgetHandle, widgetRegInfo);
+
+ transaction.Commit();
+
+ return widgetHandle;
+ }
+ SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to register widget")
+}
+
+#define DO_INSERT(row, table) \
+ { \
+ WRT_DB_INSERT(insert, table, &WrtDatabase::interface()) \
+ insert->Values(row); \
+ insert->Execute(); \
+ }
+
+void WidgetDAO::registerWidgetExtendedInfo(DbWidgetHandle widgetHandle,
+ const WidgetRegisterInfo ®Info)
+{
+ //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_share_href (DPL::FromUTF8String(regInfo.shareHref));
+ row.Set_signature_type(regInfo.signatureType);
+ row.Set_factory_widget(regInfo.isFactoryWidget);
+ row.Set_test_widget(regInfo.isTestWidget);
+ row.Set_install_time(regInfo.installedTime);
+
+ DO_INSERT(row, WidgetExtendedInfo)
+}
+
+DbWidgetHandle WidgetDAO::registerWidgetInfo(const WidgetRegisterInfo ®Info,
+ const IWacSecurity &wacSecurity)
+{
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ const ConfigParserData& widgetConfigurationInfo = regInfo.configInfo;
+
+ // TODO in wrt_db all Columns in WidgetInfo have DEFAULT VALUE set.
+ // Because of that, "Optional" is not used there
+
+ WidgetInfo::Row row;
+ row.Set_widget_type(regInfo.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_base_folder(DPL::FromUTF8String(regInfo.baseFolder));
+ row.Set_webkit_plugins_required(widgetConfigurationInfo.flashNeeded);
+ row.Set_child_protection(1);
+ row.Set_recognized(wacSecurity.isRecognized());
+ row.Set_wac_signed(wacSecurity.isWacSigned());
+ row.Set_distributor_signed(wacSecurity.isDistributorSigned());
+ {
+ std::stringstream tmp;
+ tmp << widgetConfigurationInfo.minVersionRequired;
+ row.Set_min_version(DPL::FromUTF8String(tmp.str()));
+ }
+ row.Set_back_supported(widgetConfigurationInfo.backSupported);
+ row.Set_access_network(widgetConfigurationInfo.accessNetwork);
+ row.Set_pkgname(regInfo.pkgname);
+
+ wrt::WidgetInfo::app_id::ColumnType appID;
+ {
+ WRT_DB_INSERT(insert, WidgetInfo, &WrtDatabase::interface())
+ insert->Values(row);
+ appID = insert->Execute();
+ }
+ return appID;
+}
+
+void WidgetDAO::registerWidgetLocalizedInfo(DbWidgetHandle widgetHandle,
+ const WidgetRegisterInfo ®Info)
+{
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+
+ const ConfigParserData& widgetConfigurationInfo = regInfo.configInfo;
+
+ FOREACH(it, widgetConfigurationInfo.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::registerWidgetUserAgentLocales(
+ DbWidgetHandle widgetHandle,
+ const WidgetRegisterInfo &/*regInfo*/,
+ const LanguageTagsList& languageTags)
+{
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+
+
+ FOREACH(i, languageTags)
+ {
+ wrt::WidgetUserAgentLocales::Row row;
+ row.Set_app_id(widgetHandle);
+ row.Set_language_tag(*i);
+
+ DO_INSERT(row, wrt::WidgetUserAgentLocales)
+ }
+}
+
+void WidgetDAO::registerWidgetIcons(DbWidgetHandle widgetHandle,
+ const WidgetRegisterInfo ®Info)
+{
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+
+
+ FOREACH(i, regInfo.localizationData.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 = 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);
+ WRT_DB_SELECT(select, WidgetLocalizedIcon, &WrtDatabase::interface())
+ select->Where(And(Equals<WidgetLocalizedIcon::app_id>(widgetHandle),
+ Equals<WidgetLocalizedIcon::widget_locale>(*j)));
+ WidgetLocalizedIcon::Select::RowList rows = select->GetRowList();
+
+ bool flag = !rows.empty();
+
+ if(flag == true)
+ {
+ // already default icon value of same locale exists
+ WRT_DB_UPDATE(update, WidgetLocalizedIcon, &WrtDatabase::interface())
+ update->Where(And(Equals<WidgetLocalizedIcon::app_id>(widgetHandle),
+ Equals<WidgetLocalizedIcon::widget_locale>(*j)));
+ update->Values(row);
+ update->Execute();
+ }else{
+ // any icon value of same locale doesn't exist
+ DO_INSERT(row, WidgetLocalizedIcon)
+ }
+ }
+ }
+}
+
+void WidgetDAO::registerWidgetStartFile(DbWidgetHandle widgetHandle,
+ const WidgetRegisterInfo ®Info)
+{
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+
+
+ FOREACH(i, regInfo.localizationData.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 = 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 WidgetRegisterInfo ®Info)
+{
+ using namespace DPL::DB::ORM;
+ const ConfigParserData& widgetConfigurationInfo = regInfo.configInfo;
+
+
+ FOREACH(pWidgetFeature, widgetConfigurationInfo.featuresList)
+ {
+ wrt::WidgetFeature::Row widgetFeature;
+ widgetFeature.Set_app_id(widgetHandle);
+ widgetFeature.Set_name(pWidgetFeature->name);
+ widgetFeature.Set_required(pWidgetFeature->required);
+
+ wrt::WidgetFeature::widget_feature_id::ColumnType widgetFeatureID;
+ {
+ WRT_DB_INSERT(insert, wrt::WidgetFeature, &WrtDatabase::interface())
+ insert->Values(widgetFeature);
+ widgetFeatureID = insert->Execute();
+ }
+
+ // Insert into table FeatureParam
+ wrt::FeatureParam::Row featureParam;
+ featureParam.Set_widget_feature_id(widgetFeatureID);
+
+ ConfigParserData::ParamsList::const_iterator iter;
+
+ FOREACH(iter, pWidgetFeature->paramsList)
+ {
+ featureParam.Set_name(iter->name);
+ featureParam.Set_value(iter->value);
+
+ DO_INSERT(featureParam, wrt::FeatureParam)
+ }
+ }
+}
+
+void WidgetDAO::registerWidgetWindowModes(DbWidgetHandle widgetHandle,
+ const WidgetRegisterInfo ®Info)
+{
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ const ConfigParserData& widgetConfigurationInfo = regInfo.configInfo;
+
+
+ FOREACH(i, widgetConfigurationInfo.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 WidgetRegisterInfo ®Info)
+{
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ const ConfigParserData& widgetConfigurationInfo = regInfo.configInfo;
+
+
+ FOREACH(AccIt, widgetConfigurationInfo.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::registerWidgetCertificates(DbWidgetHandle widgetHandle,
+ const IWacSecurity &wacSecurity)
+{
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+
+
+ FOREACH(it, wacSecurity.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::registerWidgetPowderData(DbWidgetHandle widgetHandle,
+ const WidgetRegisterInfo ®Info)
+{
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+
+ using namespace Powder;
+
+ FOREACH(i, regInfo.powderDescription.categories)
+ {
+ const DPL::String& categoryName(i->first);
+ const Description::CategoryEntry& categoryEntry(i->second);
+ FOREACH(l, categoryEntry.levels)
+ {
+ PowderLevels::id::ColumnType powderID;
+ {
+ PowderLevels::Row row;
+ row.Set_app_id(widgetHandle);
+ row.Set_category(categoryName);
+ row.Set_level(l->level);
+
+ WRT_DB_INSERT(insert, PowderLevels, &WrtDatabase::interface())
+ insert->Values(row);
+ powderID = insert->Execute();
+ }
+
+ FOREACH(c, l->context)
+ {
+ PowderLevelContexts::Row row;
+ row.Set_levelId(powderID);
+ row.Set_context(*c);
+
+ DO_INSERT(row, PowderLevelContexts)
+ }
+ }
+ }
+}
+
+void WidgetDAO::registerLaunchCertificates(DbWidgetHandle widgetHandle,
+ 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_encoded_chain(DPL::FromASCIIString(*certChain));
+
+ DO_INSERT(row, WidgetCertificate);
+ }
+}
+
+void WidgetDAO::registerWidgetSettings(DbWidgetHandle widgetHandle,
+ const WidgetRegisterInfo ®Info)
+{
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+
+ const ConfigParserData& widgetConfigurationInfo = regInfo.configInfo;
+
+ FOREACH(pWidgetSetting, widgetConfigurationInfo.settingsList)
+ {
+ SettginsList::Row row;
+ row.Set_appId(widgetHandle);
+ row.Set_settingName(pWidgetSetting->m_name);
+ row.Set_settingValue(pWidgetSetting->m_value);
+
+ DO_INSERT(row, SettginsList)
+ }
+}
+
+void WidgetDAO::registerAppService(DbWidgetHandle widgetHandle,
+ const WidgetRegisterInfo ®Info)
+{
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ const ConfigParserData& widgetConfigurationInfo = regInfo.configInfo;
+
+ FOREACH(ASIt, widgetConfigurationInfo.appServiceList)
+ {
+ ApplicationServiceInfo::Row row;
+ row.Set_app_id(widgetHandle);
+ row.Set_src(ASIt->m_src);
+ row.Set_operation(ASIt->m_operation);
+ row.Set_scheme(ASIt->m_scheme);
+ row.Set_mime(ASIt->m_mime);
+
+ DO_INSERT(row, ApplicationServiceInfo)
+ }
+}
+
+#undef DO_INSERT
+
+void WidgetDAO::unregisterWidget(DbWidgetHandle widgetHandle)
+{
+ LogDebug("Unregistering widget from DB. Handle: " << widgetHandle);
+ SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
+ {
+ DPL::DB::ORM::wrt::ScopedTransaction transaction(&WrtDatabase::interface());
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+
+ CHECK_WIDGET_EXISTENCE(transaction, widgetHandle)
+
+ // Delete from table Widget Info
+ {
+ WRT_DB_DELETE(del, WidgetInfo, &WrtDatabase::interface())
+ del->Where(Equals<WidgetInfo::app_id>(widgetHandle));
+ del->Execute();
+ }
+
+ // Deleting in other tables is done via "delete cascade" in SQL
+
+ transaction.Commit();
+ }
+ SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to unregister widget")
+}
+
+#undef SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
+#undef SQL_CONNECTION_EXCEPTION_HANDLER_END
+#undef CHECK_WIDGET_EXISTENCE
+
+} // namespace WrtDB
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <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>
+
+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 {
+
+WidgetInfoRow getWidgetInfoRow(int widgetHandle)
+{
+ LogDebug("Getting WidgetInfo row. Handle: " << widgetHandle);
+ SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
+ {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ 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")
+}
+
+} // namespace
+
+
+IWacSecurity::~IWacSecurity()
+{
+}
+
+WidgetDAOReadOnly::WidgetDAOReadOnly(DbWidgetHandle widgetHandle) :
+ m_widgetHandle(widgetHandle)
+{
+}
+
+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
+ {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ 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")
+
+ ThrowMsg(WidgetDAOReadOnly::Exception::WidgetNotExist,
+ "Failed to get widget by guid");
+}
+
+DbWidgetHandle WidgetDAOReadOnly::getHandle(const DPL::String pkgName)
+{
+ LogDebug("Getting WidgetHandle by Package Name [" << pkgName << "]");
+
+ SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
+ {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ WRT_DB_SELECT(select, WidgetInfo, &WrtDatabase::interface())
+ select->Where(Equals<WidgetInfo::pkgname>(pkgName));
+ 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")
+
+ ThrowMsg(WidgetDAOReadOnly::Exception::WidgetNotExist,
+ "Failed to get widget by package name");
+}
+
+PropertyDAOReadOnly::WidgetPropertyKeyList
+WidgetDAOReadOnly::getPropertyKeyList() const
+{
+ return PropertyDAOReadOnly::GetPropertyKeyList(m_widgetHandle);
+}
+
+PropertyDAOReadOnly::WidgetPreferenceList
+WidgetDAOReadOnly::getPropertyList() const
+{
+ return PropertyDAOReadOnly::GetPropertyList(m_widgetHandle);
+}
+
+PropertyDAOReadOnly::WidgetPropertyValue WidgetDAOReadOnly::getPropertyValue(
+ const PropertyDAOReadOnly::WidgetPropertyKey &key) const
+{
+ return PropertyDAOReadOnly::GetPropertyValue(m_widgetHandle, key);
+}
+
+DPL::OptionalInt WidgetDAOReadOnly::checkPropertyReadFlag(
+ const PropertyDAOReadOnly::WidgetPropertyKey &key) const
+{
+ return PropertyDAOReadOnly::CheckPropertyReadFlag(m_widgetHandle, key);
+}
+
+DPL::String WidgetDAOReadOnly::getPath() const
+{
+ DPL::String path = DPL::FromUTF8String(
+ GlobalConfig::GetUserInstalledWidgetPath());
+ DPL::String srcPath = DPL::FromUTF8String(GlobalConfig::GetWidgetSrcPath());
+
+ bool isFactoryWidget = isFactory();
+
+ if (isFactoryWidget) {
+ WidgetGUID widgetGUID = getGUID();
+ if (!widgetGUID) {
+ Throw(WidgetDAOReadOnly::Exception::GUIDisNull);
+ }
+ path += L"/" + *widgetGUID + L"/";
+ } else {
+ // if the widget is a "downloaded widget",
+ // use unique package name.
+ DPL::OStringStream strAppId;
+ strAppId << m_widgetHandle;
+ DPL::OptionalString pkgname = getPkgname();
+ path += L"/" + *pkgname + L"/";
+ 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
+ {
+ DPL::DB::ORM::wrt::ScopedTransaction transaction(&WrtDatabase::interface());
+ CHECK_WIDGET_EXISTENCE(transaction, m_widgetHandle)
+
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ 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
+ {
+ DPL::DB::ORM::wrt::ScopedTransaction transaction(&WrtDatabase::interface());
+ CHECK_WIDGET_EXISTENCE(transaction, m_widgetHandle)
+
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ WRT_DB_SELECT(select, DPL::DB::ORM::wrt::WidgetFeature, &WrtDatabase::interface())
+ select->Where(Equals<DPL::DB::ORM::wrt::WidgetFeature::app_id>(m_widgetHandle));
+
+ DbWidgetFeatureSet resultSet;
+ typedef std::list<DPL::DB::ORM::wrt::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.required = i->Get_required();
+ feature.params = getFeatureParams(i->Get_widget_feature_id());
+ 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")
+}
+
+WidgetParamMap WidgetDAOReadOnly::getFeatureParams(int id)
+{
+ WidgetFeatureId widgetFeatureId(id);
+ LogDebug("Getting feature Params. featureId: " << widgetFeatureId);
+ SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
+ {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ WRT_DB_SELECT(select, DPL::DB::ORM::wrt::FeatureParam, &WrtDatabase::interface())
+ select->Where(Equals<DPL::DB::ORM::wrt::FeatureParam::widget_feature_id>(
+ widgetFeatureId));
+
+ WidgetParamMap resultMap;
+ typedef std::list<DPL::DB::ORM::wrt::FeatureParam::Row> RowList;
+ RowList list = select->GetRowList();
+
+ FOREACH(i, list)
+ resultMap.insert(std::make_pair(i->Get_name(), i->Get_value()));
+
+ return resultMap;
+ }
+ SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get feature params")
+}
+
+bool WidgetDAOReadOnly::hasFeature(const std::string& featureName) const
+{
+ LogDebug(
+ "Checking if widget has feature: " << featureName << ". Handle: " <<
+ m_widgetHandle);
+ SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
+ {
+ DPL::DB::ORM::wrt::ScopedTransaction transaction(&WrtDatabase::interface());
+ CHECK_WIDGET_EXISTENCE(transaction, m_widgetHandle)
+
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ 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")
+}
+
+HostList WidgetDAOReadOnly::getAccessHostList() const
+{
+ LogDebug("Getting AccessHostList. Handle: " << m_widgetHandle);
+ SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
+ {
+ DPL::DB::ORM::wrt::ScopedTransaction transaction(&WrtDatabase::interface());
+ CHECK_WIDGET_EXISTENCE(transaction, m_widgetHandle)
+
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ WRT_DB_SELECT(select, WidgetAccessHost, &WrtDatabase::interface())
+ select->Where(Equals<WidgetAccessHost::app_id>(m_widgetHandle));
+ std::list<WidgetAccessHost::host::ColumnType> values =
+ select->GetValueList<WidgetAccessHost::host>();
+ HostList ret;
+ FOREACH(it, values)
+ ret.push_back(DPL::ToUTF8String(*it));
+
+ transaction.Commit();
+ return ret;
+ }
+ SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get access host list")
+}
+
+bool WidgetDAOReadOnly::getAccessNetworkMode() const
+{
+ //TODO there is no column access_network
+ //it was removed in "Widget localization overhaul
+ return true;
+}
+
+DbWidgetHandleList WidgetDAOReadOnly::getHandleList()
+{
+ LogDebug("Getting DbWidgetHandle List");
+ SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
+ {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ WRT_DB_SELECT(select, WidgetInfo, &WrtDatabase::interface())
+ return select->GetValueList<WidgetInfo::app_id>();
+ }
+ SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get handle list")
+}
+
+bool WidgetDAOReadOnly::isWidgetInstalled(DbWidgetHandle handle)
+{
+ LogDebug("Checking if widget exist. Handle: " << handle);
+ SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
+ {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ 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(DPL::String pkgName)
+{
+ LogDebug("Checking if widget exist. package name " << pkgName);
+ SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
+ {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ WRT_DB_SELECT(select, WidgetInfo, &WrtDatabase::interface())
+ select->Where(Equals<WidgetInfo::pkgname>(pkgName));
+
+ WidgetInfo::Select::RowList rows = select->GetRowList();
+
+ return !rows.empty();
+ }
+ SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to check if widget exist")
+}
+
+CertificateChainList WidgetDAOReadOnly::getWidgetCertificate() const
+{
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ WRT_DB_SELECT(select, WidgetCertificate, &WrtDatabase::interface())
+ select->Where(Equals<WidgetCertificate::app_id>(m_widgetHandle));
+
+ std::list<DPL::DB::ORM::wrt::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::getPkgname() const
+{
+ WidgetInfoRow row = getWidgetInfoRow(m_widgetHandle);
+ return row.Get_pkgname();
+}
+
+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();
+}
+
+std::string WidgetDAOReadOnly::getShareHref() 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);
+ }
+
+ DPL::Optional<DPL::String> value = rows.front().Get_share_href();
+ std::string ret = "";
+ if (!value.IsNull()) {
+ ret = DPL::ToUTF8String(*value);
+ }
+ return ret;
+ }
+ SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get share HREF")
+}
+
+bool WidgetDAOReadOnly::getBackSupported() const
+{
+ WidgetInfoRow row = getWidgetInfoRow(m_widgetHandle);
+ return row.Get_back_supported();
+}
+
+bool WidgetDAOReadOnly::isRecognized() const
+{
+ WidgetInfoRow row = getWidgetInfoRow(m_widgetHandle);
+ DPL::OptionalInt result = row.Get_recognized();
+ if (result.IsNull()) {
+ return false;
+ }
+ return static_cast<bool>(*result);
+}
+
+bool WidgetDAOReadOnly::isWacSigned() const
+{
+ WidgetInfoRow row = getWidgetInfoRow(m_widgetHandle);
+ DPL::OptionalInt result = row.Get_wac_signed();
+ if (result.IsNull()) {
+ return false;
+ }
+ return static_cast<bool>(*result);
+}
+
+bool WidgetDAOReadOnly::isDistributorSigned() const
+{
+ WidgetInfoRow row = getWidgetInfoRow(m_widgetHandle);
+ DPL::OptionalInt result = row.Get_distributor_signed();
+ if (result.IsNull()) {
+ return false;
+ }
+ return static_cast<bool>(*result);
+}
+
+bool WidgetDAOReadOnly::isTrusted() const
+{
+ // SP-2100
+ // widget with verified distributor signature is trusted
+ return isDistributorSigned();
+}
+
+bool WidgetDAOReadOnly::isTestWidget() const
+{
+ Try {
+ 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 static_cast<bool>(rows.front().Get_test_widget());
+ }
+ Catch(DPL::DB::SqlConnection::Exception::Base){
+ ReThrowMsg(WidgetDAOReadOnly::Exception::DatabaseError,
+ "Failed to check IsTestWidget");
+ }
+}
+
+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; }
+}
+
+bool WidgetDAOReadOnly::isFactory() 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);
+ }
+
+ DPL::OptionalInt ret = rows.front().Get_factory_widget();
+ if (ret.IsNull()) {
+ return false;
+ }
+ return static_cast<bool>(*ret);
+ }
+ SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get isFactory")
+}
+
+time_t WidgetDAOReadOnly::getInstallTime() 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 static_cast<time_t>(*rows.front().Get_install_time());
+ }
+ SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get widdget install time")
+}
+
+WidgetDAOReadOnly::WidgetLocalizedIconList WidgetDAOReadOnly::getLocalizedIconList() const
+{
+ //TODO check widget existance??
+ SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
+ {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ WRT_DB_SELECT(select, WidgetLocalizedIcon, &WrtDatabase::interface())
+ select->Where(Equals<WidgetLocalizedIcon::app_id>(m_widgetHandle));
+
+ std::list<DPL::DB::ORM::wrt::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
+ {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ WRT_DB_SELECT(select, wrt::WidgetIcon, &WrtDatabase::interface())
+ select->Where(Equals<wrt::WidgetIcon::app_id>(m_widgetHandle));
+
+ std::list<DPL::DB::ORM::wrt::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
+ {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ WRT_DB_SELECT(select, WidgetLocalizedStartFile, &WrtDatabase::interface())
+ select->Where(Equals<WidgetLocalizedStartFile::app_id>(
+ m_widgetHandle));
+ select->OrderBy("start_file_id ASC");
+
+ std::list<DPL::DB::ORM::wrt::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
+ {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ WRT_DB_SELECT(select, WidgetStartFile, &WrtDatabase::interface())
+ select->Where(Equals<WidgetStartFile::app_id>(m_widgetHandle));
+ select->OrderBy("start_file_id ASC");
+
+ std::list<DPL::DB::ORM::wrt::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
+ {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ 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;
+}
+
+bool WidgetDAOReadOnly::isDeletable() const
+{
+ return !WidgetDAOReadOnly::isFactory();
+}
+
+WidgetCertificateDataList WidgetDAOReadOnly::getCertificateDataList() const
+{
+ //TODO check widget existance
+ SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
+ {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ 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
+ {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ 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> md5 = it->Get_md5_fingerprint();
+ keys.push_back(md5.IsNull() ? "" : DPL::ToUTF8String(*md5));
+ DPL::Optional<DPL::String> sha1 = it->Get_sha1_fingerprint();
+ keys.push_back(sha1.IsNull() ? "" : DPL::ToUTF8String(*sha1));
+ }
+ 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
+ {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ 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")
+}
+
+ResourceAttributeList WidgetDAOReadOnly::getResourceAttribute(
+ const std::string &resourceId) const
+{
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ WRT_DB_SELECT(select, DPL::DB::ORM::wrt::WidgetFeature, &WrtDatabase::interface())
+ select->Where(And(Equals<DPL::DB::ORM::wrt::WidgetFeature::app_id>(m_widgetHandle),
+ Equals<DPL::DB::ORM::wrt::WidgetFeature::name>(
+ DPL::FromUTF8String(resourceId))));
+
+ std::list<DPL::DB::ORM::wrt::WidgetFeature::Row> list = select->GetRowList();
+ ResourceAttributeList result;
+ if (!list.empty()) {
+ int widgetFeatureId = list.begin()->Get_widget_feature_id();
+ WidgetParamMap map = getFeatureParams(widgetFeatureId);
+
+ FOREACH(i, map)
+ result.push_back(DPL::ToUTF8String(i->first));
+ }
+ return result;
+}
+
+void WidgetDAOReadOnly::getWidgetAccessInfo(
+ WidgetAccessInfoList& outAccessInfoList) const
+{
+ //TODO check widget existance
+ SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
+ {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ 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")
+}
+
+LanguageTagList WidgetDAOReadOnly::getLanguageTags() const
+{
+ //TODO check widget existance
+ SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
+ {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ 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")
+}
+
+LanguageTagList WidgetDAOReadOnly::getIconLanguageTags() const
+{
+ //TODO check widget existance
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ WRT_DB_SELECT(select, WidgetLocalizedIcon, &WrtDatabase::interface())
+ select->Where(Equals<WidgetLocalizedIcon::app_id>(m_widgetHandle));
+ select->Distinct();
+ return select->GetValueList<WidgetLocalizedIcon::widget_locale>();
+}
+
+std::string WidgetDAOReadOnly::getCookieDatabasePath() const
+{
+ using namespace WrtDB::WidgetConfig;
+ std::ostringstream path;
+
+ DPL::OptionalString pkgname = getPkgname();
+
+ path << GetWidgetPersistentStoragePath(*pkgname);
+ path << "/";
+ path << GlobalConfig::GetCookieDatabaseFile();
+
+ return path.str();
+}
+
+std::string WidgetDAOReadOnly::getPrivateLocalStoragePath() const
+{
+ std::ostringstream path;
+ DPL::OptionalString pkgname = getPkgname();
+ path << WidgetConfig::GetWidgetWebLocalStoragePath(*pkgname);
+ path << "/";
+
+ if (isFactory()) {
+ WidgetGUID widgetGUID = getGUID();
+ if (!widgetGUID) {
+ Throw(WidgetDAOReadOnly::Exception::GUIDisNull);
+ }
+ path << DPL::ToUTF8String(*widgetGUID);
+ }
+
+ return path.str();
+}
+
+ChildProtection::Record WidgetDAOReadOnly::getChildProtection() const
+{
+ WidgetInfoRow row = getWidgetInfoRow(m_widgetHandle);
+ return ChildProtection::Record(row.Get_child_protection());
+}
+
+Powder::Description WidgetDAOReadOnly::getPowderDescription() const
+{
+ //TODO check widget existance
+ SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
+ {
+ using namespace Powder;
+ Description description;
+
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ WRT_DB_SELECT(select, PowderLevels, &WrtDatabase::interface())
+ select->Where(Equals<PowderLevels::app_id>(m_widgetHandle));
+ typedef std::list<PowderLevels::Row> RowList;
+ RowList list = select->GetRowList();
+
+ FOREACH(it, list)
+ {
+ Description::CategoryEntry& categoryEntry =
+ description.categories[it->Get_category()];
+ Description::LevelEntry levelEntry(
+ (Description::LevelEnum)it->Get_level());
+
+ WRT_DB_SELECT(selectContexts, PowderLevelContexts, &WrtDatabase::interface())
+ selectContexts->Where(Equals<PowderLevelContexts::levelId>(
+ it->Get_id()));
+ typedef std::list<PowderLevelContexts::Row> ContextsRowList;
+ ContextsRowList contextsList = selectContexts->GetRowList();
+
+ FOREACH(c, contextsList)
+ levelEntry.context.insert(c->Get_context());
+
+ categoryEntry.levels.push_back(levelEntry);
+ }
+ return description;
+ }
+ SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get powder description")
+}
+
+void WidgetDAOReadOnly::getWidgetSettings(
+ WidgetSettings& outWidgetSettings) const
+{
+ //TODO check widget existance
+ SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
+ {
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ WRT_DB_SELECT(select, SettginsList, &WrtDatabase::interface())
+ select->Where(Equals<SettginsList::appId>(m_widgetHandle));
+
+ SettginsList::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::getAppServiceList(
+ WidgetApplicationServiceList& outAppServiceList) const
+{
+ LogDebug("Getting getAppServiceList. Handle: " << m_widgetHandle);
+ SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
+ {
+ DPL::DB::ORM::wrt::ScopedTransaction transaction(&WrtDatabase::interface());
+ CHECK_WIDGET_EXISTENCE(transaction, m_widgetHandle)
+
+ using namespace DPL::DB::ORM;
+ using namespace DPL::DB::ORM::wrt;
+ WRT_DB_SELECT(select, ApplicationServiceInfo, &WrtDatabase::interface())
+ select->Where(Equals<ApplicationServiceInfo::app_id>(m_widgetHandle));
+
+ ApplicationServiceInfo::Select::RowList rows = select->GetRowList();
+
+ if (rows.empty()) {
+ LogDebug("Application Service list is empty. Handle: " <<
+ m_widgetHandle);
+ }
+
+ FOREACH(it, rows) {
+ WidgetApplicationService ret;
+ ret.src = it->Get_src();
+ ret.operation = it->Get_operation();
+ ret.scheme = it->Get_scheme();
+ ret.mime = it->Get_mime();
+ outAppServiceList.push_back(ret);
+ }
+
+ transaction.Commit();
+ }
+ SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get access host list")
+}
+
+#undef SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
+#undef SQL_CONNECTION_EXCEPTION_HANDLER_END
+#undef CHECK_WIDGET_EXISTENCE
+
+} // namespace WrtDB
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 attachToThread();
+ static void detachFromThread();
+ static DPL::DB::ThreadDatabaseSupport& interface();
+ static bool CheckTableExist(const char *name);
+
+ private:
+ static DPL::DB::ThreadDatabaseSupport m_interface;
+};
+
+}
+
+#endif /* WRTDATABASE_H */
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_SRC_CONFIGURATION_COMMON_DAO_TYPES_H_
+#define WRT_SRC_CONFIGURATION_COMMON_DAO_TYPES_H_
+
+#include <set>
+#include <string>
+#include <map>
+#include <vector>
+#include <list>
+#include <dpl/optional_typedefs.h>
+#include <dpl/shared_ptr.h>
+
+namespace WrtDB {
+namespace Powder {
+
+typedef std::set<DPL::String> StringSet;
+//! Widget description
+struct Description
+{
+ //!Content level
+ typedef enum
+ {
+ Level0 = 0,
+ Level1,
+ Level2,
+ Level3,
+ Level4,
+ Level5,
+ LevelUnknown
+ } LevelEnum;
+ struct LevelEntry
+ {
+ LevelEnum level; //!< content level
+
+ typedef StringSet Context;
+
+ //! POWDER context
+ //! xa This material appears in an artistic context
+ //! xb This material appears in an educational context
+ //! xc This material appears in a medical context
+ //! xd This material appears in a sports context
+ //! xe This material appears in a violent context
+ Context context;
+ explicit LevelEntry(LevelEnum level = LevelUnknown);
+ //! Function checks if context is valid
+ //! \param[in] level POWDER content level
+ //! \param[in] context POWDER context
+ bool isContextValid(LevelEnum level,
+ const DPL::OptionalString& context) const;
+ };
+
+ struct CategoryEntry
+ {
+ //! Levels entries for POWDER description
+ typedef std::vector <LevelEntry> LevelsContainer;
+ LevelsContainer levels;
+ //! Function checks if context is valid
+ //! \param[out] reason set if context invalid
+ //! \param[in] level POWDER content level
+ //! \param[in] context POWDER context
+ bool isCategoryValid(LevelEntry& reason,
+ LevelEnum level,
+ const DPL::OptionalString& context) const;
+ };
+
+ //! POWDER Category -> Category entry map for Widget
+ //!
+ //! nu Nudity
+ //! se Sex
+ //! vi Violence
+ //! la Potentially offensive language
+ //! dr Drug use
+ //! ga Gambling
+ //! ha Hate or harmful activities
+ //! ug Use of user-generated content
+ typedef std::map<DPL::String, CategoryEntry> CategoryEntries;
+
+ CategoryEntries categories;
+
+ //! Age rating for widget
+ //! If Null not set
+ DPL::OptionalInt ageRating;
+};
+} // namespace Powder
+
+namespace ChildProtection {
+
+//! Blacklist with forbidden URLs
+//! It should be stored in WidgetDAO
+typedef std::vector<DPL::String> BlackList;
+
+//! Widget Child protection record
+//! Record should be stored in WingetDAO
+struct Record
+{
+ //! Child protection enabled
+ bool enabled;
+ explicit Record(bool enabled) :
+ enabled(enabled)
+ {
+ }
+};
+
+//! Powder processing
+struct PowderRules
+{
+ //! Rule set by parent about forbidden category
+ //! Powder category
+ //! nu Nudity
+ //! se Sex
+ //! vi Violence
+ //! la Potentially offensive language
+ //! dr Drug use
+ //! ga Gambling
+ //! ha Hate or harmful activities
+ //! ug Use of user-generated content
+ //! Powder context
+ //! xa This material appears in an artistic conteaxt
+ //! xb This material appears in an educational context
+ //! xc This material appears in a medical context
+ //! xd This material appears in a sports context
+ //! xe This material appears in a violent context
+ struct CategoryRule
+ {
+ DPL::String category;
+ Powder::Description::LevelEnum level;
+ DPL::OptionalString context;
+ explicit CategoryRule(const DPL::String& category = DPL::String(),
+ Powder::Description::LevelEnum level =
+ Powder::Description::LevelUnknown,
+ const DPL::OptionalString& context = DPL::OptionalString());
+ };
+
+ struct PowderResult
+ {
+ //! Reasoning outcome: part of POWDER description used to invalidate
+ Powder::Description::LevelEntry invalidDescription;
+ //! Reasoning outcome: rule set by parent not full filed by description
+ CategoryRule invalidRule;
+
+ //! Reasoning outcome: type of invalidity
+ enum InvalidReason
+ {
+ InvalidRule, //!< One of rules was not fulfilled
+ InvalidAge, //!< Age is invalid
+ AgeRatingNotSet, //!< Age rating for widget is not set
+ Valid //!< Description valid
+ };
+ InvalidReason reason;
+ explicit PowderResult(InvalidReason reason = Valid,
+ const Powder::Description::LevelEntry& invalidDescription =
+ Powder::Description::LevelEntry(),
+ const CategoryRule& invalidRule = CategoryRule());
+ };
+
+ typedef std::pair<bool, PowderResult> ResultPair;
+
+ //! Function checks if rule is fulfilled by description
+ //! \param[in] rule checked rule
+ //! \param[in] description
+ //! \retval true rule is valid
+ //! \retval false rule is invalid
+ ResultPair isRuleValidForDescription(const CategoryRule& rule,
+ const Powder::Description& description) const;
+ //! Function checks if age limit is fulfilled by description
+ //! \param[in] description
+ //! \retval true age is valid
+ //! \retval false age is invalid
+ ResultPair isAgeValidForDescription(
+ const Powder::Description& description) const;
+
+ //! It is the maximum age rating valid for child
+ //! Uniform age is stored in WidgetDAO
+ DPL::OptionalInt ageLimit;
+
+ //! Set to true if age rating is required
+ //! If ageLimit is not set value is ignored
+ bool isAgeRatingRequired;
+
+ //! Set of rules configured by parent
+ //! Rules are stored in WidgetDAO and are uniform for all widgets
+ typedef std::vector<CategoryRule> RulesContainer;
+ RulesContainer rules;
+
+ //! Function check if Widget description is valid for ChildProtection
+ //! configuration
+ //! \param description widget description
+ //! \retval true widget is valid
+ //! \retval false widget is invalid
+ ResultPair isDescriptionValid(const Powder::Description& description)
+ const;
+
+ PowderRules() :
+ isAgeRatingRequired(false)
+ {
+ }
+};
+} // namespace ChildProtection
+
+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;
+ std::string m_featuresInstallURI;
+ std::string m_featuresKeyCN;
+ std::string m_featuresRootCN;
+ std::string m_featuresRootFingerprint;
+
+ FeatureContainer m_featureContainer;
+};
+
+class PluginObjectsDAO
+{
+ public:
+ typedef std::set<std::string> Objects;
+ typedef DPL::SharedPtr<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;
+
+/**
+ * @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;
+
+typedef std::list<DPL::String> WindowModeList;
+
+/**
+ * @brief Widget configuration parameter key
+ */
+typedef DPL::String WidgetParamKey;
+
+/**
+ * @brief Widget configuration parameter value
+ */
+typedef DPL::String WidgetParamValue;
+
+/**
+ * @brief A map of widget configuration parameters.
+ *
+ * Widget configuration parameters are read from database and are stored
+ * along with feature that they describe.
+ */
+typedef std::multimap<WidgetParamKey, WidgetParamValue> WidgetParamMap;
+
+/**
+ * @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 required; /// Whether feature is required
+ DbPluginHandle pluginId; /// Plugin id that implement this feature
+ WidgetParamMap params; /// Widget's params
+
+ DbWidgetFeature() :
+ required(false),
+ 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.required == featureB.required &&
+ 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;
+
+/**
+ * @brief Widget specific type
+ *
+ * Widget type describes belowed in WAC, TIZEN WebApp
+ */
+enum AppType
+{
+ APP_TYPE_UNKNOWN = 0, // unknown
+ APP_TYPE_WAC10, // WAC 1.0
+ APP_TYPE_WAC20, // WAC 2.0
+ APP_TYPE_TIZENWEBAPP, // Tizen webapp
+};
+
+class WidgetType
+{
+ public:
+ WidgetType()
+ :appType(APP_TYPE_UNKNOWN)
+ {
+ }
+ WidgetType(const AppType type)
+ :appType(type)
+ {
+ }
+ 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_WAC10)
+ X(APP_TYPE_WAC20)
+ X(APP_TYPE_TIZENWEBAPP)
+#undef X
+ default:
+ return "UNKNOWN";
+ }
+ }
+
+ AppType appType;
+};
+
+} // namespace WrtDB
+
+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 Application Service
+ *
+ * Application sercvice describes details of behaviour
+ * when widget receives aul bundle data.
+ */
+struct WidgetApplicationService
+{
+ public:
+ DPL::String src; /* start uri */
+ DPL::String operation; /* service name */
+ DPL::String scheme; /* scheme type*/
+ DPL::String mime; /* mime type */
+
+ bool operator== (const WidgetApplicationService& other) const
+ {
+ return src == other.src &&
+ operation == other.operation &&
+ scheme == other.scheme &&
+ mime == other.mime;
+ }
+};
+
+typedef std::list<WidgetApplicationService> WidgetApplicationServiceList;
+#endif /* WRT_SRC_CONFIGURATION_COMMON_DAO_TYPES_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <ctype.h>
+
+namespace WrtDB {
+
+void NormalizeString(DPL::OptionalString& txt);
+void NormalizeString(DPL::String& str);
+DPL::String GetSingleAttributeValue(const DPL::String value);
+
+class WidgetConfigurationManager;
+
+class ConfigParserData
+{
+ public:
+ struct Param
+ {
+ Param(const DPL::String& name) : name(name)
+ {
+ }
+ DPL::String name;
+ DPL::String value;
+ bool operator==(const Param&) const;
+ bool operator!=(const Param&) const;
+ bool operator >(const Param&) const;
+ bool operator>=(const Param&) const;
+ bool operator <(const Param&) const;
+ bool operator<=(const Param&) const;
+ };
+ typedef std::set<Param> ParamsList;
+
+ struct Feature
+ {
+ Feature(const DPL::String& name,
+ bool required = true) : name(name),
+ required(required)
+ {
+ }
+ DPL::String name;
+ bool required;
+ ParamsList paramsList;
+
+ 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 Icon
+ {
+ Icon(const DPL::String& src) : src(src)
+ {
+ }
+ DPL::String src;
+ DPL::OptionalInt width;
+ DPL::OptionalInt height;
+ 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 ServiceInfo
+ {
+ ServiceInfo(
+ const DPL::String& src,
+ const DPL::String& operation,
+ const DPL::String& scheme,
+ const DPL::String& mime) :
+ m_src(src),
+ m_operation(operation),
+ m_scheme(scheme),
+ m_mime(mime)
+ {
+ }
+ DPL::String m_src;
+ DPL::String m_operation;
+ DPL::String m_scheme;
+ DPL::String m_mime;
+
+ bool operator==(const ServiceInfo&) const;
+ bool operator!=(const ServiceInfo&) const;
+ };
+ typedef std::list<ServiceInfo> ServiceInfoList;
+
+ StringsList nameSpaces;
+
+ LocalizedDataSet localizedDataSet;
+
+ DPL::OptionalString authorName;
+ DPL::OptionalString authorHref;
+ DPL::OptionalString authorEmail;
+
+ FeaturesList featuresList;
+
+ 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::OptionalFloat minVersionRequired;
+ DPL::OptionalInt minVersionRequiredFound;
+ StringsList powderDescriptionLinks;
+
+ bool backSupported;
+ bool accessNetwork;
+
+ // Unlocalized data, to be processed by WidgetConfigurationManager
+ bool startFileEncountered;
+ DPL::OptionalString startFile;
+ DPL::OptionalString startFileEncoding;
+ DPL::OptionalString startFileContentType;
+ IconsList iconsList;
+
+ // pakcage name determined by operator for TIZEN webapp
+ DPL::OptionalString pkgname;
+ //Application service model list
+ ServiceInfoList appServiceList;
+
+ ConfigParserData() :
+ flashNeeded(false),
+ minVersionRequired(1.0),
+ minVersionRequiredFound(),
+ backSupported(false),
+ accessNetwork(false),
+ startFileEncountered(false)
+ {
+ }
+};
+
+} // namespace WrtDB
+
+#endif //CONFIG_PARSER_DATA_H_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 {
+
+class FeatureDAOReadOnly
+{
+ public:
+ /**
+ * Exception classes
+ */
+ class Exception
+ {
+ public:
+ DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+ DECLARE_EXCEPTION_TYPE(Base, DatabaseError)
+ DECLARE_EXCEPTION_TYPE(Base, FeatureNotExist)
+ };
+
+ typedef std::set<std::string> DeviceCapabilitiesList;
+
+ 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;
+ std::string GetInstallURI() const;
+ std::string GetKeyCn() const;
+ std::string GetRootKey() const;
+ std::string GetRootKeyFingerprint() const;
+ FeatureHandle GetFeatureHandle() const;
+ std::string GetLibraryPath() const;
+ std::string GetLibraryName() const;
+ DeviceCapabilitiesList GetDeviceCapabilities() const;
+ DbPluginHandle GetPluginHandle() const;
+
+ protected:
+ FeatureHandle m_featureHandle;
+};
+
+} // namespace WrtDB
+
+#endif /* WRT_SRC_CONFIGURATION_FEATURE_DAO_READ_ONLY_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <dpl/shared_ptr.h>
+#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 DPL::SharedPtr<FeatureHandleList> FeatureHandleListPtr;
+
+typedef int FeatureSetHandle;
+typedef std::list<FeatureSetHandle> FeatureSetHandleList;
+
+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)
+ {
+ }
+};
+
+typedef DPL::SharedPtr<FeatureModel> FeatureModelPtr;
+
+} // namespace WrtDB
+
+#endif // FEATURE_MODEL_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 origin widget interface database path
+ */
+inline const char* GetWrtWidgetInterfaceDatabaseFilePath()
+{
+ return "/usr/share/wrt-plugins-common/widget_interface_db.sql";
+}
+
+/**
+ * WRT device plugin path
+ */
+inline const char* GetDevicePluginPath()
+{
+ return "/usr/lib/wrt-plugins";
+}
+
+/**
+ * WRT factory widgets that are loaded by default
+ */
+inline const char* GetFactoryInstalledWidgetPath()
+{
+ return "/opt/apps/widget/system";
+}
+
+/**
+ * WRT widgets that are downloaded and installed by user
+ */
+inline const char* GetUserInstalledWidgetPath()
+{
+ return "/opt/apps";
+}
+
+/**
+ * WRT widgets that are downloaded and installed by user
+ */
+inline const char* GetWidgetSrcPath()
+{
+ return "res/src";
+}
+
+/**
+ * Directory for WebKit local storage files
+ */
+inline const char* GetPublicVirtualRootPath()
+{
+ return "/opt/apps/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/apps/widget/tests";
+}
+
+/**
+ * widgets exec path
+ */
+inline const char* GetUserWidgetExecPath()
+{
+ return "bin";
+}
+
+/**
+ * widgets private data path
+ */
+inline const char* GetWidgetPrivateStoragePath()
+{
+ return "data";
+}
+
+
+/**
+ * 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";
+}
+
+/**
+ * widgets desktop icon path
+ */
+inline const char* GetUserWidgetDesktopIconPath()
+{
+ return "res/icons/default/small";
+}
+
+/**
+ * widgets default icon file
+ */
+inline const char* GetUserWidgetDefaultIconFile()
+{
+ return "/usr/share/wrt-engine/wrt_widget_default_icon.png";
+}
+
+/**
+ * WRT downloaded widgets
+ */
+// KW inline const char* GetDownloadedWidgetPath()
+// KW {
+// KW return "/opt/apps/widget/test-widgets";
+// KW }
+
+inline const char* GetSignatureXmlSchema()
+{
+ //TODO please rename, this filename is not descriptive enough
+ return "/usr/share/wrt-engine/schema.xsd";
+}
+
+inline const char* GetWAC20TestRootCAFilePath()
+{
+ return "/usr/share/wrt-engine/WAC2.0TestRootCA.cert";
+}
+
+/**
+ * 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";
+}
+
+/**
+ * WRT device plugins installation required
+ * File which indicate that new plugins
+ * are available and should be installed
+ */
+inline const char* GetPluginInstallInitializerName()
+{
+ return "/opt/apps/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/.vcore.db";
+}
+bool IsOCSPEnabled();
+bool IsCRLEnabled();
+
+/**
+ * widgets cookie database file name
+ */
+inline const char* GetCookieDatabaseFile()
+{
+ return ".cookie.db";
+}
+
+/**
+ * widget interface database file name
+ */
+inline const char* GetWidgetInterfaceDatabaseFile()
+{
+ return ".widget_interface.db";
+}
+
+inline const char* GetTmpDirPath()
+{
+ return "/tmp";
+}
+} // namespace GlobalConfig
+} // namespace WrtDB
+
+#endif // GLOBAL_CONFIG_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_dao_read_only.h
+ * @author Pawel Sikorski (p.sikorski@samsung.com)
+ * @version 1.0
+ * @brief This file contains the declaration of global dao
+ */
+
+#ifndef WRT_SRC_CONFIGURATION_GLOBAL_DAO_READ_ONLY_H_
+#define WRT_SRC_CONFIGURATION_GLOBAL_DAO_READ_ONLY_H_
+
+#include <list>
+#include <set>
+#include <string>
+
+#include <dpl/string.h>
+#include <dpl/exception.h>
+
+#include <dpl/wrt-dao-ro/common_dao_types.h>
+
+namespace WrtDB {
+
+typedef std::list<DPL::String> WidgetPackageList;
+typedef std::set<DPL::String> DeviceCapabilitySet;
+
+//#ifdef USE_BROWSER_SETTING
+//typedef DPL::DB::ORM::wrt::UserAgents::key_value::ColumnType UserAgent;
+//#endif //USE_BROWSER_SETTING
+
+class GlobalDAOReadOnly
+{
+ public:
+ /**
+ * GlobalDAOReadOnly Exception classes
+ */
+ class Exception
+ {
+ public:
+ DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+ DECLARE_EXCEPTION_TYPE(Base, DatabaseError)
+ };
+
+ public:
+ /**
+ * Retrieve Parental mode status
+ *
+ * @return true for Parental Mode on, false for Parental Mode off
+ */
+ static bool GetParentalMode();
+
+ /**
+ * Retrieve Parental mode maximal allowed age
+ *
+ * @return NULL if allowed age not set, else pointer value is allowed age
+ */
+ static DPL::OptionalInt GetParentalAllowedAge();
+ /**
+ * Retrieve Parental mode maximal allowed age
+ *
+ * @return NULL if allowed age not set, else pointer value is allowed age
+ */
+
+ static bool IsValidSubTag(const DPL::String& tag, int type);
+
+ static bool IsPowderRulePresent(
+ const ChildProtection::PowderRules::CategoryRule& rule);
+
+ static ChildProtection::PowderRules GetPowderRules();
+
+ static ChildProtection::BlackList GetAdultBlackList();
+
+ static bool IsElementOnAdultBlackList(const DPL::String &url);
+
+ /**
+ * Retrieve list of deffered widget packages to be installed
+ *
+ * @return Widget package list
+ */
+ static WidgetPackageList GetDefferedWidgetPackageInstallationList();
+
+ static bool GetDeveloperMode();
+
+ static bool GetSecureByDefault();
+
+ static bool getComplianceMode();
+
+ static std::string getComplianceFakeImei();
+
+ static std::string getComplianceFakeMeid();
+
+ static WidgetAccessInfoList GetWhiteURIList();
+
+ enum NetworkAccessMode
+ {
+ NEVER_CONNECT,
+ ALWAYS_ASK,
+ CONNECT_AUTOMATICALLY
+ };
+
+ /**
+ * This method returns network access mode for home network.
+ *
+ * @return Access mode for home network.
+ */
+ static NetworkAccessMode GetHomeNetworkDataUsage();
+
+ /**
+ * This method returns network access mode while roaming is enabled.
+ *
+ * @return Access mode for home network.
+ */
+ static NetworkAccessMode GetRoamingDataUsage();
+
+ static DPL::String GetUserAgentValue(const DPL::String &key);
+
+ /**
+ * This method returns set of device capabilities used by apifeature.
+ */
+ static DeviceCapabilitySet GetDeviceCapability(
+ const DPL::String &apifeature);
+
+
+ /**
+ * This method gets Autofill for Webkit
+ */
+ struct AutoSaveData
+ {
+ DPL::String userId;
+ DPL::String passwd;
+ };
+
+ static DPL::Optional<AutoSaveData> GetAutoSaveIdPasswd(
+ const DPL::String &url);
+
+ protected:
+ GlobalDAOReadOnly()
+ {
+ }
+};
+
+} // namespace WrtDB
+
+#endif // WRT_SRC_CONFIGURATION_GLOBAL_DAO_READ_ONLY_H_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <dpl/exception.h>
+#include <dpl/shared_ptr.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 DPL::SharedPtr<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 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 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;
+ std::string getInstallURI() const;
+ std::string getKeyCn() const;
+ std::string getRootKey() const;
+ std::string getRootKeyFingerprint() const;
+ PluginHandleSetPtr getLibraryDependencies() const;
+
+ private:
+ DbPluginHandle m_pluginHandle;
+
+ void checkInstallationCompleted();
+};
+
+} // namespace WrtDB
+
+#endif /* WRT_SRC_CONFIGURATION_PLUGIN_DAO_READ_ONLY_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 app_id;
+ 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)
+};
+
+/* This method checks read only flag for given property
+ */
+DPL::OptionalInt CheckPropertyReadFlag(DbWidgetHandle widgetHandle,
+ const WidgetPropertyKey &key);
+
+/* This method gets widget property key list
+ */
+WidgetPropertyKeyList GetPropertyKeyList(DbWidgetHandle widgetHandle);
+
+/* This method gets widget property list
+ */
+WidgetPreferenceList GetPropertyList(DbWidgetHandle widgetHandle);
+
+/* This method get widget property value
+ */
+WidgetPropertyValue GetPropertyValue(DbWidgetHandle widgetHandle,
+ const WidgetPropertyKey &key);
+
+} // PropertyDAOReadOnly
+} // namespace WrtDB
+
+#endif /* PROPERTY_DAO_READ_ONLY_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 pkgName)
+{
+ return PathBuilder()
+ .Append(GlobalConfig::GetUserInstalledWidgetPath())
+ .Append(DPL::ToUTF8String(pkgName))
+ .GetFullPath();
+}
+
+inline std::string GetWidgetWebLocalStoragePath(DPL::String pkgName)
+{
+ return PathBuilder(GetWidgetBasePath(pkgName))
+ .Append(GlobalConfig::GetWidgetLocalStoragePath())
+ .GetFullPath();
+}
+
+inline std::string GetWidgetPersistentStoragePath(DPL::String pkgName)
+{
+ return PathBuilder(GetWidgetBasePath(pkgName))
+ .Append(GlobalConfig::GetWidgetPrivateStoragePath())
+ .GetFullPath();
+}
+
+inline std::string GetWidgetTemporaryStoragePath(DPL::String pkgName)
+{
+ return PathBuilder()
+ .Append(GlobalConfig::GetTmpDirPath())
+ .Append(DPL::ToUTF8String(pkgName))
+ .GetFullPath();
+}
+
+inline std::string GetWidgetDesktopFilePath(DPL::String pkgName)
+{
+ return PathBuilder()
+ .Append(GlobalConfig::GetUserWidgetDesktopPath())
+ .Append(DPL::ToUTF8String(pkgName))
+ .Concat(".desktop")
+ .GetFullPath();
+}
+} // namespace WidgetConfig
+} // namespace WrtDB
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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/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 {
+
+/**
+ * Widget's signature enum.
+ * This enumerates signature type of widget.
+ */
+enum WidgetSignatureType
+{
+ SIGNATURE_TYPE_CARRIER = 0,
+ SIGNATURE_TYPE_IDENTIFIED,
+ SIGNATURE_TYPE_UNIDENTIFIED
+};
+
+typedef std::list<DPL::String> StringList;
+
+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, 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;
+
+/**
+ * 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;
+ };
+
+ enum SecurityDomain
+ {
+ Untrusted,
+ Trusted,
+ Operator,
+ None
+ };
+
+ //Constructor
+ WidgetRegisterInfo() :
+ type(APP_TYPE_UNKNOWN),
+ signatureType(SIGNATURE_TYPE_UNIDENTIFIED),
+ isFactoryWidget(0),
+ isTestWidget(0),
+ configInfo()
+ {
+ }
+
+ WidgetType type;
+ DPL::OptionalString guid;
+ DPL::OptionalString version;
+ std::string shareHref;
+ std::string baseFolder;
+ WidgetSignatureType signatureType;
+ int isFactoryWidget;
+ int isTestWidget;
+ ConfigParserData configInfo;
+ Powder::Description powderDescription;
+ LocalizationData localizationData;
+ DPL::OptionalString pkgname;
+ time_t installedTime;
+};
+
+typedef std::list<std::string> CertificateChainList;
+class IWacSecurity
+{
+ public:
+ virtual ~IWacSecurity();
+
+ virtual const WidgetCertificateDataList& getCertificateList() const = 0;
+
+ virtual bool isRecognized() const = 0;
+
+ virtual bool isDistributorSigned() const = 0;
+
+ virtual bool isWacSigned() const = 0;
+
+ virtual void getCertificateChainList(CertificateChainList& list) const = 0;
+};
+
+/**
+ * WidgetAuthorInfo.
+ * Structure to hold the information of widget's author.
+ */
+struct WidgetAuthorInfo
+{
+ DPL::OptionalString name;
+ DPL::OptionalString email;
+ DPL::OptionalString href;
+};
+
+/**
+ * Widget update policy
+ */
+enum WidgetUpdatePolicy
+{
+ WIDGET_UPDATE_MONTHLY = 0, //< monthly update
+ WIDGET_UPDATE_WEEKLY, //< weekly update
+ WIDGET_UPDATE_DAILY, //< daily update
+ WIDGET_UPDATE_STARTUP, //< update when cell phone boots
+ WIDGET_UPDATE_NEVER //< never update
+};
+
+typedef std::list <std::string> WidgetCertificateCNList;
+typedef std::list<DPL::String> LanguageTagList;
+typedef std::list<std::string> HostList;
+typedef std::list<std::string> FingerPrintList;
+typedef std::list<std::string> ResourceAttributeList;
+
+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);
+
+ /**
+ * 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 pkgName);
+
+ /**
+ * 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.
+ */
+ 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 Package name of the widget.
+ *
+ * @return pkgname
+ * @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 getPkgname() 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;
+
+ /**
+ * WAC 2.0 extension
+ * @return recognized status
+ */
+ bool isRecognized() const;
+
+ /**
+ * WAC 2.0 extension
+ * @return
+ */
+ bool isWacSigned() const;
+
+ /**
+ * WAC 2.0 extension
+ * @return
+ */
+ bool isDistributorSigned() const;
+
+ /**
+ * WAC 2.0 extension
+ * @return trusted status
+ */
+ bool isTrusted() const;
+
+ /**
+ * WAC 2.0 extension
+ * @return is WAC test widget
+ */
+ bool isTestWidget() 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 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;
+
+ static WidgetParamMap getFeatureParams(int widgetFeatureId);
+ /**
+ * 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 host list that widget can connect to.
+ *
+ * @return See above comment
+ * @exception WRT_CONF_ERR_EMDB_FAILURE - Fail to query DB table.
+ */
+ HostList getAccessHostList() const;
+
+ /**
+ * This method gets widget's access on network: true or false.
+ *
+ * @return true: widget can access network; false: widget can not access
+ * network.
+ * @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 getAccessNetworkMode() 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' app 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.
+ */
+ static DbWidgetHandleList getHandleList();
+
+ /**
+ * This method removes a widget's information from EmDB.
+ *
+ * @see RegisterWidget()
+ * @param[in] widgetHandle widget's app id
+ * @return true if succeed, false if fail.
+ */
+ static void unregisterWidget(DbWidgetHandle widgetHandle);
+
+ /**
+ * 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' share href.
+ *
+ * @return widget's share href
+ */
+ std::string getShareHref() const;
+
+ /**
+ * This method checks whether specified widget is a factory widget.
+ *
+ * @param[in] widgetHandle widget's app id
+ * @return true if yes, false if no.
+ */
+ bool isFactory() 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 gets deletable property of widget.
+ *
+ * @return true: can be deleted; false: can not be deleted
+ * @exception WRT_CONF_ERR_GCONF_FAILURE
+ * @exception WRT_CONF_ERR_EMDB_FAILURE
+ * @exception WRT_CONF_ERR_EMDB_NO_RECORD
+ */
+ bool isDeletable() const;
+
+ /* This method gets the parameter list for resource.
+ */
+ ResourceAttributeList getResourceAttribute(
+ const std::string &resourceId) 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;
+ std::string getCookieDatabasePath() const;
+ // Local storage
+ std::string getPrivateLocalStoragePath() const;
+
+ ChildProtection::Record getChildProtection() const;
+
+ Powder::Description getPowderDescription() const;
+
+ bool getBackSupported() const;
+
+ static bool isWidgetInstalled(DbWidgetHandle handle);
+ static bool isWidgetInstalled(DPL::String pkgName);
+
+ CertificateChainList getWidgetCertificate() const;
+
+ void getWidgetSettings(WidgetSettings& outWidgetSettings) const;
+
+ /**
+ * This method gets application service list that define AUL value
+ *
+ * @return See above comment
+ * @exception WRT_CONF_ERR_EMDB_FAILURE - Fail to query DB table.
+ */
+ void getAppServiceList(
+ WidgetApplicationServiceList& outAppServiceList) const;
+};
+
+} // namespace WrtDB
+
+#endif // _WRT_SRC_CONFIGURATION_WIDGET_DAO_READ_ONLY_H_
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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);
+
+ FeatureHandle RegisterStrangeFeature(const std::string& featureName);
+} // namespace FeatureDB
+} // namespace WrtDB
+
+#endif /* _FEATURE_DAO_H */
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_dao.h
+ * @author Pawel Sikorski (p.sikorski@samsung.com)
+ * @version 1.0
+ * @brief This file contains the declaration of global dao
+ */
+
+#ifndef WRT_SRC_CONFIGURATION_GLOBAL_DAO_H_
+#define WRT_SRC_CONFIGURATION_GLOBAL_DAO_H_
+
+#include <dpl/wrt-dao-ro/global_dao_read_only.h>
+
+namespace WrtDB {
+
+class GlobalDAO : public GlobalDAOReadOnly
+{
+ public:
+ /**
+ * Set new Parental mode status
+ */
+ static void SetParentalMode(bool parental_status);
+
+ /**
+ * Retrieve Parental mode maximal allowed age
+ *
+ * @return NULL if allowed age not set, else pointer value is allowed age
+ */
+ static void SetParentalAllowedAge(const DPL::OptionalInt& age);
+
+ static void AddCategoryRule(
+ const ChildProtection::PowderRules::CategoryRule& powder);
+
+ static void RemoveCategoryRule(
+ const ChildProtection::PowderRules::CategoryRule& powder);
+
+ static void UpdateCategoryRule(
+ const ChildProtection::PowderRules::CategoryRule& oldRule,
+ const ChildProtection::PowderRules::CategoryRule& newRule);
+
+ static void AddAdultBlackListElement(const DPL::String &url);
+
+ static void RemoveAdultBlackListElement(const DPL::String &url);
+
+ static void UpdateAdultBlackList(const DPL::String &oldUrl,
+ const DPL::String &newUrl);
+
+ /**
+ * Add deffered widget packages to be installed
+ */
+ static void AddDefferedWidgetPackageInstallation(const DPL::String &path);
+
+ /**
+ * Remove deffered widget packages to be installed
+ */
+ static void RemoveDefferedWidgetPackageInstallation(const DPL::String &arg);
+
+ static void SetDeveloperMode(bool mode);
+
+ static void SetSecureByDefault(bool secureByDefault);
+
+ static void setComplianceMode(bool mode);
+
+ static void setComplianceFakeImei(const std::string &imei);
+
+ static void setComplianceFakeMeid(const std::string &meid);
+
+ static void AddWhiteURI(const std::string &value, bool subDomain);
+
+ static void RemoveWhiteURI(const std::string &uri);
+
+ /**
+ * This method changes network access mode while roaming is enabled.
+ *
+ */
+ static void SetHomeNetworkDataUsage(NetworkAccessMode newMode);
+
+ /**
+ * This method changes network access mode while roaming is enabled.
+ *
+ */
+ static void SetRoamingDataUsage(NetworkAccessMode newMode);
+
+ /**
+ * This method sets Autofill for Webkit
+ */
+ static void SetAutoSaveIdPasswd(
+ const DPL::String &url, const AutoSaveData &saveData);
+
+
+ private:
+ GlobalDAO()
+ {
+ }
+};
+
+} // namespace WrtDB
+
+#endif /* WRT_SRC_CONFIGURATION_GLOBAL_DAO_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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);
+};
+
+} // namespace WrtDB
+
+#endif /* WRT_SRC_CONFIGURATION_PLUGIN_DAO_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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(DbWidgetHandle widgetHandle,
+ const PropertyDAOReadOnly::WidgetPropertyKey &key);
+
+/* This method sets widget property
+ */
+void SetProperty(DbWidgetHandle widgetHandle,
+ 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,
+ const WidgetRegisterInfo ®Info);
+
+} // namespace PropertyDAO
+} // namespace WrtDB
+
+#endif /* WRT_SRC_CONFIGURATION_PROPERTY_DAO_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <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;
+
+ /**
+ * This is a constructor.
+ *
+ * @param[in] widgetHandle application id of widget.
+ * @param[in] widgetGUID application guid of widget.
+ */
+ WidgetDAO(DbWidgetHandle widgetHandle);
+ WidgetDAO(DPL::OptionalString widgetGUID);
+
+ /**
+ * Destructor
+ */
+ virtual ~WidgetDAO();
+
+ /**
+ * This method registers the widget information to the DB when it is installed.
+ *
+ * @see WidgetRegisterInfo
+ * @see UnRegisterWidget()
+ * @param[in] pWidgetRegisterInfo Specified the widget's information needed to be registered.
+ * @return widget's app id issued by app manager; 0 represents a failure during register.
+ */
+ static DbWidgetHandle registerWidget(
+ const WidgetRegisterInfo &pWidgetRegisterInfo,
+ const IWacSecurity &wacSecurity,
+ const LanguageTagsList& languageTags);
+
+ /**
+ * This method removes a widget's information from EmDB.
+ *
+ * @see RegisterWidget()
+ * @param[in] widgetHandle widget's app id
+ * @return true if succeed, false if fail.
+ */
+ static void unregisterWidget(DbWidgetHandle widgetHandle);
+
+ /* This method removes widget property
+ */
+ void removeProperty(const PropertyDAOReadOnly::WidgetPropertyKey &key);
+
+ /* This method sets widget property
+ */
+ void setProperty(const PropertyDAOReadOnly::WidgetPropertyKey &key,
+ const PropertyDAOReadOnly::WidgetPropertyValue &value,
+ bool readOnly = false);
+
+ /* set PkgName
+ */
+ void setPkgName(const DPL::OptionalString& pkgName);
+
+ private:
+ //Methods used during widget registering
+ static DbWidgetHandle registerWidgetInfo(
+ const WidgetRegisterInfo ®Info,
+ const IWacSecurity &wacSecurity);
+ static void registerWidgetExtendedInfo(
+ DbWidgetHandle widgetHandle,
+ const WidgetRegisterInfo ®Info);
+ static void registerWidgetLocalizedInfo(
+ DbWidgetHandle widgetHandle,
+ const WidgetRegisterInfo ®Info);
+ static void registerWidgetUserAgentLocales(
+ DbWidgetHandle widgetHandle,
+ const WidgetRegisterInfo &rInf,
+ const LanguageTagsList& languageTags);
+ static void registerWidgetIcons(
+ DbWidgetHandle widgetHandle,
+ const WidgetRegisterInfo ®Info);
+ static void registerWidgetStartFile(
+ DbWidgetHandle widgetHandle,
+ const WidgetRegisterInfo ®Info);
+ static void registerWidgetPreferences(
+ DbWidgetHandle widgetHandle,
+ const WidgetRegisterInfo ®Info);
+ static void registerWidgetFeatures(
+ DbWidgetHandle widgetHandle,
+ const WidgetRegisterInfo ®Info);
+ static void registerWidgetWindowModes(
+ DbWidgetHandle widgetHandle,
+ const WidgetRegisterInfo ®Info);
+ static void registerWidgetWarpInfo(
+ DbWidgetHandle widgetHandle,
+ const WidgetRegisterInfo ®Info);
+ static void registerWidgetCertificates(
+ DbWidgetHandle widgetHandle,
+ const IWacSecurity &wacSecurity);
+ static void registerWidgetPowderData(
+ DbWidgetHandle widgetHandle,
+ const WidgetRegisterInfo ®Info);
+ static void registerLaunchCertificates(
+ DbWidgetHandle widgetHandle,
+ const CertificateChainList &list);
+ static void registerWidgetSettings(
+ DbWidgetHandle widgetHandle,
+ const WidgetRegisterInfo ®Info);
+ static void registerAppService(
+ DbWidgetHandle widgetHandle,
+ const WidgetRegisterInfo ®Info);
+};
+
+} // namespace WrtDB
+
+#endif // WIDGET_DAO_H
--- /dev/null
+#!/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}
+
--- /dev/null
+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; )
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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
--- /dev/null
+SQL(
+ BEGIN TRANSACTION;
+ CREATE TABLE DB_CHECKSUM (version INT);
+ COMMIT;
+)
--- /dev/null
+SQL(
+ PRAGMA foreign_keys = ON;
+ BEGIN TRANSACTION;
+)
+/*TODO: secure_by_default should be 0 by default*/
+CREATE_TABLE(GlobalProperties)
+ COLUMN_NOT_NULL(developer_mode, INT, DEFAULT 0)
+ COLUMN_NOT_NULL(parental_mode, INT, DEFAULT 0)
+ COLUMN(parental_allowed_age, INT, DEFAULT NULL)
+ COLUMN_NOT_NULL(secure_by_default, INT, DEFAULT 1)
+ COLUMN_NOT_NULL(home_network_data_usage, TINYINT, DEFAULT 1)
+ COLUMN_NOT_NULL(roaming_data_usage, TINYINT, DEFAULT 1)
+ COLUMN_NOT_NULL(compliance_mode, TINYINT, DEFAULT 0)
+ COLUMN_NOT_NULL(compliance_fake_imei, VARCHAR(256), DEFAULT '')
+ COLUMN_NOT_NULL(compliance_fake_meid, VARCHAR(256), DEFAULT '')
+CREATE_TABLE_END()
+
+SQL(
+ INSERT INTO GlobalProperties DEFAULT VALUES;
+)
+
+CREATE_TABLE(WidgetInfo)
+ COLUMN_NOT_NULL(app_id, INTEGER, PRIMARY KEY AUTOINCREMENT)
+ COLUMN(widget_type, INT, DEFAULT 1)
+ COLUMN(widget_id, VARCHAR(256), DEFAULT '')
+ COLUMN(widget_version, VARCHAR(256), DEFAULT '')
+ COLUMN(widget_width, INT, DEFAULT 0)
+ COLUMN(widget_height, INT, DEFAULT 0)
+ COLUMN(author_name, VARCHAR(256), DEFAULT '')
+ COLUMN(author_email, VARCHAR(256), DEFAULT '')
+ COLUMN(author_href, VARCHAR(256), DEFAULT '')
+ COLUMN(base_folder, VARCHAR(256), DEFAULT '')
+ COLUMN(webkit_plugins_required, TINYINT, DEFAULT 0)
+ COLUMN(security_domain, INT, DEFAULT 0)
+ COLUMN_NOT_NULL(child_protection,INT, DEFAULT 0)
+ COLUMN(recognized, INT, DEFAULT 0)
+ COLUMN(wac_signed, INT, DEFAULT 0)
+ COLUMN(distributor_signed, INT, DEFAULT 0)
+ COLUMN(min_version, VARCHAR(16), DEFAULT '1.0')
+ COLUMN_NOT_NULL(back_supported, TINYINT, DEFAULT 0)
+ COLUMN(access_network, TINYINT, DEFAULT 0)
+ COLUMN(defaultlocale, VARCHAR(256), DEFAULT 0)
+ COLUMN(pkgname, VARCHAR(256), DEFAULT 0)
+CREATE_TABLE_END()
+
+CREATE_TABLE(WidgetCertificate)
+ COLUMN_NOT_NULL(app_id, INT,)
+ 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(WidgetUserAgentLocales)
+ COLUMN_NOT_NULL(id, INTEGER, PRIMARY KEY AUTOINCREMENT)
+ COLUMN_NOT_NULL(app_id, INT,)
+ COLUMN_NOT_NULL(language_tag, TEXT,)
+ 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(share_href, VARCHAR(256), DEFAULT '')
+ COLUMN(signature_type, INT, DEFAULT 0)
+ COLUMN(factory_widget, 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)
+ TABLE_CONSTRAINTS(
+ FOREIGN KEY(app_id) REFERENCES WidgetInfo (app_id) ON DELETE CASCADE
+ )
+CREATE_TABLE_END()
+
+CREATE_TABLE(WidgetPreference)
+ COLUMN_NOT_NULL(app_id, INT,)
+ COLUMN_NOT_NULL(key_name, VARCHAR(256),)
+ COLUMN(key_value, VARCHAR(8000), 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, VARCHAR(256),)
+ COLUMN_NOT_NULL(required, INT,)
+ TABLE_CONSTRAINTS(
+ FOREIGN KEY (app_id) REFERENCES WidgetInfo (app_id) ON DELETE CASCADE
+ )
+CREATE_TABLE_END()
+
+CREATE_TABLE(FeatureParam)
+ COLUMN_NOT_NULL(widget_feature_id, INTEGER,)
+ COLUMN_NOT_NULL(name, TEXT,)
+ COLUMN_NOT_NULL(value, TEXT,)
+
+ TABLE_CONSTRAINTS(
+ FOREIGN KEY (widget_feature_id) REFERENCES WidgetFeature (widget_feature_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, VARCHAR(256),)
+ 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, VARCHAR(256),)
+ 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(WidgetAccessHost)
+ COLUMN_NOT_NULL(app_id, INT,)
+ COLUMN_NOT_NULL(host, VARCHAR(256),)
+
+ TABLE_CONSTRAINTS(
+ PRIMARY KEY(app_id, host)
+ FOREIGN KEY (app_id) REFERENCES WidgetInfo (app_id) ON DELETE CASCADE)
+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, VARCHAR(64),)
+ COLUMN(sha1_fingerprint, VARCHAR(64),)
+ 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, VARCHAR(65536),)
+ 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(FeaturesList)
+ COLUMN_NOT_NULL(FeatureUUID, INTEGER, primary key autoincrement)
+ COLUMN_NOT_NULL(FeatureName, TEXT, unique)
+ COLUMN_NOT_NULL(PluginPropertiesId, INT,)
+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,)
+ COLUMN(InstallURI, TEXT,)
+ COLUMN(KeyCN, TEXT,)
+ COLUMN(RootKeyCN, TEXT,)
+ COLUMN(RootKeyFingerprint, TEXT,)
+CREATE_TABLE_END()
+
+CREATE_TABLE(PluginDependencies)
+ COLUMN_NOT_NULL(PluginPropertiesId, INTEGER, not null)
+ COLUMN_NOT_NULL(RequiredPluginPropertiesId, INTEGER, not null)
+CREATE_TABLE_END()
+
+CREATE_TABLE(PluginImplementedObjects)
+ COLUMN_NOT_NULL(PluginObject, TEXT, unique)
+ COLUMN_NOT_NULL(PluginPropertiesId, INTEGER, not null)
+CREATE_TABLE_END()
+
+CREATE_TABLE(PluginRequiredObjects)
+ COLUMN_NOT_NULL(PluginPropertiesId, INTEGER, not null)
+ COLUMN_NOT_NULL(PluginObject, TEXT, not null)
+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(PRIMARY KEY(FeatureUUID,DeviceCapID))
+CREATE_TABLE_END()
+
+CREATE_TABLE(PowderLevels)
+ COLUMN_NOT_NULL(app_id, INT, )
+ COLUMN_NOT_NULL(id, INTEGER, primary key autoincrement)
+ COLUMN_NOT_NULL(category, TEXT, )
+ COLUMN_NOT_NULL(level, INTEGER, )
+ TABLE_CONSTRAINTS(
+ FOREIGN KEY (app_id) REFERENCES WidgetInfo (app_id) ON DELETE CASCADE
+ )
+CREATE_TABLE_END()
+
+CREATE_TABLE(PowderLevelContexts)
+ COLUMN_NOT_NULL(levelId, INTEGER, )
+ COLUMN_NOT_NULL(context, TEXT, )
+
+ TABLE_CONSTRAINTS(
+ FOREIGN KEY (levelId) REFERENCES PowderLevels (id) ON DELETE CASCADE
+ )
+CREATE_TABLE_END()
+
+CREATE_TABLE(ChildProtectionBlacklist)
+ COLUMN_NOT_NULL(url, TEXT, unique)
+CREATE_TABLE_END()
+
+CREATE_TABLE(PowderRules)
+ COLUMN_NOT_NULL(id, INTEGER, primary key autoincrement)
+ COLUMN_NOT_NULL(category, TEXT, )
+ COLUMN_NOT_NULL(level, INTEGER, )
+ COLUMN(context, TEXT, )
+ TABLE_CONSTRAINTS(unique(category,context))
+CREATE_TABLE_END()
+
+CREATE_TABLE(DefferedWidgetPackageInstallation)
+ COLUMN_NOT_NULL(path, TEXT, unique)
+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(AutoSaveIdPasswd)
+ COLUMN_NOT_NULL(address, VARCHAR(256), unique)
+ COLUMN_NOT_NULL(userId, VARCHAR(128),)
+ COLUMN_NOT_NULL(passwd, VARCHAR(128),)
+CREATE_TABLE_END()
+
+CREATE_TABLE(SettginsList)
+ 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(ApplicationServiceInfo)
+ COLUMN_NOT_NULL(app_id, INT,)
+ COLUMN_NOT_NULL(src, TEXT,)
+ COLUMN_NOT_NULL(operation, TEXT,)
+ COLUMN_NOT_NULL(scheme, TEXT,)
+ COLUMN_NOT_NULL(mime, TEXT,)
+
+ TABLE_CONSTRAINTS(
+ PRIMARY KEY(app_id, operation, scheme, mime)
+ FOREIGN KEY(app_id) REFERENCES WidgetInfo (app_id) ON DELETE CASCADE
+ )
+CREATE_TABLE_END()
+
+CREATE_TABLE(WidgetWhiteURIList)
+ COLUMN_NOT_NULL(uri, VARCHAR(65536), primary key)
+ COLUMN_NOT_NULL(subdomain_access, INT, CHECK(subdomain_access between 0 and 1))
+CREATE_TABLE_END()
+
+SQL(
+ INSERT INTO WidgetWhiteURIList VALUES("http://samsung.com", 1);
+ INSERT INTO WidgetWhiteURIList VALUES("http://orange.fr", 1);
+ INSERT INTO WidgetWhiteURIList VALUES("http://orange.co.uk", 1);
+)
+
+/*TODO: It will be removed when user agent is fixed. User agent MUST be configurable in development...*/
+CREATE_TABLE(UserAgents)
+ COLUMN_NOT_NULL(key_name, VARCHAR(256),)
+ COLUMN(key_value, VARCHAR(8000), DEFAULT '')
+
+ TABLE_CONSTRAINTS(PRIMARY KEY(key_name))
+CREATE_TABLE_END()
+
+SQL(
+ INSERT INTO UserAgents VALUES("Tizen", "Mozilla/5.0 (Linux; U; Tizen 1.0; en-us) AppleWebKit/534.46 (KHTML, like Gecko) Mobile Tizen Browser/1.0");
+ INSERT INTO UserAgents VALUES("Chrome 16", "Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20110706 Firefox/5.0");
+)
+
+SQL(
+ COMMIT;
+)
--- /dev/null
+DATABASE_START(wrt)
+
+#include "wrt_db"
+#include "iana_db"
+#include "version_db"
+
+DATABASE_END()
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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"
--- /dev/null
+Name: dpl
+Summary: Design patterns library
+Version: 0.1.57
+Release: 1
+Group: System/Libraries
+License: TBD
+Source0: %{name}-%{version}.tar.bz2
+Requires(post): /sbin/ldconfig
+Requires(postun): /sbin/ldconfig
+BuildRequires: cmake
+BuildRequires: pkgconfig(ecore)
+BuildRequires: pkgconfig(vconf)
+BuildRequires: pkgconfig(heynoti)
+BuildRequires: pkgconfig(appcore-efl)
+BuildRequires: pkgconfig(libssl)
+BuildRequires: pkgconfig(sqlite3)
+BuildRequires: pkgconfig(db-util)
+BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(zlib)
+BuildRequires: pkgconfig(libpcrecpp)
+BuildRequires: pkgconfig(icu-uc)
+
+BuildRoot: %{_tmppath}/%{name}-%{version}-build
+
+%description
+Design patterns library is a collection of useful C++ utilities to easily develop window applications.
+
+%package efl
+Summary: Design patterns library - EFL based
+Group: System/Libraries
+
+%description efl
+Design patterns library is a collection of useful C++ utilities to easily develop window applications.
+
+%package efl-devel
+Summary: Design patterns library - EFL based developer files
+Group: Development/Libraries
+Requires: %{name}-efl = %{version}-%{release}
+
+%description efl-devel
+Design patterns library is a collection of useful C++ utilities to easily develop window applications. The most important part of library is full MVC support. It also supports event-based architecture, adds wrappers for many packages and provides many basic C++ utilities as RAII objects, singletons, and many other.
+
+%prep
+%setup -q -n %{name}-%{version}
+
+%build
+
+cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} \
+ -DDPL_LOG=ON \
+ -DDISABLE_GTK=ON
+
+# Call make instruction with smp support
+make %{?jobs:-j%jobs}
+
+# >> build post
+# << build post
+%install
+rm -rf %{buildroot}
+%make_install
+
+%clean
+rm -rf %{buildroot}
+
+%post -p /sbin/ldconfig
+
+%postun -p /sbin/ldconfig
+
+
+%files efl
+%defattr(-,root,root,-)
+%{_libdir}/lib*-efl.so*
+# << files
+
+%files efl-devel
+%defattr(-,root,root,-)
+%{_includedir}/dpl-efl/*
+%{_libdir}/pkgconfig/*-efl.pc
+
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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
+#
+
+SET(DPL_TEST_INCLUDE_DIR
+ ${DPL_CORE_INCLUDE_DIR}
+ ${DPL_EVENT_INCLUDE_DIR}
+ ${DPL_DBUS_INCLUDE_DIR}
+ ${DPL_DB_INCLUDE_DIR}
+ ${DPL_RPC_INCLUDE_DIR}
+ ${DPL_SOCKET_INCLUDE_DIR}
+ ${DPL_TEST_ENGINE_INCLUDE_DIR}
+ ${DPL_LOG_INCLUDE_DIR}
+)
+
+ADD_SUBDIRECTORY(core)
+ADD_SUBDIRECTORY(dbus)
+ADD_SUBDIRECTORY(db)
+ADD_SUBDIRECTORY(event)
+ADD_SUBDIRECTORY(ace)
+ADD_SUBDIRECTORY(vcore)
+ADD_SUBDIRECTORY(localization)
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "AttributeSetter.h"
+
+#include <dpl/singleton_impl.h>
+IMPLEMENT_SINGLETON(AttributeSetter)
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @file AttributeSetter.h
+ * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 0.1
+ * @brief Stub for attribute_facade.h
+ */
+#ifndef _TEST_ACE_TESTS_ATTRIBUTE_SETTER_
+#define _TEST_ACE_TESTS_ATTRIBUTE_SETTER_
+
+#include <list>
+#include <map>
+#include <string>
+
+#include <dpl/singleton.h>
+#include <dpl/foreach.h>
+#include <dpl/log/log.h>
+
+#include <dpl/ace/Request.h>
+#include <dpl/ace/WRT_INTERFACE.h>
+
+class AttributeSetter {
+public:
+ typedef std::list<std::string> ValueList;
+ typedef std::map<std::string, ValueList> AttributeMap;
+ typedef std::map<int, AttributeMap> CollectionHandlerMap;
+
+ typedef std::list<ATTRIBUTE> Evil;
+
+ void get(const Request &request,
+ const Evil* evil)
+ {
+ int handle = request.getWidgetHandle();
+
+ CollectionHandlerMap::iterator widgetContextIt =
+ m_collectionMap.find(handle);
+
+ if (widgetContextIt == m_collectionMap.end()) {
+ LogError("WidgetContext is empty");
+ return;
+ }
+
+ FOREACH(it, *evil)
+ {
+ std::string attrName = *(it->first);
+
+ if (attrName == "device-cap") {
+ Request::DeviceCapabilitySet devCapSet =
+ request.getDeviceCapabilitySet();
+ std::copy(devCapSet.begin(),
+ devCapSet.end(),
+ std::back_inserter(*(it->second)));
+ continue;
+ }
+
+ AttributeMap::iterator attrIt =
+ widgetContextIt->second.find(attrName);
+
+ if (attrIt == widgetContextIt->second.end()) {
+ LogError("No attribute: " << attrName <<
+ " in context nr: " << handle);
+ const ATTRIBUTE &a = *it;
+ const_cast<ATTRIBUTE&>(a).second = NULL;
+ continue;
+ }
+
+ ValueList valueList = attrIt->second;
+
+ std::copy(valueList.begin(),
+ valueList.end(),
+ std::back_inserter(*(it->second)));
+ }
+ }
+
+ void addValue(int handler,
+ const std::string &attributeName,
+ const std::string &attributeValue)
+ {
+ m_collectionMap[handler][attributeName].push_back(attributeValue);
+ }
+
+ std::string getValue(int handler, const std::string &attributeName)
+ {
+ std::list<std::string> lst = m_collectionMap[handler][attributeName];
+ if (lst.empty())
+ return "fake-device-name-that-should-not-match-with-anything";
+ return lst.front();
+ }
+
+ void addValue(int handler,
+ const char *attributeName,
+ const char *attributeValue)
+ {
+ std::string aN = attributeName;
+ std::string aV = attributeValue;
+ addValue(handler, aN, aV);
+ }
+
+ void clear() {
+ m_collectionMap.clear();
+ }
+protected:
+ AttributeSetter(){}
+ ~AttributeSetter(){}
+private:
+ CollectionHandlerMap m_collectionMap;
+};
+
+typedef DPL::Singleton<AttributeSetter> AttributeSetterSingleton;
+
+#endif // _TEST_ACE_TESTS_ATTRIBUTE_SETTER_
--- /dev/null
+#
+#Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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 0.1
+# @brief
+#
+INCLUDE(FindPkgConfig)
+SET(TARGET_ACE_TEST "dpl-tests-ace")
+
+PKG_CHECK_MODULES(ACE_TEST_DEP
+ libxml-2.0
+ gobject-2.0
+ REQUIRED
+ )
+
+# Set DPL tests sources
+SET(ACE_TESTS_SOURCES
+ ${PROJECT_SOURCE_DIR}/tests/ace/ace_tests.cpp
+ ${PROJECT_SOURCE_DIR}/tests/ace/loop_control.cpp
+ ${PROJECT_SOURCE_DIR}/tests/ace/TestSuite01.cpp
+ ${PROJECT_SOURCE_DIR}/tests/ace/TestSuite02.cpp
+ ${PROJECT_SOURCE_DIR}/tests/ace/TestSuite03.cpp
+ ${PROJECT_SOURCE_DIR}/tests/ace/TestSuite04.cpp
+ ${PROJECT_SOURCE_DIR}/tests/ace/TestSuite05.cpp
+ ${PROJECT_SOURCE_DIR}/tests/ace/TestSuite06.cpp
+ ${PROJECT_SOURCE_DIR}/tests/ace/TestSuite07.cpp
+ ${PROJECT_SOURCE_DIR}/tests/ace/Interfaces.cpp
+ ${PROJECT_SOURCE_DIR}/tests/ace/PEPSingleton.cpp
+ ${PROJECT_SOURCE_DIR}/tests/ace/AttributeSetter.cpp
+ )
+
+INCLUDE_DIRECTORIES(
+ ${SYS_EFL_INCLUDE_DIRS}
+ ${DPL_TEST_INCLUDE_DIR}
+ ${PROJECT_SOURCE_DIR}/modules/ace/include
+ ${PROJECT_SOURCE_DIR}/tests/ace
+ ${ACE_TEST_DEP_INCLUDE_DIRS}
+ )
+
+ADD_EXECUTABLE(${TARGET_ACE_TEST} ${ACE_TESTS_SOURCES})
+
+TARGET_LINK_LIBRARIES(${TARGET_ACE_TEST}
+ ${SYS_EFL_LIBRARIES}
+ ${TARGET_DPL_EFL}
+ ${TARGET_DPL_TEST_ENGINE_EFL}
+ ${TARGET_ACE_LIB}
+ ${ACE_TEST_DEP_LIBRARIES}
+ )
+
+INSTALL(TARGETS ${TARGET_ACE_TEST}
+ DESTINATION bin
+ PERMISSIONS OWNER_READ
+ OWNER_WRITE
+ OWNER_EXECUTE
+ GROUP_READ
+ GROUP_EXECUTE
+ WORLD_READ
+ WORLD_EXECUTE
+ )
+
+ADD_SUBDIRECTORY(test-configuration)
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file Interfaces.cpp
+ * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 1.0
+ * @brief Stubs used by PolicyInformationPoint.h
+ */
+#include "Interfaces.h"
+
+#include <dpl/log/log.h>
+
+#include "AttributeSetter.h"
+
+int WebRuntimeImp::getAttributesValues(
+ const Request &request,
+ std::list<ATTRIBUTE> *attribute)
+{
+ LogError("Running stub");
+ AttributeSetterSingleton::Instance().get(request, attribute);
+ return 0;
+}
+
+int ResourceInformationImp::getAttributesValues(
+ const Request &request,
+ std::list<ATTRIBUTE> *attribute)
+{
+ LogError("Running stub");
+ AttributeSetterSingleton::Instance().get(request, attribute);
+ return 0;
+}
+
+int OperationSystemImp::getAttributesValues(
+ const Request &request,
+ std::list<ATTRIBUTE> *attribute)
+{
+ LogError("Running stub");
+ AttributeSetterSingleton::Instance().get(request, attribute);
+ return 0;
+}
+
+int FunctionParamImpl::getAttributesValues(const Request & /* request*/,
+ std::list<ATTRIBUTE> *attributes)
+{
+ LogError("Running stub");
+ FOREACH(iter, *attributes)
+ {
+ std::string attributeName = *(iter->first);
+
+ ParamMap::const_iterator i;
+ std::pair<ParamMap::const_iterator, ParamMap::const_iterator> jj =
+ paramMap.equal_range(attributeName);
+
+ for (i = jj.first; i != jj.second; ++i) {
+ iter->second->push_back(i->second);
+ LogDebug("Attribute: " << attributeName << " Value: " <<
+ i->second);
+ }
+ }
+ return 0;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file Interfaces.h
+ * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 1.0
+ * @brief Stubs used by PolicyInformationPoint.h
+ */
+#ifndef _TEST_ACE_TESTS_INTERFACE_H_
+#define _TEST_ACE_TESTS_INTERFACE_H_
+
+#include <string>
+#include <dpl/ace/WRT_INTERFACE.h>
+#include <map>
+#include <vector>
+
+class Request;
+
+class WebRuntimeImp : public IWebRuntime {
+public:
+ int getAttributesValues(
+ const Request &request,
+ std::list<ATTRIBUTE> *attribute);
+ std::string getSessionId(const Request &) { return std::string(); }
+};
+
+class ResourceInformationImp : public IResourceInformation {
+public:
+ int getAttributesValues(
+ const Request &request,
+ std::list<ATTRIBUTE> *attribute);
+};
+
+class OperationSystemImp : public IOperationSystem {
+public:
+ int getAttributesValues(
+ const Request &request,
+ std::list<ATTRIBUTE> *attribute);
+};
+
+class FunctionParamImpl : public IFunctionParam
+{
+public:
+ virtual int getAttributesValues(const Request & /* request*/,
+ std::list<ATTRIBUTE> *attributes);
+ void addAttribute(const std::string &key,
+ const std::string &value)
+ {
+ paramMap.insert(make_pair(key, value));
+ }
+ virtual ~FunctionParamImpl() {}
+private:
+ typedef std::multimap<std::string, std::string> ParamMap;
+ ParamMap paramMap;
+};
+
+#endif // _TEST_ACE_TESTS_INTERFACE_H_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file Interfaces.h
+ * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 1.0
+ * @brief Instance of PEP used in tests.
+ */
+#include "PEPSingleton.h"
+
+#include <dpl/singleton_impl.h>
+IMPLEMENT_SINGLETON(PolicyEnforcementPoint)
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file Interfaces.h
+ * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 1.0
+ * @brief Instantion of PEP used in tests.
+ */
+#ifndef _TEST_ACE_TEST_PEPSINGLETON_H_
+#define _TEST_ACE_TEST_PEPSINGLETON_H_
+
+#include <dpl/singleton.h>
+#include <dpl/ace/PolicyEnforcementPoint.h>
+
+typedef DPL::Singleton<PolicyEnforcementPoint> PEPSingleton;
+
+#endif // _TEST_ACE_TEST_PEPSINGLETON_H_
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file TestSuite01.cpp
+ * @author unknown
+ * @version 1.0
+ * @brief Test cases for PolicyEvaluator class.
+ */
+#include <string>
+
+#include <dpl/log/log.h>
+#include <dpl/test/test_runner.h>
+
+#include <dpl/ace-dao-rw/AceDAO.h>
+#include <dpl/ace/Preference.h>
+#include <dpl/ace/SettingsLogic.h>
+#include <dpl/ace/PolicyEvaluator.h>
+
+#include "AttributeSetter.h"
+#include "Interfaces.h"
+#include "PEPSingleton.h"
+
+#define GENERAL_TEST_POLICY "/usr/etc/ace/general-test.xml"
+#define GENERAL_TEST_POLICY_UNDETERMIND "/usr/etc/ace/undefined-test.xml"
+#define GENERAL_TEST_POLICY_GSETTINGS "/usr/etc/ace/policy-test-gsettings.xml"
+#define GENERAL_TEST_POLICY_TEST "/usr/etc/ace/policy-test.xml"
+
+#define CLEANENV(d) \
+ do{ \
+ if (PEPSingleton::Instance().getPdp()->getCurrentPolicy() != (d)) { \
+ PEPSingleton::Instance().getPdp()->updatePolicy(d); \
+ } \
+ AttributeSetterSingleton::Instance().clear(); \
+ AceDB::AceDAO::clearWidgetDevCapSettings(); \
+ AceDB::AceDAO::clearDevCapSettings(); \
+ }while(0)
+
+#define QU(nr, subid, resid) \
+ do{ \
+ AttributeSetterSingleton::Instance().addValue((nr), "id", (subid)); \
+ AttributeSetterSingleton::Instance().addValue((nr), "resource-id", (resid));\
+ }while(0)
+
+#define QA(nr, attrname, attrvalue) \
+ AttributeSetterSingleton::Instance().addValue((nr), (attrname), (attrvalue))
+
+#define QC(nr, expect) \
+ do{ \
+ Request request((nr), WidgetExecutionPhase_Unknown); \
+ std::string a = \
+ AttributeSetterSingleton::Instance().getValue((nr),"resource-id"); \
+ request.addDeviceCapability(a); \
+ PolicyResult result = PEPSingleton::Instance().check(request); \
+ RUNNER_ASSERT(result == (expect)); \
+ }while(0)
+
+#define QCP(nr, param, expect) \
+ do{ \
+ Request request((nr), WidgetExecutionPhase_Unknown, (param)); \
+ std::string a = \
+ AttributeSetterSingleton::Instance().getValue((nr),"resource-id"); \
+ request.addDeviceCapability(a); \
+ PolicyResult result = PEPSingleton::Instance().check(request); \
+ RUNNER_ASSERT(result == (expect)); \
+ }while(0)
+
+#define TESTSUITE01(n) \
+RUNNER_TEST(ts01_general_tests_ ## n)
+
+TESTSUITE01(01){
+ CLEANENV(GENERAL_TEST_POLICY);
+ QU(1, "subject", "resource");
+ QA(1, "version", "3");
+ QC(1, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(02){
+ CLEANENV(GENERAL_TEST_POLICY);
+ QU(2, "subject2", "resource");
+ QA(2, "version", "1");
+ QC(2, PolicyEffect::DENY);
+}
+
+TESTSUITE01(03){
+ CLEANENV(GENERAL_TEST_POLICY);
+ QU(3, "subject3", "resource2");
+ QC(3, PolicyEffect::DENY);
+}
+
+TESTSUITE01(04){
+ CLEANENV(GENERAL_TEST_POLICY);
+ QU(4, "subject4", "resource4");
+ QA(4, "version", "4");
+ QC(4, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(05){
+ CLEANENV(GENERAL_TEST_POLICY);
+
+ QU(5, "subject5", "resource5");
+ QA(5, "version", "5");
+ QC(5, PolicyEffect::PERMIT);
+
+ QU(6, "subject5", "resource5");
+ QA(6, "version", "1");
+ QC(6, PolicyDecision::NOT_APPLICABLE);
+
+ QU(7, "subject6", "resource6");
+ QA(7, "version", "1");
+ QC(7, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(06){
+ CLEANENV(GENERAL_TEST_POLICY);
+
+ QU(6, "subject7", "resource7");
+ QA(6, "version", "7");
+ QA(6, "author", "author");
+ QC(6, PolicyDecision::NOT_APPLICABLE);
+
+ QU(7, "subject7", "resource7");
+ QA(7, "version", "7");
+ QA(7, "author", "author2");
+ QC(7, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(07){
+ CLEANENV(GENERAL_TEST_POLICY);
+ QU(3, "subject7", "resource7");
+ QA(3, "version", "1");
+ QA(3, "author", "author3");
+ QC(3, PolicyEffect::DENY);
+}
+
+TESTSUITE01(08){
+ CLEANENV(GENERAL_TEST_POLICY);
+
+ QU(8, "s8a", "r8");
+ QA(8, "r8v1", "1");
+ QA(8, "r8v2", "2");
+ QC(8, PolicyEffect::PERMIT);
+
+ QU(9, "s8b", "r8");
+ QA(9, "r8v1", "1");
+ QA(9, "r8v2", "2");
+ QC(9, PolicyEffect::DENY);
+
+ QU(19, "s8c", "r8");
+ QA(19, "r8v1", "1");
+ QA(19, "r8v2", "2");
+ QC(19, PolicyDecision::NOT_APPLICABLE);
+}
+
+TESTSUITE01(09){
+ CLEANENV(GENERAL_TEST_POLICY);
+
+ QU(1, "s9a", "r9");
+ QA(1, "r9a", "http://onet.pl:90/test.html");
+ QA(1, "r9b", "http://onet.pl:80/test.html");
+ QA(1, "r9c", "http://onet.pl:80");
+ QA(1, "r9d", "http://onet.pl:80");
+ QA(1, "r9e", "http://onet.pl:80/test.html");
+ QA(1, "r9g", "http://onet.pl:80/test.html");
+ QC(1, PolicyEffect::PERMIT);
+
+ QU(2, "s9b", "r9");
+ QA(2, "r9a", "http://onet.pl:90/test.html");
+ QA(2, "r9b", "http://onet.pl:80/test.html");
+ QA(2, "r9c", "http://onet.pl:80");
+ QA(2, "r9d", "http://onet.pl:80");
+ QA(2, "r9e", "http://onet.pl:80/test.html");
+ QA(2, "r9g", "http://onet.pl:80/test.html");
+ QC(2, PolicyEffect::DENY);
+
+ QU(3, "s9c", "r9");
+ QA(3, "r9a", "http://onet.pl:90/test.html");
+ QA(3, "r9b", "http://onet.pl:80/test.html");
+ QA(3, "r9c", "http://onet.pl:80");
+ QA(3, "r9d", "http://onet.pl:80");
+ QA(3, "r9e", "http://onet.pl:80/test.html");
+ QA(3, "r9g", "http://onet.pl:80/test.html");
+ QC(3, PolicyEffect::PERMIT);
+
+ QU(4, "s9d", "r9");
+ QA(4, "r9a", "http://onet.pl:90/test.html");
+ QA(4, "r9b", "http://onet.pl:80/test.html");
+ QA(4, "r9c", "http://onet.pl:80");
+ QA(4, "r9d", "http://onet.pl:80");
+ QA(4, "r9e", "http://onet.pl:80/test.html");
+ QA(4, "r9g", "http://onet.pl:80/test.html");
+ QC(4, PolicyEffect::DENY);
+
+ QU(5, "s9e", "r9");
+ QA(5, "r9a", "http://onet.pl:90/test.html");
+ QA(5, "r9b", "http://onet.pl:80/test.html");
+ QA(5, "r9c", "http://onet.pl:80");
+ QA(5, "r9d", "http://onet.pl:80");
+ QA(5, "r9e", "http://onet.pl:80/test.html");
+ QA(5, "r9g", "http://onet.pl:80/test.html");
+ QC(5, PolicyEffect::DENY);
+
+ QU(6, "s9f", "r9");
+ QA(6, "r9a", "http://onet.pl:90/test.html");
+ QA(6, "r9b", "http://onet.pl:80/test.html");
+ QA(6, "r9c", "http://onet.pl:80");
+ QA(6, "r9d", "http://onet.pl:80");
+ QA(6, "r9e", "http://onet.pl:80/test.html");
+ QA(6, "r9g", "http://onet.pl:80/test.html");
+ QC(6, PolicyEffect::PERMIT);
+
+ QU(7, "s9g", "r9");
+ QA(7, "r9a", "http://onet.pl:90/test.html");
+ QA(7, "r9b", "http://onet.pl:80/test.html");
+ QA(7, "r9c", "http://onet.pl:80");
+ QA(7, "r9d", "http://onet.pl:80");
+ QA(7, "r9e", "http://onet.pl:80/test.html");
+ QA(7, "r9g", "http://onet.pl:80/test.html");
+ QC(7, PolicyEffect::DENY);
+
+ QU(8, "s9h", "r9");
+ QA(8, "r9a", "http://onet.pl:90/test.html");
+ QA(8, "r9b", "http://onet.pl:80/test.html");
+ QA(8, "r9c", "http://onet.pl:80");
+ QA(8, "r9d", "http://onet.pl:80");
+ QA(8, "r9e", "http://onet.pl:80/test.html");
+ QA(8, "r9g", "http://onet.pl:80/test.html");
+ QC(8, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(10){
+ CLEANENV(GENERAL_TEST_POLICY);
+
+ QU(1, "s10a", "r10");
+ QA(1, "r10a", "15ba");
+ QA(1, "r10c", "15a1");
+ QC(1, PolicyEffect::PERMIT);
+
+ QU(2, "s10b", "r10");
+ QA(2, "r10a", "15ba");
+ QA(2, "r10c", "15a1");
+ QC(2, PolicyEffect::DENY);
+
+ QU(3, "s10c", "r10");
+ QA(3, "r10a", "15ba");
+ QA(3, "r10c", "15a1");
+ QC(3, PolicyResult::UNDETERMINED);
+}
+
+TESTSUITE01(11){
+ CLEANENV(GENERAL_TEST_POLICY);
+
+ QU(1, "s15", "device:pim.contacts");
+ QA(1, "uri", "//buu.com.pl");
+ QC(1, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(12){
+ CLEANENV(GENERAL_TEST_POLICY);
+
+ QU(1, "s16", "device:pim.contacts");
+ QA(1, "uri", "//v.com.pl");
+ QC(1, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(13){
+ CLEANENV(GENERAL_TEST_POLICY);
+
+ QU(1, "s17a", "resource4");
+ QA(1, "version", "4");
+ QC(1, PolicyEffect::PERMIT);
+
+ QU(2, "s17b", "resource4");
+ QA(2, "version", "4");
+ QC(2, PolicyEffect::DENY);
+}
+
+TESTSUITE01(14){
+ CLEANENV(GENERAL_TEST_POLICY);
+
+ QU(1, "s18a", "device:pim.contacts");
+ QA(1, "uri", "buu.com.pl");
+ QC(1, PolicyEffect::PERMIT);
+
+ QU(2, "s18b", "device:pim.contacts");
+ QA(2, "uri", "buu.com.pl");
+ QC(2, PolicyEffect::PERMIT);
+
+ QU(3, "s18c", "device:pim.contacts");
+ QA(3, "uri", "buu.com.pl");
+ QC(3, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(15){
+ CLEANENV(GENERAL_TEST_POLICY);
+
+ QU(1, "s19.1", "resource4");
+ QA(1, "key-root-trust", "voperator");
+ QC(1, PolicyEffect::DENY);
+
+ QU(2, "s19.2", "resource4");
+ QA(2, "key-root-trust", "voperator");
+ QC(2, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(16){
+ CLEANENV(GENERAL_TEST_POLICY);
+
+ QU(1, "s20.1", "resource4");
+ QA(1, "signer-id", "v7zha89%49x£$");
+ QC(1, PolicyEffect::DENY);
+
+ QU(2, "s20.2", "resource4");
+ QA(2, "signer-id", "v7zha89%49x£$");
+ QC(2, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(17){
+ CLEANENV(GENERAL_TEST_POLICY);
+
+ QU(1, "s21", "undetermined");
+ QC(1, PolicyDecision::NOT_APPLICABLE);
+
+
+ QU(2, "s21a", "undetermined");
+ QC(2, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(18){
+ CLEANENV(GENERAL_TEST_POLICY);
+ QU(1, "s23", "device:pim.contacts");
+ QA(1, "version", "undetermined");
+ QC(1, PolicyDecision::NOT_APPLICABLE);
+}
+
+TESTSUITE01(19){
+ CLEANENV(GENERAL_TEST_POLICY);
+ QU(1, "s24", "device:pim");
+ QC(1, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(20){
+ CLEANENV(GENERAL_TEST_POLICY);
+ QU(1, "s25.1", "device:pim.contacts");
+ QA(1, "version", "5");
+ QA(1, "roaming", "off");
+ QC(1, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(21){
+ CLEANENV(GENERAL_TEST_POLICY);
+ QU(1, "s25.2", "device:pim.contacts");
+ QA(1, "version", "undetermined");
+ QC(1, PolicyDecision::NOT_APPLICABLE);
+}
+
+TESTSUITE01(22){
+ CLEANENV(GENERAL_TEST_POLICY_UNDETERMIND);
+ QU(1, "s25.3", "device:pim.contacts");
+// undetermined QA(1, "version", "");
+ QC(1, PolicyResult::UNDETERMINED);
+}
+
+TESTSUITE01(23){
+ CLEANENV(GENERAL_TEST_POLICY_UNDETERMIND);
+ QU(1, "s25.4", "device:pim.contacts");
+ //undetermined
+ //QA(1, "version", "", true);
+ QC(1, PolicyResult::UNDETERMINED);
+}
+
+TESTSUITE01(24){
+ CLEANENV(GENERAL_TEST_POLICY_UNDETERMIND);
+ QU(1, "s26.1", "device:pim.contacts");
+ QA(1, "version", "5");
+ QC(1, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(25){
+ CLEANENV(GENERAL_TEST_POLICY_UNDETERMIND);
+ QU(1, "s26.2", "device:pim.contacts");
+ //undetermined
+ //QA(1, "version", "", true);
+ QC(1, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(26){
+ CLEANENV(GENERAL_TEST_POLICY_UNDETERMIND);
+ QU(1, "s26.3", "device:pim.contacts");
+ //undetermined
+ //QA(1, "version", "", true);
+ QC(1, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(27){
+ CLEANENV(GENERAL_TEST_POLICY_UNDETERMIND);
+ QU(1, "s26.4", "device:pim.contacts");
+ //undetermined
+ //QA(1, "version", "undetermined", true);
+ QC(1, PolicyResult::UNDETERMINED);
+}
+
+TESTSUITE01(28){
+ CLEANENV(GENERAL_TEST_POLICY_UNDETERMIND);
+ QU(1, "s27.1", "device:pim.contacts");
+ //undetermined
+ //QA(1, "version", "undetermined", true);
+ QC(1, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(29){
+ CLEANENV(GENERAL_TEST_POLICY_UNDETERMIND);
+ //Test undetermined, we have to refine this tests to test something
+ QU(1, "s27.2", "device:pim.contacts");
+ //undetermined
+ //QA(1, "version", "undetermined", true);
+ QC(1, PolicyResult::UNDETERMINED);
+}
+
+TESTSUITE01(30){
+ CLEANENV(GENERAL_TEST_POLICY_UNDETERMIND);
+ //Test undetermined, we have to refine this tests to test something
+ QU(1, "s27.3", "device:pim.contacts");
+ //undetermined
+ //QA(1, "version", "undetermined", true);
+ QC(1, PolicyDecision::NOT_APPLICABLE);
+}
+
+TESTSUITE01(31){
+ CLEANENV(GENERAL_TEST_POLICY_UNDETERMIND);
+ //Test undetermined, we have to refine this tests to test something
+ QU(1, "s27.4", "device:pim.contacts");
+ //undetermined
+ //QA(1, "version", "undetermined", true);
+ QC(1, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(32){
+ CLEANENV(GENERAL_TEST_POLICY_UNDETERMIND);
+ //Test undetermined, we have to refine this tests to test something
+ QU(1, "s28", "device:pim.contacts");
+ //undetermined
+ //QA(1, "version", "undetermined", true);
+ QC(1, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(33){
+ CLEANENV(GENERAL_TEST_POLICY_UNDETERMIND);
+ //Test undetermined, we have to refine this tests to test something
+ QU(1, "s29", "device:pim.contacts");
+ //undetermined
+ //QA(1, "version", "undetermined", true);
+ QC(1, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(34){
+ CLEANENV(GENERAL_TEST_POLICY_UNDETERMIND);
+ //Test undetermined, we have to refine this tests to test something
+ QU(1, "s30.1", "device:pim.contacts");
+ //undetermined
+ //QA(1, "version", "undetermined", true);
+ QC(1, PolicyResult::UNDETERMINED);
+}
+
+TESTSUITE01(35){
+ CLEANENV(GENERAL_TEST_POLICY_UNDETERMIND);
+ //Test undetermined, we have to refine this tests to test something
+ QU(1, "s30.2", "device:pim.contacts");
+ //undetermined
+ //QA(1, "version", "undetermined", true);
+ QC(1, PolicyResult::UNDETERMINED);
+}
+
+TESTSUITE01(36){
+ CLEANENV(GENERAL_TEST_POLICY_UNDETERMIND);
+ //Test undetermined, we have to refine this tests to test something
+ QU(1, "s30.3", "device:pim.contacts");
+ //undetermined
+ //QA(1, "version", "undetermined", true);
+ QC(1, PolicyResult::UNDETERMINED);
+}
+
+TESTSUITE01(37){
+ CLEANENV(GENERAL_TEST_POLICY_UNDETERMIND);
+ //Test undetermined, we have to refine this tests to test something
+ QU(1, "s30.4", "device:pim.contacts");
+ //undetermined
+ //QA(1, "version", "undetermined", true);
+ QC(1, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(38){
+ CLEANENV(GENERAL_TEST_POLICY_UNDETERMIND);
+ //Test undetermined, we have to refine this tests to test something
+ QU(1, "s31.1", "device:pim.contacts");
+ //undetermined
+ //QA(1, "version", "undetermined", true);
+ QC(1, PolicyResult::UNDETERMINED);
+}
+
+TESTSUITE01(39){
+ CLEANENV(GENERAL_TEST_POLICY_UNDETERMIND);
+ //Test undetermined, we have to refine this tests to test something
+ //undetermined
+ //QA(1, "version", "undetermined", true);
+ QU(1, "s31.2.1", "device:pim.contacts");
+ QC(1, PolicyEffect::DENY);
+}
+
+TESTSUITE01(40){
+ CLEANENV(GENERAL_TEST_POLICY_UNDETERMIND);
+ //Test undetermined, we have to refine this tests to test something
+ //undetermined
+ //QA(1, "version", "undetermined", true);
+ QU(1, "s31.2.2", "device:pim.contacts");
+ QC(1, PolicyResult::UNDETERMINED);
+}
+
+TESTSUITE01(41){
+ CLEANENV(GENERAL_TEST_POLICY_UNDETERMIND);
+ //Test undetermined, we have to refine this tests to test something
+ //undetermined
+ //QA(1, "version", "undetermined", true);
+ QU(1, "s31.3", "device:pim.contacts");
+ QC(1, PolicyResult::UNDETERMINED);
+}
+
+TESTSUITE01(42){
+ CLEANENV(GENERAL_TEST_POLICY_UNDETERMIND);
+ //Test undetermined, we have to refine this tests to test something
+ //undetermined
+ //QA(1, "version", "undetermined", true);
+ QU(1, "s32.1", "device:pim.contacts");
+ QC(1, PolicyResult::UNDETERMINED);
+}
+
+TESTSUITE01(43){
+ CLEANENV(GENERAL_TEST_POLICY_UNDETERMIND);
+ //Test undetermined, we have to refine this tests to test something
+ //undetermined
+ //QA(1, "version", "undetermined", true);
+ QU(1, "s32.2.1", "device:pim.contacts");
+ QC(1, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(44){
+ CLEANENV(GENERAL_TEST_POLICY_UNDETERMIND);
+ //Test undetermined, we have to refine this tests to test something
+ //undetermined
+ //QA(1, "version", "undetermined", true);
+ QU(1, "s32.2.2", "device:pim.contacts");
+ QC(1, PolicyResult::UNDETERMINED);
+}
+
+TESTSUITE01(45){
+ CLEANENV(GENERAL_TEST_POLICY_UNDETERMIND);
+ //Test undetermined, we have to refine this tests to test something
+ //undetermined
+ //QA(1, "version", "undetermined", true);
+ QU(1, "s32.3", "device:pim.contacts");
+ QC(1, PolicyResult::UNDETERMINED);
+}
+
+TESTSUITE01(46){
+ CLEANENV(GENERAL_TEST_POLICY_UNDETERMIND);
+ //Test undetermined, we have to refine this tests to test something
+ //undetermined
+ //QA(1, "version", "undetermined", true);
+ QU(1, "s33.1", "device:pim.contacts");
+ QC(1, PolicyResult::UNDETERMINED);
+}
+
+TESTSUITE01(47){
+ CLEANENV(GENERAL_TEST_POLICY_UNDETERMIND);
+ //Test undetermined, we have to refine this tests to test something
+ //undetermined
+ //QA(1, "version", "undetermined", true);
+ QU(1, "s33.2", "device:pim.contacts");
+ QC(1, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(48){
+ CLEANENV(GENERAL_TEST_POLICY_UNDETERMIND);
+ //Test undetermined, we have to refine this tests to test something
+ //undetermined
+ //QA(1, "version", "undetermined", true);
+ QU(1, "s33.3", "device:pim.contacts");
+ QC(1, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(49){
+ CLEANENV(GENERAL_TEST_POLICY_UNDETERMIND);
+ //Test undetermined, we have to refine this tests to test something
+ //undetermined
+ //QA(1, "version", "undetermined", true);
+ QU(1, "s34.1", "device:pim.contacts");
+ QC(1, PolicyResult::UNDETERMINED);
+}
+
+TESTSUITE01(50){
+ CLEANENV(GENERAL_TEST_POLICY_UNDETERMIND);
+ //undetermined
+ //QA(1, "version", "undetermined", true);
+ QU(1, "s34.2", "device:pim.contacts");
+ QC(1, PolicyResult::UNDETERMINED);
+}
+
+TESTSUITE01(51){
+ CLEANENV(GENERAL_TEST_POLICY_UNDETERMIND);
+ //undetermined
+ //QA(1, "version", "undetermined", true);
+ QU(1, "s35.1", "device:pim.contacts");
+ QC(1, PolicyResult::UNDETERMINED);
+}
+
+TESTSUITE01(52){
+ CLEANENV(GENERAL_TEST_POLICY_UNDETERMIND);
+ //undetermined
+ //QA(1, "version", "undetermined", true);
+ QU(1, "s35.2", "device:pim.contacts");
+ QC(1, PolicyResult::UNDETERMINED);
+}
+
+TESTSUITE01(53){
+ CLEANENV(GENERAL_TEST_POLICY_UNDETERMIND);
+ QU(1, "s36", "device:pim.contacts");
+ //undetermined
+ //QA(1, "version", "undetermined", true);
+ QC(1, PolicyDecision::NOT_APPLICABLE);
+}
+
+TESTSUITE01(54){
+ CLEANENV(GENERAL_TEST_POLICY);
+ QU(1, "s37", "device:pim.contacts.read");
+ QC(1, PolicyEffect::PROMPT_ONESHOT);
+}
+
+TESTSUITE01(55){
+ CLEANENV(GENERAL_TEST_POLICY);
+
+ QU(1, "s38", "device:pim.contacts.read");
+ QC(1, PolicyEffect::PROMPT_SESSION);
+
+ QU(2, "s38.4", "device:pim.contacts.read");
+ QC(2, PolicyEffect::PROMPT_SESSION);
+}
+
+TESTSUITE01(56){
+ CLEANENV(GENERAL_TEST_POLICY);
+
+ QU(1, "s39", "device:pim.contacts.read");
+ QC(1, PolicyEffect::PROMPT_BLANKET);
+
+ QU(2, "s39.4", "device:pim.contacts.read");
+ QC(2, PolicyEffect::PROMPT_BLANKET);
+}
+
+TESTSUITE01(57){
+ CLEANENV(GENERAL_TEST_POLICY);
+ QU(1, "s40", "r40");
+ QC(1, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(58){
+ CLEANENV(GENERAL_TEST_POLICY);
+ QU(1, "s41", "r41");
+ QC(1, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(59){
+ CLEANENV(GENERAL_TEST_POLICY);
+ QU(1, "s42.1", "r42.1");
+ QC(1, PolicyEffect::DENY);
+}
+
+TESTSUITE01(60){
+ CLEANENV(GENERAL_TEST_POLICY);
+ QU(1, "s42.2", "r42.2");
+ QC(1, PolicyEffect::DENY);
+
+}
+
+TESTSUITE01(61){
+ CLEANENV(GENERAL_TEST_POLICY);
+ QU(1, "s43.1", "r43.1");
+ QC(1, PolicyEffect::DENY);
+}
+
+TESTSUITE01(62){
+ CLEANENV(GENERAL_TEST_POLICY);
+ QU(1, "s43.2", "r43.2");
+ QC(1, PolicyEffect::DENY);
+}
+
+TESTSUITE01(63){
+ CLEANENV(GENERAL_TEST_POLICY);
+ QU(1, "s44.1", "r44.1");
+ QC(1, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(64){
+ CLEANENV(GENERAL_TEST_POLICY);
+ QU(1, "s44.2", "r44.2");
+ QC(1, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(65){
+ CLEANENV(GENERAL_TEST_POLICY);
+ QU(1, "s45.1", "r45.1");
+ QC(1, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(66){
+ CLEANENV(GENERAL_TEST_POLICY);
+ QU(1, "s45.2", "r45.2");
+ QC(1, PolicyEffect::DENY);
+}
+
+TESTSUITE01(67){
+ CLEANENV(GENERAL_TEST_POLICY);
+ QU(1, "s46.1", "r46.1");
+ QC(1, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(68){
+ CLEANENV(GENERAL_TEST_POLICY);
+ QU(1, "s46.2", "r46.2");
+ QC(1, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(69){
+ CLEANENV(GENERAL_TEST_POLICY);
+ QU(1, "s47.1", "r47.1");
+ QC(1, PolicyEffect::DENY);
+}
+
+TESTSUITE01(70){
+ CLEANENV(GENERAL_TEST_POLICY);
+ QU(1, "s47.2", "r47.2");
+ QC(1, PolicyEffect::DENY);
+}
+
+TESTSUITE01(71){
+ CLEANENV(GENERAL_TEST_POLICY);
+ QU(1, "s48", "device:pim.contacts");
+ QA(1, "uri", "http://www.test.pl:80");
+ QC(1, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(72){
+ CLEANENV(GENERAL_TEST_POLICY);
+ QU(1, "BF00", "BFR00");
+ QC(1, PolicyEffect::DENY);
+}
+
+TESTSUITE01(73){
+ CLEANENV(GENERAL_TEST_POLICY);
+ QU(1, "BF01", "BFR01");
+ QC(1, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(74){
+ CLEANENV(GENERAL_TEST_POLICY);
+ QU(1, "BF02", "BFR02");
+ QC(1, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(75){
+ CLEANENV(GENERAL_TEST_POLICY);
+ QU(1, "BF03", "BFR03");
+ QC(1, PolicyEffect::DENY);
+}
+
+TESTSUITE01(76){
+ CLEANENV(GENERAL_TEST_POLICY);
+ QU(1, "BF04", "BFR04");
+ QC(1, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(77){
+ CLEANENV(GENERAL_TEST_POLICY);
+ FunctionParamImpl functionParam;
+ functionParam.addAttribute("param:recipients","+44091234");
+ QU(1, "paramTestSubject", "resource");
+ QA(1, "dev-cap","messaging");
+ QCP(1, &functionParam, PolicyEffect::DENY);
+}
+
+TESTSUITE01(78){
+ CLEANENV(GENERAL_TEST_POLICY);
+ FunctionParamImpl functionParam;
+ functionParam.addAttribute("param:recipients","+44081234");
+ QU(1, "paramTestSubject", "resource");
+ QA(1, "dev-cap","messaging");
+ QCP(1, &functionParam, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(79){
+ CLEANENV(GENERAL_TEST_POLICY);
+ FunctionParamImpl functionParam;
+ functionParam.addAttribute("param:recipients","+4812345656");
+ QU(1, "paramTestSubject", "resource");
+ QA(1, "dev-cap","messaging");
+ QCP(1, &functionParam, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(80){
+ CLEANENV(GENERAL_TEST_POLICY);
+ FunctionParamImpl functionParam;
+ functionParam.addAttribute("param:quality","low");
+ QU(1, "paramTestSubject", "resource");
+ QA(1, "dev-cap","messaging");
+ QCP(1, &functionParam, PolicyDecision::NOT_APPLICABLE);
+}
+
+TESTSUITE01(81){
+ CLEANENV(GENERAL_TEST_POLICY);
+ FunctionParamImpl functionParam;
+ functionParam.addAttribute("param:quality", "high");
+ QU(1, "paramTestSubject", "resource");
+ QA(1, "dev-cap","camera");
+ QCP(1, &functionParam, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(82){
+ CLEANENV(GENERAL_TEST_POLICY);
+
+ QU(1, "s61a", "r61a");
+ QC(1, PolicyEffect::DENY);
+
+ FunctionParamImpl functionParam;
+ functionParam.addAttribute("param:name", "type");
+ QU(2, "s61b", "r61b");
+ QCP(2, &functionParam, PolicyEffect::PERMIT);
+
+ QU(3, "s61c", "r61c");
+ QC(3, PolicyEffect::DENY);
+
+ FunctionParamImpl functionParam4;
+ functionParam4.addAttribute("param:name", "type");
+ functionParam4.addAttribute("param:name", "port");
+ QU(4, "s61d", "r61d");
+ QCP(4, &functionParam4, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(83){
+ CLEANENV(GENERAL_TEST_POLICY_TEST);
+
+ PermissionList sList;
+ sList.push_back(PermissionTriple(1, "b1", Preference::PREFERENCE_PERMIT));
+ sList.push_back(PermissionTriple(2, "bb2", Preference::PREFERENCE_DENY));
+ sList.push_back(PermissionTriple(3, "d3", Preference::PREFERENCE_DEFAULT));
+ SettingsLogic::setWidgetDevCapSettings(sList);
+
+ QU(1, "a1", "b1");
+ QC(1, PolicyEffect::DENY);
+
+ QU(2, "aa2", "bb2");
+ QC(2, PolicyEffect::DENY);
+
+ QU(3, "c3", "d3");
+ QC(3, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(84){
+ CLEANENV(GENERAL_TEST_POLICY_TEST);
+ PermissionList sList;
+ sList.push_back(PermissionTriple(3, "d3", Preference::PREFERENCE_ONE_SHOT_PROMPT));
+ SettingsLogic::setWidgetDevCapSettings(sList);
+ QU(3, "c3", "d3");
+ QC(3, PolicyEffect::PROMPT_ONESHOT);
+}
+
+TESTSUITE01(85){
+ CLEANENV(GENERAL_TEST_POLICY_TEST);
+
+ PermissionList sList;
+ sList.push_back(PermissionTriple(1, "bnp", Preference::PREFERENCE_DEFAULT));
+ sList.push_back(PermissionTriple(2, "bbnp", Preference::PREFERENCE_DENY));
+ sList.push_back(PermissionTriple(3, "dnp", Preference::PREFERENCE_PERMIT));
+
+ SettingsLogic::setWidgetDevCapSettings(sList);
+
+ QU(1, "anp", "bnp");
+ QC(1, PolicyDecision::NOT_APPLICABLE);
+
+ QU(2, "aanp", "bbnp");
+ QC(2, PolicyEffect::DENY);
+
+ QU(3, "cnp", "dnp");
+ QC(3, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(86){
+ CLEANENV(GENERAL_TEST_POLICY_TEST);
+
+ PermissionList sList;
+ sList.push_back(PermissionTriple(1, "b1", Preference::PREFERENCE_DEFAULT));
+ sList.push_back(PermissionTriple(2, "bb", Preference::PREFERENCE_DENY));
+ sList.push_back(PermissionTriple(3, "d3", Preference::PREFERENCE_PERMIT));
+ sList.push_back(PermissionTriple(4, "b1", Preference::PREFERENCE_PERMIT));
+ sList.push_back(PermissionTriple(5, "bb2", Preference::PREFERENCE_DENY));
+ sList.push_back(PermissionTriple(6, "d3", Preference::PREFERENCE_DEFAULT));
+
+ SettingsLogic::setWidgetDevCapSettings(sList);
+
+ QU(1, "a1", "b1");
+ QC(1, PolicyEffect::DENY);
+
+ QU(2, "aa", "bb");
+ QC(2, PolicyEffect::DENY);
+
+ QU(3, "c3", "d3");
+ QC(3, PolicyEffect::PERMIT);
+
+ QU(5, "aa2", "bb2");
+ QC(5, PolicyEffect::DENY);
+}
+
+TESTSUITE01(87){
+ CLEANENV(GENERAL_TEST_POLICY_TEST);
+
+ QU(1, "c3", "d3");
+ QC(1, PolicyEffect::PERMIT);
+
+ QU(2, "aa2", "bb2");
+ QC(2, PolicyEffect::PERMIT);
+
+ SettingsLogic::updateDevCapSetting("d3", Preference::PREFERENCE_DENY);
+ SettingsLogic::updateDevCapSetting("bb2", Preference::PREFERENCE_DEFAULT);
+
+ QC(1, PolicyEffect::DENY);
+
+ QC(2, PolicyEffect::PERMIT);
+
+ SettingsLogic::updateDevCapSetting("d3", Preference::PREFERENCE_PERMIT);
+
+ QC(1, PolicyEffect::PERMIT);
+}
+
+TESTSUITE01(88){
+ CLEANENV(GENERAL_TEST_POLICY_GSETTINGS);
+ std::string d3("d3");
+
+ QU(1, "c3", "d3");
+ QC(1, PolicyEffect::PERMIT);
+
+ QU(2, "aa2", "bb2");
+ QC(2, PolicyEffect::PERMIT);
+
+ QU(3, "a1", "d3");
+ QC(3, PolicyEffect::DENY);
+
+ SettingsLogic::updateDevCapSetting(d3, Preference::PREFERENCE_DEFAULT);
+
+ QC(1, PolicyEffect::PERMIT);
+
+ QC(2, PolicyEffect::PERMIT);
+
+ QC(3, PolicyEffect::DENY);
+
+ SettingsLogic::updateDevCapSetting(d3, Preference::PREFERENCE_DENY);
+
+ QC(1, PolicyEffect::DENY);
+
+ QC(3, PolicyEffect::DENY);
+
+ SettingsLogic::updateDevCapSetting(d3, Preference::PREFERENCE_PERMIT);
+
+ QC(1, PolicyEffect::PERMIT);
+
+ QC(3, PolicyEffect::DENY);
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file TestSuite02.cpp
+ * @author unknown
+ * @version 1.0
+ * @brief Test cases for Attribute class.
+ */
+#include <string>
+
+#include <dpl/log/log.h>
+#include <dpl/test/test_runner.h>
+
+#include <dpl/ace/Attribute.h>
+#include <dpl/ace-dao-ro/BaseAttribute.h>
+
+#include <dpl/ace/PolicyEvaluator.h>
+
+#include "PEPSingleton.h"
+
+#define POLICY_ATTR_EXAMPLE "/usr/etc/ace/attr_policy-example.xml"
+#define POLICY_ATTR_EXAMPLE1 "/usr/etc/ace/attr_policy-example1.xml"
+#define POLICY_ATTR_EXAMPLE2 "/usr/etc/ace/attr_policy-example2.xml"
+#define POLICY_ATTR_EXAMPLE3 "/usr/etc/ace/attr_policy-example3.xml"
+#define POLICY_ATTR_EXAMPLE4 "/usr/etc/ace/attr_policy-example4.xml"
+#define POLICY_ATTR_EXAMPLE5 "/usr/etc/ace/attr_policy-example5.xml"
+#define POLICY_ATTR_EXAMPLE6 "/usr/etc/ace/attr_policy-example6.xml"
+#define POLICY_ATTR_EXAMPLE7 "/usr/etc/ace/attr_policy-example7.xml"
+#define POLICY_ATTR_EXAMPLE8 "/usr/etc/ace/attr_policy-example8.xml"
+
+#define CLEANENV(d) \
+ do{ \
+ if (PEPSingleton::Instance().getPdp()->getCurrentPolicy() != (d)) { \
+ PEPSingleton::Instance().getPdp()->updatePolicy(d); \
+ } \
+ }while(0)
+
+#define PEPTR PEPSingleton::Instance().getPdp()
+
+#define TESTSUITE02(n) \
+RUNNER_TEST(ts02_extract_attributes_tests_ ## n)
+
+using namespace AceDB;
+
+bool AttrEqual(const AttributeSet &actual, AttributeSet * expected)
+{
+ bool match = false;
+ for (AttributeSet::const_iterator ita = actual.begin();
+ ita != actual.end();
+ ++ita)
+ {
+ match = false;
+ for (AttributeSet::const_iterator ite = expected->begin();
+ ite != expected->end();
+ ++ite)
+ {
+ if ((*(*ita)->getName() == *(*ite)->getName()) &&
+ ((*ita)->getType() == (*ite)->getType()))
+ {
+ match = true;
+ }
+ }
+ if (!match)
+ {
+ LogError("Not found " <<
+ *(*ita)->getName() <<
+ " " << static_cast<int>((*ita)->getType()));
+ return false;
+ }
+ }
+ return true;
+}
+
+TESTSUITE02(01){
+ CLEANENV(POLICY_ATTR_EXAMPLE);
+
+ AttributeSet attrSet;
+ std::string n1("name");
+ BaseAttributePtr a1(new Attribute(&n1,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a1);
+
+
+ std::string n2("resource-id");
+ BaseAttributePtr a2(new Attribute(&n2,
+ Attribute::Match::Equal,
+ Attribute::Type::Resource));
+ attrSet.insert(a2);
+
+ PEPTR->extractAttributesTest();
+
+ bool result = AttrEqual(attrSet, PEPTR->getAttributeSet());
+ RUNNER_ASSERT(result);
+}
+
+TESTSUITE02(02){
+ CLEANENV(POLICY_ATTR_EXAMPLE1);
+
+ AttributeSet attrSet;
+
+ std::string n3("uri.host");
+ BaseAttributePtr a3(new Attribute(&n3,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a3);
+
+ std::string n4("key-root-trust");
+ BaseAttributePtr a4(new Attribute(&n4,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a4);
+
+ std::string n5("id");
+ BaseAttributePtr a5(new Attribute(&n5,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a5);
+
+ std::string n6("signer-id");
+ BaseAttributePtr a6(new Attribute(&n6,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a6);
+
+ std::string n7("version");
+ BaseAttributePtr a7(new Attribute(&n7,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a7);
+
+ std::string n8("r8v2");
+ BaseAttributePtr a8(new Attribute(&n8,
+ Attribute::Match::Equal,
+ Attribute::Type::Resource));
+ attrSet.insert(a8);
+
+ std::string n9("author");
+ BaseAttributePtr a9(new Attribute(&n9,
+ Attribute::Match::Equal,
+ Attribute::Type::Resource));
+ attrSet.insert(a9);
+
+ std::string n10("r9a.scheme");
+ BaseAttributePtr a10(new Attribute(&n10,
+ Attribute::Match::Equal,
+ Attribute::Type::Resource));
+ attrSet.insert(a10);
+
+ std::string n11("r9b.authority");
+ BaseAttributePtr a11(new Attribute(&n11,
+ Attribute::Match::Equal,
+ Attribute::Type::Resource));
+ attrSet.insert(a11);
+
+ std::string n12("r9c.scheme-authority");
+ BaseAttributePtr a12(new Attribute(&n12,
+ Attribute::Match::Equal,
+ Attribute::Type::Resource));
+ attrSet.insert(a12);
+
+ PEPTR->extractAttributesTest();
+
+ bool result = AttrEqual(attrSet, PEPTR->getAttributeSet());
+ RUNNER_ASSERT(result);
+}
+
+TESTSUITE02(03){
+ CLEANENV(POLICY_ATTR_EXAMPLE2);
+
+ AttributeSet attrSet;
+
+ std::string n1("id");
+ BaseAttributePtr a1(new Attribute(&n1,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a1);
+
+ std::string n3("version");
+ BaseAttributePtr a3(new Attribute(&n3,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a3);
+
+ std::string n2("resource-id");
+ BaseAttributePtr a2(new Attribute(&n2,
+ Attribute::Match::Equal,
+ Attribute::Type::Resource));
+ attrSet.insert(a2);
+
+ std::string n4("author");
+ BaseAttributePtr a4(new Attribute(&n4,
+ Attribute::Match::Equal,
+ Attribute::Type::Resource));
+ attrSet.insert(a4);
+
+ PEPTR->extractAttributesTest();
+
+ bool result = AttrEqual(attrSet, PEPTR->getAttributeSet());
+ RUNNER_ASSERT(result);
+}
+
+TESTSUITE02(04){
+ CLEANENV(POLICY_ATTR_EXAMPLE3);
+
+ AttributeSet attrSet;
+
+ std::string n1("id");
+ BaseAttributePtr a1(new Attribute(&n1,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a1);
+
+ std::string n3("version");
+ BaseAttributePtr a3(new Attribute(&n3,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a3);
+
+ std::string n2("resource-id");
+ BaseAttributePtr a2(new Attribute(&n2,
+ Attribute::Match::Equal,
+ Attribute::Type::Resource));
+ attrSet.insert(a2);
+
+ std::string n4("author");
+ BaseAttributePtr a4(new Attribute(&n4,
+ Attribute::Match::Equal,
+ Attribute::Type::Resource));
+ attrSet.insert(a4);
+
+ PEPTR->extractAttributesTest();
+
+ bool result = AttrEqual(attrSet, PEPTR->getAttributeSet());
+ RUNNER_ASSERT(result);
+}
+
+TESTSUITE02(05){
+ CLEANENV(POLICY_ATTR_EXAMPLE4);
+
+ AttributeSet attrSet;
+
+ std::string n1("id");
+ BaseAttributePtr a1(new Attribute(&n1,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a1);
+
+ std::string n3("version");
+ BaseAttributePtr a3(new Attribute(&n3,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a3);
+
+
+ std::string n2("resource-id");
+ BaseAttributePtr a2(new Attribute(&n2,
+ Attribute::Match::Equal,
+ Attribute::Type::Resource));
+ attrSet.insert(a2);
+
+ std::string n4("author");
+ BaseAttributePtr a4(new Attribute(&n4,
+ Attribute::Match::Equal,
+ Attribute::Type::Resource));
+ attrSet.insert(a4);
+
+ std::string n5("author");
+ BaseAttributePtr a5(new Attribute(&n5,
+ Attribute::Match::Equal,
+ Attribute::Type::Environment));
+ attrSet.insert(a5);
+
+ std::string n6("version");
+ BaseAttributePtr a6(new Attribute(&n6,
+ Attribute::Match::Equal,
+ Attribute::Type::Environment));
+ attrSet.insert(a6);
+
+ std::string n7("ver");
+ BaseAttributePtr a7(new Attribute(&n7,
+ Attribute::Match::Equal,
+ Attribute::Type::Environment));
+ attrSet.insert(a7);
+
+ PEPTR->extractAttributesTest();
+
+ bool result = AttrEqual(attrSet, PEPTR->getAttributeSet());
+ RUNNER_ASSERT(result);
+}
+
+TESTSUITE02(06){
+ CLEANENV(POLICY_ATTR_EXAMPLE5);
+
+ AttributeSet attrSet;
+
+ std::string n3("uri.host");
+ BaseAttributePtr a3(new Attribute(&n3,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a3);
+
+ std::string n4("key-root-trust");
+ BaseAttributePtr a4(new Attribute(&n4,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a4);
+
+ std::string n5("id");
+ BaseAttributePtr a5(new Attribute(&n5,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a5);
+
+ std::string n6("signer-id");
+ BaseAttributePtr a6(new Attribute(&n6,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a6);
+
+ std::string n7("version");
+ BaseAttributePtr a7(new Attribute(&n7,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a7);
+
+ std::string n13("name");
+ BaseAttributePtr a13(new Attribute(&n13,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a13);
+
+ std::string n14("resource-id");
+ BaseAttributePtr a14(new Attribute(&n14,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a14);
+
+ std::string n15("r8v2");
+ BaseAttributePtr a15(new Attribute(&n15,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a15);
+
+ std::string n16("author");
+ BaseAttributePtr a16(new Attribute(&n16,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a16);
+
+ std::string n17("r9a.scheme");
+ BaseAttributePtr a17(new Attribute(&n17,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a17);
+
+ std::string n18("r9b.authority");
+ BaseAttributePtr a18(new Attribute(&n18,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a18);
+
+ std::string n19("r9c.scheme-authority");
+ BaseAttributePtr a19(new Attribute(&n19,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a19);
+
+ std::string n20("resource-id");
+ BaseAttributePtr a20(new Attribute(&n20,
+ Attribute::Match::Equal,
+ Attribute::Type::Resource));
+ attrSet.insert(a20);
+
+ std::string n8("r8v2");
+ BaseAttributePtr a8(new Attribute(&n8,
+ Attribute::Match::Equal,
+ Attribute::Type::Resource));
+ attrSet.insert(a8);
+
+ std::string n9("author");
+ BaseAttributePtr a9(new Attribute(&n9,
+ Attribute::Match::Equal,
+ Attribute::Type::Resource));
+ attrSet.insert(a9);
+
+ std::string n10("r9a.scheme");
+ BaseAttributePtr a10(new Attribute(&n10,
+ Attribute::Match::Equal,
+ Attribute::Type::Resource));
+ attrSet.insert(a10);
+
+ std::string n11("r9b.authority");
+ BaseAttributePtr a11(new Attribute(&n11,
+ Attribute::Match::Equal,
+ Attribute::Type::Resource));
+ attrSet.insert(a11);
+
+ std::string n12("r9c.scheme-authority");
+ BaseAttributePtr a12(new Attribute(&n12,
+ Attribute::Match::Equal,
+ Attribute::Type::Resource));
+ attrSet.insert(a12);
+
+ std::string n21("resource-id");
+ BaseAttributePtr a21(new Attribute(&n21,
+ Attribute::Match::Equal,
+ Attribute::Type::Environment));
+ attrSet.insert(a21);
+
+ std::string n22("r8v2");
+ BaseAttributePtr a22(new Attribute(&n22,
+ Attribute::Match::Equal,
+ Attribute::Type::Environment));
+ attrSet.insert(a22);
+
+ std::string n23("author");
+ BaseAttributePtr a23(new Attribute(&n23,
+ Attribute::Match::Equal,
+ Attribute::Type::Environment));
+ attrSet.insert(a23);
+
+ std::string n24("r9a.scheme");
+ BaseAttributePtr a24(new Attribute(&n24,
+ Attribute::Match::Equal,
+ Attribute::Type::Environment));
+ attrSet.insert(a24);
+
+ std::string n25("r9b.authority");
+ BaseAttributePtr a25(new Attribute(&n25,
+ Attribute::Match::Equal,
+ Attribute::Type::Environment));
+ attrSet.insert(a25);
+
+ std::string n26("r9c.scheme-authority");
+ BaseAttributePtr a26(new Attribute(&n26,
+ Attribute::Match::Equal,
+ Attribute::Type::Environment));
+ attrSet.insert(a26);
+
+ PEPTR->extractAttributesTest();
+
+ bool result = AttrEqual(attrSet, PEPTR->getAttributeSet());
+ RUNNER_ASSERT(result);
+}
+
+TESTSUITE02(07){
+ CLEANENV(POLICY_ATTR_EXAMPLE6);
+
+ AttributeSet attrSet;
+
+ std::string n3("s-uri.host");
+ BaseAttributePtr a3(new Attribute(&n3,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a3);
+
+ std::string n4("s-key-root-trust");
+ BaseAttributePtr a4(new Attribute(&n4,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a4);
+
+ std::string n5("s-id");
+ BaseAttributePtr a5(new Attribute(&n5,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a5);
+
+ std::string n6("s-signer-id");
+ BaseAttributePtr a6(new Attribute(&n6,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a6);
+
+ std::string n7("s-version");
+ BaseAttributePtr a7(new Attribute(&n7,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a7);
+
+ std::string n13("s-name");
+ BaseAttributePtr a13(new Attribute(&n13,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a13);
+
+ std::string n14("s-resource-id");
+ BaseAttributePtr a14(new Attribute(&n14,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a14);
+
+ std::string n15("s-r8v2");
+ BaseAttributePtr a15(new Attribute(&n15,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a15);
+
+ std::string n16("s-author");
+ BaseAttributePtr a16(new Attribute(&n16,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a16);
+
+ std::string n17("s-r9a.scheme");
+ BaseAttributePtr a17(new Attribute(&n17,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a17);
+
+ std::string n18("s-r9b.authority");
+ BaseAttributePtr a18(new Attribute(&n18,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a18);
+
+ std::string n19("s-r9c.scheme-authority");
+ BaseAttributePtr a19(new Attribute(&n19,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a19);
+
+ std::string n20("r-resource-id");
+ BaseAttributePtr a20(new Attribute(&n20,
+ Attribute::Match::Equal,
+ Attribute::Type::Resource));
+ attrSet.insert(a20);
+
+ std::string n8("r-r8v2");
+ BaseAttributePtr a8(new Attribute(&n8,
+ Attribute::Match::Equal,
+ Attribute::Type::Resource));
+ attrSet.insert(a8);
+
+ std::string n9("r-author");
+ BaseAttributePtr a9(new Attribute(&n9,
+ Attribute::Match::Equal,
+ Attribute::Type::Resource));
+ attrSet.insert(a9);
+
+ std::string n10("r-r9a.scheme");
+ BaseAttributePtr a10(new Attribute(&n10,
+ Attribute::Match::Equal,
+ Attribute::Type::Resource));
+ attrSet.insert(a10);
+
+ std::string n11("r-r9b.authority");
+ BaseAttributePtr a11(new Attribute(&n11,
+ Attribute::Match::Equal,
+ Attribute::Type::Resource));
+ attrSet.insert(a11);
+
+ std::string n12("r-r9c.scheme-authority");
+ BaseAttributePtr a12(new Attribute(&n12,
+ Attribute::Match::Equal,
+ Attribute::Type::Resource));
+ attrSet.insert(a12);
+
+ std::string n21("e-resource-id");
+ BaseAttributePtr a21(new Attribute(&n21,
+ Attribute::Match::Equal,
+ Attribute::Type::Environment));
+ attrSet.insert(a21);
+
+ std::string n22("e-r8v2");
+ BaseAttributePtr a22(new Attribute(&n22,
+ Attribute::Match::Equal,
+ Attribute::Type::Environment));
+ attrSet.insert(a22);
+
+ std::string n23("e-author");
+ BaseAttributePtr a23(new Attribute(&n23,
+ Attribute::Match::Equal,
+ Attribute::Type::Environment));
+ attrSet.insert(a23);
+
+ std::string n24("e-r9a.scheme");
+ BaseAttributePtr a24(new Attribute(&n24,
+ Attribute::Match::Equal,
+ Attribute::Type::Environment));
+ attrSet.insert(a24);
+
+ std::string n25("e-r9b.authority");
+ BaseAttributePtr a25(new Attribute(&n25,
+ Attribute::Match::Equal,
+ Attribute::Type::Environment));
+ attrSet.insert(a25);
+
+ std::string n26("e-r9c.scheme-authority");
+ BaseAttributePtr a26(new Attribute(&n26,
+ Attribute::Match::Equal,
+ Attribute::Type::Environment));
+ attrSet.insert(a26);
+
+ PEPTR->extractAttributesTest();
+
+ bool result = AttrEqual(attrSet, PEPTR->getAttributeSet());
+ RUNNER_ASSERT(result);
+}
+
+TESTSUITE02(08){
+ CLEANENV(POLICY_ATTR_EXAMPLE2);
+
+ AttributeSet attrSet;
+
+ std::string n1("id");
+ BaseAttributePtr a1(new Attribute(&n1,
+ Attribute::Match::Glob,
+ Attribute::Type::Subject));
+ attrSet.insert(a1);
+
+ std::string n3("version");
+ BaseAttributePtr a3(new Attribute(&n3,
+ Attribute::Match::Glob,
+ Attribute::Type::Subject));
+ attrSet.insert(a3);
+
+
+ std::string n2("resource-id");
+ BaseAttributePtr a2(new Attribute(&n2,
+ Attribute::Match::Glob,
+ Attribute::Type::Resource));
+ attrSet.insert(a2);
+
+ std::string n4("author");
+ BaseAttributePtr a4(new Attribute(&n4,
+ Attribute::Match::Glob,
+ Attribute::Type::Resource));
+ attrSet.insert(a4);
+
+ PEPTR->extractAttributesTest();
+
+ bool result = AttrEqual(attrSet, PEPTR->getAttributeSet());
+ RUNNER_ASSERT(result);
+}
+
+TESTSUITE02(09){
+ CLEANENV(POLICY_ATTR_EXAMPLE2);
+
+ AttributeSet attrSet;
+
+ std::string n1("id");
+ BaseAttributePtr a1(new Attribute(&n1,
+ Attribute::Match::Regexp,
+ Attribute::Type::Subject));
+ attrSet.insert(a1);
+
+ std::string n3("version");
+ BaseAttributePtr a3(new Attribute(&n3,
+ Attribute::Match::Regexp,
+ Attribute::Type::Subject));
+ attrSet.insert(a3);
+
+
+ std::string n2("resource-id");
+ BaseAttributePtr a2(new Attribute(&n2,
+ Attribute::Match::Regexp,
+ Attribute::Type::Resource));
+ attrSet.insert(a2);
+
+ std::string n4("author");
+ BaseAttributePtr a4(new Attribute(&n4,
+ Attribute::Match::Regexp,
+ Attribute::Type::Resource));
+ attrSet.insert(a4);
+
+ PEPTR->extractAttributesTest();
+
+ bool result = AttrEqual(attrSet, PEPTR->getAttributeSet());
+ RUNNER_ASSERT(result);
+}
+
+TESTSUITE02(10){
+ CLEANENV(POLICY_ATTR_EXAMPLE2);
+
+ AttributeSet attrSet;
+
+ std::string n1("id");
+ BaseAttributePtr a1(new Attribute(&n1,
+ Attribute::Match::Regexp,
+ Attribute::Type::Subject));
+ attrSet.insert(a1);
+
+ std::string n3("version");
+ BaseAttributePtr a3(new Attribute(&n3,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a3);
+
+
+ std::string n2("resource-id");
+ BaseAttributePtr a2(new Attribute(&n2,
+ Attribute::Match::Glob,
+ Attribute::Type::Resource));
+ attrSet.insert(a2);
+
+ std::string n4("author");
+ BaseAttributePtr a4(new Attribute(&n4,
+ Attribute::Match::Regexp,
+ Attribute::Type::Resource));
+ attrSet.insert(a4);
+
+ PEPTR->extractAttributesTest();
+
+ bool result = AttrEqual(attrSet, PEPTR->getAttributeSet());
+ RUNNER_ASSERT(result);
+}
+
+TESTSUITE02(11){
+ CLEANENV(POLICY_ATTR_EXAMPLE7);
+
+ AttributeSet attrSet;
+
+ std::string n3("uri.host");
+ BaseAttributePtr a3(new Attribute(&n3,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a3);
+
+ std::string n4("key-root-trust");
+ BaseAttributePtr a4(new Attribute(&n4,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a4);
+
+ std::string n5("id");
+ BaseAttributePtr a5(new Attribute(&n5,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a5);
+
+ std::string n6("signer-id");
+ BaseAttributePtr a6(new Attribute(&n6,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a6);
+
+ std::string n7("version");
+ BaseAttributePtr a7(new Attribute(&n7,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a7);
+
+ std::string n13("name");
+ BaseAttributePtr a13(new Attribute(&n13,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a13);
+
+ std::string n14("resource-id");
+ BaseAttributePtr a14(new Attribute(&n14,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a14);
+
+ std::string n15("r8v2");
+ BaseAttributePtr a15(new Attribute(&n15,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a15);
+
+ std::string n16("author");
+ BaseAttributePtr a16(new Attribute(&n16,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a16);
+
+ std::string n17("r9a.scheme");
+ BaseAttributePtr a17(new Attribute(&n17,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a17);
+
+ std::string n18("r9b.authority");
+ BaseAttributePtr a18(new Attribute(&n18,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a18);
+
+ std::string n19("r9c.scheme-authority");
+ BaseAttributePtr a19(new Attribute(&n19,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a19);
+
+ std::string n20("resource-id");
+ BaseAttributePtr a20(new Attribute(&n20,
+ Attribute::Match::Equal,
+ Attribute::Type::Resource));
+ attrSet.insert(a20);
+
+ std::string n8("r8v2");
+ BaseAttributePtr a8(new Attribute(&n8,
+ Attribute::Match::Equal,
+ Attribute::Type::Resource));
+ attrSet.insert(a8);
+
+ std::string n9("author");
+ BaseAttributePtr a9(new Attribute(&n9,
+ Attribute::Match::Equal,
+ Attribute::Type::Resource));
+ attrSet.insert(a9);
+
+ std::string n10("r9a.scheme");
+ BaseAttributePtr a10(new Attribute(&n10,
+ Attribute::Match::Equal,
+ Attribute::Type::Resource));
+ attrSet.insert(a10);
+
+ std::string n11("r9b.authority");
+ BaseAttributePtr a11(new Attribute(&n11,
+ Attribute::Match::Equal,
+ Attribute::Type::Resource));
+ attrSet.insert(a11);
+
+ std::string n12("r9c.scheme-authority");
+ BaseAttributePtr a12(new Attribute(&n12,
+ Attribute::Match::Equal,
+ Attribute::Type::Resource));
+ attrSet.insert(a12);
+
+ std::string n21("resource-id");
+ BaseAttributePtr a21(new Attribute(&n21,
+ Attribute::Match::Equal,
+ Attribute::Type::Environment));
+ attrSet.insert(a21);
+
+ std::string n22("r8v2");
+ BaseAttributePtr a22(new Attribute(&n22,
+ Attribute::Match::Equal,
+ Attribute::Type::Environment));
+ attrSet.insert(a22);
+
+ std::string n23("author");
+ BaseAttributePtr a23(new Attribute(&n23,
+ Attribute::Match::Equal,
+ Attribute::Type::Environment));
+ attrSet.insert(a23);
+
+ std::string n24("r9a.scheme");
+ BaseAttributePtr a24(new Attribute(&n24,
+ Attribute::Match::Equal,
+ Attribute::Type::Environment));
+ attrSet.insert(a24);
+
+ std::string n25("r9b.authority");
+ BaseAttributePtr a25(new Attribute(&n25,
+ Attribute::Match::Equal,
+ Attribute::Type::Environment));
+ attrSet.insert(a25);
+
+ std::string n26("r9c.scheme-authority");
+ BaseAttributePtr a26(new Attribute(&n26,
+ Attribute::Match::Equal,
+ Attribute::Type::Environment));
+ attrSet.insert(a26);
+
+ PEPTR->extractAttributesTest();
+
+ bool result = AttrEqual(attrSet, PEPTR->getAttributeSet());
+ RUNNER_ASSERT(result);
+}
+
+TESTSUITE02(12){
+ CLEANENV(POLICY_ATTR_EXAMPLE8);
+
+ AttributeSet attrSet;
+
+ std::string n1("id");
+ BaseAttributePtr a1(new Attribute(&n1,
+ Attribute::Match::Regexp,
+ Attribute::Type::Subject));
+ attrSet.insert(a1);
+
+ std::string n3("version");
+ BaseAttributePtr a3(new Attribute(&n3,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ attrSet.insert(a3);
+
+
+ std::string n2("resource-id");
+ BaseAttributePtr a2(new Attribute(&n2,
+ Attribute::Match::Glob,
+ Attribute::Type::Resource));
+ attrSet.insert(a2);
+
+ std::string n4("author");
+ BaseAttributePtr a4(new Attribute(&n4,
+ Attribute::Match::Regexp,
+ Attribute::Type::Resource));
+ attrSet.insert(a4);
+
+ PEPTR->extractAttributesTest();
+
+ bool result = AttrEqual(attrSet, PEPTR->getAttributeSet());
+ RUNNER_ASSERT(result);
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file TestSuite03.cpp
+ * @author Piotr Fatyga (p.fatyga@samsung.com)
+ * @version 0.1
+ * @brief Test cases for Condition class.
+ */
+
+#include <string>
+
+#include <dpl/log/log.h>
+#include <dpl/test/test_runner.h>
+
+#include <dpl/ace/Attribute.h>
+#include <dpl/ace-dao-ro/BaseAttribute.h>
+#include <dpl/ace/Condition.h>
+
+#define TESTSUITE03(n) \
+RUNNER_TEST(ts03_condtitions_tests_ ## n)
+
+using namespace AceDB;
+
+BaseAttributePtr createAttribute(
+ const char *name,
+ const char * value,
+ const Attribute::Type type = Attribute::Type::Subject)
+{
+ std::string aName(name);
+ BaseAttributePtr attr(new Attribute(&aName, Attribute::Match::Equal, type));
+ if(value != NULL){
+ std::string aValue(value);
+ DPL::StaticPointerCast<Attribute>(attr)->addValue(&aValue);
+ }
+ return attr;
+}
+
+BaseAttributePtr createAttribute(
+ const char *name,
+ const char *value,
+ const char *value2,
+ const Attribute::Type type = Attribute::Type::Subject)
+{
+ std::string aName(name);
+ BaseAttributePtr attr(new Attribute(&aName, Attribute::Match::Equal, type));
+ if(value != NULL && value2 != NULL ){
+ std::string aValue(value), aValue2(value2);
+ DPL::StaticPointerCast<Attribute>(attr)->addValue(&aValue);
+ DPL::StaticPointerCast<Attribute>(attr)->addValue(&aValue2);
+ }
+ return attr;
+}
+
+
+bool MatchResultEqual(
+ Attribute::MatchResult actual,
+ Attribute::MatchResult expected)
+{
+ return actual == expected;
+}
+
+bool evaluateResult(
+ Condition con,
+ AttributeSet & attrs,
+ Attribute::MatchResult expectedResult)
+{
+ Attribute::MatchResult matchResult = con.evaluateCondition(&attrs);
+ return MatchResultEqual(matchResult ,expectedResult);
+}
+
+TESTSUITE03(01){
+ Condition con(Condition::OR);
+ AttributeSet attrSet;
+
+ BaseAttributePtr a1 = createAttribute("version","var1");
+ BaseAttributePtr a2 = createAttribute("r8v2","var2");
+ BaseAttributePtr a3 = createAttribute("author","va3");
+
+ con.addAttribute(*DPL::StaticPointerCast<Attribute>(a1));
+ con.addAttribute(*DPL::StaticPointerCast<Attribute>(a2));
+ con.addAttribute(*DPL::StaticPointerCast<Attribute>(a3));
+
+ attrSet.insert(a1);
+ attrSet.insert(a2);
+ attrSet.insert(a3);
+
+ RUNNER_ASSERT(
+ evaluateResult(con,attrSet,Attribute::MatchResult::MRTrue));
+}
+
+TESTSUITE03(02){
+ Condition con(Condition::AND);
+ AttributeSet attrSet;
+
+ BaseAttributePtr a1 = createAttribute("version","var1");
+ BaseAttributePtr a2 = createAttribute("r8v2","var2");
+ BaseAttributePtr a3 = createAttribute("author","va3");
+
+ con.addAttribute(*DPL::StaticPointerCast<Attribute>(a1));
+ con.addAttribute(*DPL::StaticPointerCast<Attribute>(a2));
+ con.addAttribute(*DPL::StaticPointerCast<Attribute>(a3));
+
+ attrSet.insert(a1);
+ attrSet.insert(a2);
+ attrSet.insert(a3);
+
+ RUNNER_ASSERT(
+ evaluateResult(con,attrSet,Attribute::MatchResult::MRTrue));
+}
+
+TESTSUITE03(03){
+ Condition con(Condition::OR);
+ AttributeSet attrSet;
+
+ BaseAttributePtr a1 = createAttribute("version","var1");
+ BaseAttributePtr a2 = createAttribute("r8v2","var2");
+ BaseAttributePtr a3 = createAttribute("author","va3");
+ BaseAttributePtr a4 = createAttribute("version","wrongValue");
+
+ con.addAttribute(*DPL::StaticPointerCast<Attribute>(a1));
+ con.addAttribute(*DPL::StaticPointerCast<Attribute>(a2));
+ con.addAttribute(*DPL::StaticPointerCast<Attribute>(a3));
+
+ attrSet.insert(a2);
+ attrSet.insert(a3);
+ attrSet.insert(a4);
+
+ RUNNER_ASSERT(
+ evaluateResult(con,attrSet,Attribute::MatchResult::MRTrue));
+}
+
+TESTSUITE03(04){
+ Condition con(Condition::AND);
+ AttributeSet attrSet;
+
+ BaseAttributePtr a1 = createAttribute("version","var1");
+ BaseAttributePtr a2 = createAttribute("r8v2","var2");
+ BaseAttributePtr a3 = createAttribute("author","va3");
+ BaseAttributePtr a4 = createAttribute("version","bad");
+ BaseAttributePtr a5 = createAttribute("version","var1", Attribute::Type::Resource);
+
+ con.addAttribute(*DPL::StaticPointerCast<Attribute>(a1));
+ con.addAttribute(*DPL::StaticPointerCast<Attribute>(a2));
+ con.addAttribute(*DPL::StaticPointerCast<Attribute>(a3));
+
+ attrSet.insert(a2);
+ attrSet.insert(a3);
+ attrSet.insert(a4);
+ attrSet.insert(a5);
+
+ RUNNER_ASSERT(
+ evaluateResult(con,attrSet,Attribute::MatchResult::MRFalse));
+}
+
+TESTSUITE03(05){
+ Condition con(Condition::OR);
+ AttributeSet attrSet;
+
+ BaseAttributePtr a1 = createAttribute("version","var1");
+ BaseAttributePtr a2 = createAttribute("r8v2","var2");
+ BaseAttributePtr a3 = createAttribute("author","va3");
+
+ BaseAttributePtr a4 = createAttribute("version","var1");
+ BaseAttributePtr a5 = createAttribute("r8v2","var2");
+ BaseAttributePtr a6 = createAttribute("author","va3");
+
+ con.addAttribute(*DPL::StaticPointerCast<Attribute>(a1));
+ con.addAttribute(*DPL::StaticPointerCast<Attribute>(a2));
+ con.addAttribute(*DPL::StaticPointerCast<Attribute>(a3));
+
+ attrSet.insert(a4);
+ attrSet.insert(a5);
+ attrSet.insert(a6);
+
+ RUNNER_ASSERT(
+ evaluateResult(con,attrSet,Attribute::MatchResult::MRTrue));
+}
+
+TESTSUITE03(06){
+ Condition con(Condition::OR);
+ AttributeSet attrSet;
+
+ BaseAttributePtr a1 = createAttribute("version","var1");
+ BaseAttributePtr a2 = createAttribute("r8v2","var2");
+ BaseAttributePtr a3 = createAttribute("author","va3");
+
+ BaseAttributePtr a4 = createAttribute("version","var2");
+ BaseAttributePtr a5 = createAttribute("r8v2","var3");
+ BaseAttributePtr a6 = createAttribute("author","va4");
+
+ con.addAttribute(*DPL::StaticPointerCast<Attribute>(a1));
+ con.addAttribute(*DPL::StaticPointerCast<Attribute>(a2));
+ con.addAttribute(*DPL::StaticPointerCast<Attribute>(a3));
+
+ attrSet.insert(a4);
+ attrSet.insert(a5);
+ attrSet.insert(a6);
+
+ RUNNER_ASSERT(
+ evaluateResult(con,attrSet,Attribute::MatchResult::MRFalse));
+}
+
+TESTSUITE03(07){
+ Condition con(Condition::OR);
+ AttributeSet attrSet;
+
+ BaseAttributePtr a1 = createAttribute("version","var1");
+ BaseAttributePtr a2 = createAttribute("r8v2","var2");
+ BaseAttributePtr a3 = createAttribute("author","va3");
+
+ BaseAttributePtr a4 = createAttribute("version","var1", Attribute::Type::Resource );
+ BaseAttributePtr a5 = createAttribute("r8v2","var2", Attribute::Type::Resource);
+ BaseAttributePtr a6 = createAttribute("author","va3", Attribute::Type::Resource);
+
+ BaseAttributePtr a7 = createAttribute("version","var2" );
+ BaseAttributePtr a8 = createAttribute("r8v2","var3");
+ BaseAttributePtr a9 = createAttribute("author","va4");
+
+ con.addAttribute(*DPL::StaticPointerCast<Attribute>(a1));
+ con.addAttribute(*DPL::StaticPointerCast<Attribute>(a2));
+ con.addAttribute(*DPL::StaticPointerCast<Attribute>(a3));
+
+ attrSet.insert(a4);
+ attrSet.insert(a5);
+ attrSet.insert(a6);
+ attrSet.insert(a7);
+ attrSet.insert(a8);
+ attrSet.insert(a9);
+
+ //Despite that there are attribute a4,a5,a6 that matches the value of attributes
+ //a1,a2,a3 the type of the attributes is different
+ RUNNER_ASSERT(
+ evaluateResult(con,attrSet,Attribute::MatchResult::MRFalse));
+}
+
+//Test if the same attributes (but other instances) passes the test
+
+TESTSUITE03(08){
+ Condition con(Condition::OR);
+ AttributeSet attrSet;
+
+ BaseAttributePtr a1 = createAttribute("version","var1");
+ BaseAttributePtr a2 = createAttribute("r8v2","var2");
+ BaseAttributePtr a3 = createAttribute("author","va3");
+
+ BaseAttributePtr a4 = createAttribute("version","var1");
+ BaseAttributePtr a5 = createAttribute("r8v2","var2", Attribute::Type::Resource);
+ BaseAttributePtr a6 = createAttribute("author","va3", Attribute::Type::Resource);
+ BaseAttributePtr a7 = createAttribute("r8v2","aaa");
+ BaseAttributePtr a8 = createAttribute("author","aaa");
+
+ con.addAttribute(*DPL::StaticPointerCast<Attribute>(a1));
+ con.addAttribute(*DPL::StaticPointerCast<Attribute>(a2));
+ con.addAttribute(*DPL::StaticPointerCast<Attribute>(a3));
+
+ attrSet.insert(a4);
+ attrSet.insert(a5);
+ attrSet.insert(a6);
+ attrSet.insert(a7);
+ attrSet.insert(a8);
+
+ RUNNER_ASSERT(
+ evaluateResult(con,attrSet,Attribute::MatchResult::MRTrue));
+}
+
+TESTSUITE03(09){
+ Condition con(Condition::OR);
+ AttributeSet attrSet;
+
+ BaseAttributePtr a1 = createAttribute("version", NULL); //empty bag
+ con.addAttribute(*DPL::StaticPointerCast<Attribute>(a1));
+ attrSet.insert(a1);
+
+ RUNNER_ASSERT(
+ evaluateResult(con,attrSet,Attribute::MatchResult::MRFalse));
+}
+
+TESTSUITE03(10){
+ Condition con(Condition::OR);
+ AttributeSet attrSet;
+
+ BaseAttributePtr a1 = createAttribute("version","var1","var2");
+
+ BaseAttributePtr a4 = createAttribute("version","var1");
+
+ con.addAttribute(*DPL::StaticPointerCast<Attribute>(a1));
+ attrSet.insert(a4);
+ //It's enough that one value from string bag matches
+ RUNNER_ASSERT(
+ evaluateResult(con,attrSet,Attribute::MatchResult::MRTrue));
+}
+
+TESTSUITE03(11){
+ Condition con(Condition::AND);
+ AttributeSet attrSet;
+
+ BaseAttributePtr a1 = createAttribute("version","var1","var2");
+ BaseAttributePtr a2 = createAttribute("version","var3","var1");
+
+ BaseAttributePtr a4 = createAttribute("version","var1");
+
+ con.addAttribute(*DPL::StaticPointerCast<Attribute>(a1));
+ con.addAttribute(*DPL::StaticPointerCast<Attribute>(a2));
+ attrSet.insert(a4);
+ //It's enough that one value from string bag matches
+ RUNNER_ASSERT(
+ evaluateResult(con,attrSet,Attribute::MatchResult::MRTrue));
+}
+
+
+TESTSUITE03(12){
+ Condition con(Condition::OR);
+ AttributeSet attrSet;
+
+ BaseAttributePtr a1 = createAttribute("version","var1");
+ BaseAttributePtr a2 = createAttribute("r8v2","var2");
+ BaseAttributePtr a3 = createAttribute("author","va3");
+
+ BaseAttributePtr a4 = createAttribute("version","var1");
+ BaseAttributePtr a5 = createAttribute("r8v2","var2", Attribute::Type::Resource);
+ BaseAttributePtr a6 = createAttribute("author","va3", Attribute::Type::Resource);
+
+ con.addAttribute(*DPL::StaticPointerCast<Attribute>(a1));
+ con.addAttribute(*DPL::StaticPointerCast<Attribute>(a2));
+ con.addAttribute(*DPL::StaticPointerCast<Attribute>(a3));
+
+ attrSet.insert(a4);
+ attrSet.insert(a5);
+ attrSet.insert(a6);
+ RUNNER_ASSERT(
+ evaluateResult(con,attrSet,Attribute::MatchResult::MRTrue));
+}
+
+TESTSUITE03(13){
+ Condition con(Condition::AND);
+ AttributeSet attrSet;
+
+ BaseAttributePtr a1 = createAttribute("version",NULL);
+ a1->setUndetermind(true);
+ BaseAttributePtr a4 = createAttribute("version","var1");
+ con.addAttribute(*DPL::StaticPointerCast<Attribute>(a4));
+ attrSet.insert(a1);
+
+ RUNNER_ASSERT(
+ evaluateResult(con,attrSet,Attribute::MatchResult::MRUndetermined));
+}
+
+TESTSUITE03(14){
+ Condition con(Condition::OR);
+ AttributeSet attrSet;
+
+ BaseAttributePtr a1 = createAttribute("version",NULL);
+ a1->setUndetermind(true);
+ BaseAttributePtr a2 = createAttribute("author","good");
+ BaseAttributePtr a4 = createAttribute("version","var1");
+ con.addAttribute(*DPL::StaticPointerCast<Attribute>(a4));
+ con.addAttribute(*DPL::StaticPointerCast<Attribute>(a2));
+ attrSet.insert(a1);
+ attrSet.insert(a2);
+
+ RUNNER_ASSERT(
+ evaluateResult(con,attrSet,Attribute::MatchResult::MRTrue));
+}
+
+TESTSUITE03(15){
+ Condition con(Condition::OR);
+ AttributeSet attrSet;
+
+ BaseAttributePtr a1 = createAttribute("version",NULL,NULL);
+ a1->setUndetermind(true);
+ BaseAttributePtr a4 = createAttribute("version","var1");
+ con.addAttribute(*DPL::StaticPointerCast<Attribute>(a4));
+ attrSet.insert(a1);
+
+ RUNNER_ASSERT(
+ evaluateResult(con,attrSet,Attribute::MatchResult::MRUndetermined));
+}
+
+TESTSUITE03(16){
+ Condition con(Condition::OR);
+ AttributeSet attrSet;
+
+ BaseAttributePtr a1 = createAttribute("version","var1","aaa");
+ a1->setUndetermind(true);
+ BaseAttributePtr a4 = createAttribute("version","var1");
+ con.addAttribute(*DPL::StaticPointerCast<Attribute>(a4));
+ attrSet.insert(a1);
+
+ RUNNER_ASSERT(
+ evaluateResult(con,attrSet,Attribute::MatchResult::MRUndetermined));
+}
+
+TESTSUITE03(17){
+ Condition con(Condition::AND);
+ AttributeSet attrSet;
+
+ BaseAttributePtr a1 = createAttribute("version","var1");
+ BaseAttributePtr a2 = createAttribute("version1","var1");
+ BaseAttributePtr a3 = createAttribute("version2","var1");
+ BaseAttributePtr a4 = createAttribute("version3","var1");
+ BaseAttributePtr a5 = createAttribute("version1","var2");
+
+ Condition con2(Condition::AND);
+ con2.addAttribute(*DPL::StaticPointerCast<Attribute>(a2));
+ Condition con3(Condition::OR);
+ con3.addAttribute(*DPL::StaticPointerCast<Attribute>(a3));
+ con3.addAttribute(*DPL::StaticPointerCast<Attribute>(a4));
+
+ con.addCondition(con2);
+ con.addCondition(con3);
+
+ con.addAttribute(*DPL::StaticPointerCast<Attribute>(a4));
+ attrSet.insert(a1);
+ attrSet.insert(a3);
+ attrSet.insert(a4);
+ attrSet.insert(a5);
+
+ RUNNER_ASSERT(
+ evaluateResult(con,attrSet,Attribute::MatchResult::MRFalse));
+}
+
+TESTSUITE03(18){
+ Condition con(Condition::OR);
+ AttributeSet attrSet;
+
+ BaseAttributePtr a1 = createAttribute("version","var1");
+ BaseAttributePtr a2 = createAttribute("version1","var1");
+ BaseAttributePtr a3 = createAttribute("version2","var1");
+ BaseAttributePtr a4 = createAttribute("version3","var1");
+ BaseAttributePtr a5 = createAttribute("version1","var2");
+
+ Condition con2(Condition::AND);
+ con2.addAttribute(*DPL::StaticPointerCast<Attribute>(a2));
+ con2.addAttribute(*DPL::StaticPointerCast<Attribute>(a5));
+ Condition con3(Condition::AND);
+ con3.addAttribute(*DPL::StaticPointerCast<Attribute>(a3));
+ con3.addAttribute(*DPL::StaticPointerCast<Attribute>(a4));
+ Condition con4(Condition::AND);
+ con4.addAttribute(*DPL::StaticPointerCast<Attribute>(a2));
+
+ con3.addCondition(con4);
+ con.addCondition(con2);
+ con.addCondition(con3);
+
+ attrSet.insert(a1);
+ attrSet.insert(a3);
+ attrSet.insert(a4);
+ attrSet.insert(a5);
+
+ RUNNER_ASSERT(
+ evaluateResult(con,attrSet,Attribute::MatchResult::MRFalse));
+}
+
+TESTSUITE03(19){
+ Condition con(Condition::OR);
+ AttributeSet attrSet;
+
+ BaseAttributePtr a1 = createAttribute("version","var1");
+ BaseAttributePtr a2 = createAttribute("version1","var1");
+ BaseAttributePtr a3 = createAttribute("version2","var1");
+ BaseAttributePtr a4 = createAttribute("version3","var1");
+ BaseAttributePtr a5 = createAttribute("version1","var2");
+
+ Condition con2(Condition::AND);
+ con2.addAttribute(*DPL::StaticPointerCast<Attribute>(a2));
+ con2.addAttribute(*DPL::StaticPointerCast<Attribute>(a5));
+ Condition con3(Condition::OR);
+ con3.addAttribute(*DPL::StaticPointerCast<Attribute>(a3));
+ con3.addAttribute(*DPL::StaticPointerCast<Attribute>(a4));
+
+ con.addCondition(con2);
+ con.addCondition(con3);
+
+ attrSet.insert(a1);
+ attrSet.insert(a3);
+ attrSet.insert(a4);
+ attrSet.insert(a5);
+
+ RUNNER_ASSERT(
+ evaluateResult(con,attrSet,Attribute::MatchResult::MRTrue));
+}
+
+TESTSUITE03(20){
+ Condition con(Condition::OR);
+ AttributeSet attrSet;
+
+ BaseAttributePtr a1 = createAttribute("version","var1");
+ BaseAttributePtr a2 = createAttribute("version1","var1");
+ BaseAttributePtr a3 = createAttribute("version2","var1");
+ BaseAttributePtr a4 = createAttribute("version3","var1");
+
+ BaseAttributePtr a5 = createAttribute("version1","var2");
+ BaseAttributePtr a6 = createAttribute("version2","var2");
+ BaseAttributePtr a7 = createAttribute("version3","var2");
+ BaseAttributePtr a8 = createAttribute("version4","var2");
+
+ Condition con2(Condition::OR);
+ Condition con3(Condition::OR);
+ Condition con4(Condition::OR);
+ Condition con5(Condition::OR);
+
+ con2.addAttribute(*DPL::StaticPointerCast<Attribute>(a2));
+ con3.addAttribute(*DPL::StaticPointerCast<Attribute>(a3));
+ con4.addAttribute(*DPL::StaticPointerCast<Attribute>(a4));
+ con5.addAttribute(*DPL::StaticPointerCast<Attribute>(a1));
+
+ con2.addCondition(con4);
+ con3.addCondition(con5);
+ con.addCondition(con2);
+ con.addCondition(con3);
+
+ attrSet.insert(a1);
+ attrSet.insert(a5);
+ attrSet.insert(a6);
+ attrSet.insert(a7);
+ attrSet.insert(a8);
+
+ RUNNER_ASSERT(
+ evaluateResult(con,attrSet,Attribute::MatchResult::MRTrue));
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file TestSuite04.cpp
+ * @author unknown
+ * @version 1.0
+ * @brief Test cases for Combiner.
+ */
+
+#include <list>
+#include <string>
+
+#include <dpl/log/log.h>
+#include <dpl/test/test_runner.h>
+
+#include <dpl/ace/CombinerImpl.h>
+#include <dpl/ace/PolicySet.h>
+#include <dpl/ace/Effect.h>
+
+#define TESTSUITE04(n) \
+RUNNER_TEST(ts04_combiner_tests_ ## n)
+
+bool assertEffectEqual(Effect actual, Effect expected){
+ return (actual == expected);
+}
+
+class WTF : public CombinerImpl{
+public:
+ // the evaluation functions should be static and public
+ // but they are protected methods!
+ Effect denyOverrides(std::list<Effect> &lst){
+ return CombinerImpl::denyOverrides(lst);
+ }
+ Effect permitOverrides(std::list<Effect> &lst){
+ return CombinerImpl::permitOverrides(lst);
+ }
+ Effect firstApplicable(std::list<Effect> &lst){
+ return CombinerImpl::firstApplicable(lst);
+ }
+ Effect firstMatchingTarget(std::list<Effect> &lst){
+ return CombinerImpl::firstMatchingTarget(lst);
+ }
+};
+
+Effect denyOverridesTest(std::list<Effect> &lst) {
+ WTF impl;
+ return impl.denyOverrides(lst);
+}
+
+Effect permitOverridesTest(std::list<Effect> &lst) {
+ WTF impl;
+ return impl.permitOverrides(lst);
+}
+
+Effect firstApplicableTest(std::list<Effect> &lst) {
+ WTF impl;
+ return impl.firstApplicable(lst);
+}
+
+Effect firstMatchingTargetTest(std::list<Effect> &lst) {
+ WTF impl;
+ return impl.firstMatchingTarget(lst);
+}
+
+TESTSUITE04(00_denyOverrides){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Deny);
+ effectList->push_back(Undetermined);
+ effectList->push_back(Permit);
+ effectList->push_back(Inapplicable);
+
+ Effect eff = denyOverridesTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Deny));
+}
+
+TESTSUITE04(01_denyOverrides){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Undetermined);
+ effectList->push_back(Permit);
+ effectList->push_back(Inapplicable);
+ effectList->push_back(Deny);
+ effectList->push_back(Permit);
+
+ Effect eff = denyOverridesTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Deny));
+}
+
+TESTSUITE04(02_denyOverrides){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Undetermined);
+ effectList->push_back(Permit);
+ effectList->push_back(Inapplicable);
+ effectList->push_back(Permit);
+
+ Effect eff = denyOverridesTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Undetermined));
+}
+
+TESTSUITE04(03_denyOverrides){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+
+ effectList->push_back(Permit);
+ effectList->push_back(Inapplicable);
+ effectList->push_back(Permit);
+ effectList->push_back(Undetermined);
+ effectList->push_back(PromptSession);
+
+ Effect eff = denyOverridesTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Undetermined));
+}
+
+TESTSUITE04(04_denyOverrides){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Permit);
+ effectList->push_back(Inapplicable);
+ effectList->push_back(Permit);
+ effectList->push_back(PromptOneShot);
+ effectList->push_back(PromptSession);
+ effectList->push_back(PromptBlanket);
+
+ Effect eff = denyOverridesTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, PromptOneShot));
+}
+
+TESTSUITE04(05_denyOverrides){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Permit);
+ effectList->push_back(Inapplicable);
+ effectList->push_back(Permit);
+ effectList->push_back(PromptSession);
+ effectList->push_back(PromptBlanket);
+
+ Effect eff = denyOverridesTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, PromptSession));
+}
+
+TESTSUITE04(06_denyOverrides){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+
+ effectList->push_back(Permit);
+ effectList->push_back(Inapplicable);
+ effectList->push_back(Permit);
+ effectList->push_back(PromptBlanket);
+
+ Effect eff = denyOverridesTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, PromptBlanket));
+}
+
+TESTSUITE04(07_denyOverrides){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Permit);
+ effectList->push_back(Inapplicable);
+ effectList->push_back(Permit);
+
+ Effect eff = denyOverridesTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Permit));
+}
+
+TESTSUITE04(08_denyOverrides){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Inapplicable);
+
+ Effect eff = denyOverridesTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Inapplicable));
+}
+
+TESTSUITE04(09_denyOverrides){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ Effect eff = denyOverridesTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Inapplicable));
+}
+
+TESTSUITE04(10_denyOverrides){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Deny);
+ effectList->push_back(Undetermined);
+ effectList->push_back(Permit);
+ effectList->push_back(Error);
+ effectList->push_back(Inapplicable);
+
+ Effect eff = denyOverridesTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Error));
+}
+
+TESTSUITE04(11_denyOverrides){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Error);
+ effectList->push_back(Undetermined);
+ effectList->push_back(Error);
+ effectList->push_back(Inapplicable);
+ effectList->push_back(Permit);
+
+ Effect eff = denyOverridesTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Error));
+}
+
+TESTSUITE04(12_denyOverrides){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Permit);
+ effectList->push_back(Inapplicable);
+ effectList->push_back(Permit);
+ effectList->push_back(Error);
+ effectList->push_back(PromptOneShot);
+ effectList->push_back(PromptSession);
+ effectList->push_back(PromptBlanket);
+
+
+ Effect eff = denyOverridesTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Error));
+}
+
+TESTSUITE04(13_denyOverrides){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Permit);
+ effectList->push_back(Inapplicable);
+ effectList->push_back(Permit);
+ effectList->push_back(Error);
+ effectList->push_back(PromptBlanket);
+ effectList->push_back(PromptSession);
+
+ Effect eff = denyOverridesTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Error));
+}
+
+TESTSUITE04(14_denyOverrides){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Error);
+ effectList->push_back(Inapplicable);
+
+ Effect eff = denyOverridesTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Error));
+}
+
+TESTSUITE04(15_denyOverrides){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Inapplicable);
+ effectList->push_back(Error);
+
+ Effect eff = denyOverridesTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Error));
+}
+
+TESTSUITE04(16_permitOverrides){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Deny);
+ effectList->push_back(Undetermined);
+ effectList->push_back(Permit);
+ effectList->push_back(Inapplicable);
+ effectList->push_back(PromptOneShot);
+ effectList->push_back(PromptSession);
+ effectList->push_back(PromptBlanket);
+
+ Effect eff = permitOverridesTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Permit));
+}
+
+TESTSUITE04(17_permitOverrides){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Deny);
+ effectList->push_back(Inapplicable);
+ effectList->push_back(PromptOneShot);
+ effectList->push_back(PromptSession);
+ effectList->push_back(PromptBlanket);
+ effectList->push_back(Undetermined);
+
+ Effect eff = permitOverridesTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Undetermined));
+}
+
+TESTSUITE04(18_permitOverrides){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Deny);
+ effectList->push_back(Inapplicable);
+ effectList->push_back(PromptOneShot);
+ effectList->push_back(PromptSession);
+ effectList->push_back(PromptBlanket);
+
+
+ Effect eff = permitOverridesTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, PromptBlanket));
+}
+
+TESTSUITE04(19_permitOverrides){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Deny);
+ effectList->push_back(PromptOneShot);
+ effectList->push_back(PromptSession);
+ effectList->push_back(Inapplicable);
+
+ Effect eff = permitOverridesTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, PromptSession));
+}
+
+TESTSUITE04(20_permitOverrides){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Deny);
+ effectList->push_back(Inapplicable);
+ effectList->push_back(PromptOneShot);
+
+ Effect eff = permitOverridesTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, PromptOneShot));
+}
+
+TESTSUITE04(21_permitOverrides){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Deny);
+ effectList->push_back(Inapplicable);
+
+ Effect eff = permitOverridesTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Deny));
+}
+
+TESTSUITE04(22_permitOverrides){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Inapplicable);
+
+ Effect eff = permitOverridesTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Inapplicable));
+}
+
+TESTSUITE04(23_permitOverrides){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+
+ Effect eff = permitOverridesTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Inapplicable));
+}
+
+TESTSUITE04(24_permitOverrides){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Deny);
+ effectList->push_back(Undetermined);
+ effectList->push_back(Permit);
+ effectList->push_back(Inapplicable);
+ effectList->push_back(Error);
+ effectList->push_back(PromptSession);
+ effectList->push_back(PromptOneShot);
+ effectList->push_back(PromptBlanket);
+
+ Effect eff = permitOverridesTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Error));
+}
+
+TESTSUITE04(25_permitOverrides){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Deny);
+ effectList->push_back(Inapplicable);
+ effectList->push_back(PromptOneShot);
+ effectList->push_back(PromptSession);
+ effectList->push_back(PromptBlanket);
+ effectList->push_back(Undetermined);
+ effectList->push_back(Error);
+
+ Effect eff = permitOverridesTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Error));
+}
+
+TESTSUITE04(26_permitOverrides){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Deny);
+ effectList->push_back(Error);
+ effectList->push_back(Inapplicable);
+ effectList->push_back(PromptOneShot);
+
+ Effect eff = permitOverridesTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Error));
+}
+
+TESTSUITE04(27_permitOverrides){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Error);
+ Effect eff = permitOverridesTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Error));
+}
+
+TESTSUITE04(28_firstApplicable){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Deny);
+ effectList->push_back(Inapplicable);
+ effectList->push_back(PromptOneShot);
+ effectList->push_back(PromptSession);
+ effectList->push_back(PromptBlanket);
+ effectList->push_back(Undetermined);
+
+ Effect eff = firstApplicableTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Deny));
+}
+
+TESTSUITE04(29_firstApplicable){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Undetermined);
+ effectList->push_back(Deny);
+ effectList->push_back(PromptOneShot);
+ effectList->push_back(Inapplicable);
+ effectList->push_back(PromptOneShot);
+ effectList->push_back(PromptSession);
+ effectList->push_back(PromptBlanket);
+ effectList->push_back(Undetermined);
+
+ Effect eff = firstApplicableTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Undetermined));
+}
+
+TESTSUITE04(30_firstApplicable){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Inapplicable);
+ effectList->push_back(Deny);
+ effectList->push_back(PromptOneShot);
+ effectList->push_back(Inapplicable);
+ effectList->push_back(PromptOneShot);
+ effectList->push_back(PromptSession);
+ effectList->push_back(PromptBlanket);
+ effectList->push_back(Undetermined);
+
+ Effect eff = firstApplicableTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Deny));
+}
+
+TESTSUITE04(31_firstApplicable){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Inapplicable);
+ effectList->push_back(Undetermined);
+ effectList->push_back(PromptOneShot);
+ effectList->push_back(Inapplicable);
+ effectList->push_back(PromptOneShot);
+ effectList->push_back(PromptSession);
+ effectList->push_back(PromptBlanket);
+ effectList->push_back(Undetermined);
+
+ Effect eff = firstApplicableTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Undetermined));
+}
+
+TESTSUITE04(32_firstApplicable){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Inapplicable);
+ effectList->push_back(Inapplicable);
+ effectList->push_back(Inapplicable);
+
+ Effect eff = firstApplicableTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Inapplicable));
+}
+
+TESTSUITE04(33_firstApplicable){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Inapplicable);
+ effectList->push_back(Inapplicable);
+ effectList->push_back(Inapplicable);
+ effectList->push_back(Permit);
+
+ Effect eff = firstApplicableTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Permit));
+}
+
+TESTSUITE04(34_firstApplicable){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+
+ Effect eff = firstApplicableTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Inapplicable));
+}
+
+TESTSUITE04(35_firstApplicable){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Deny);
+ effectList->push_back(Inapplicable);
+ effectList->push_back(PromptOneShot);
+ effectList->push_back(Error);
+ effectList->push_back(PromptSession);
+ effectList->push_back(PromptBlanket);
+ effectList->push_back(Undetermined);
+
+ Effect eff = firstApplicableTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Error));
+}
+
+TESTSUITE04(36_firstApplicable){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Inapplicable);
+ effectList->push_back(Inapplicable);
+ effectList->push_back(Inapplicable);
+ effectList->push_back(Error);
+ effectList->push_back(Permit);
+
+ Effect eff = firstApplicableTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Error));
+}
+
+TESTSUITE04(37_firstApplicable){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Error);
+
+ Effect eff = firstApplicableTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Error));
+}
+
+TESTSUITE04(38_firstMatching){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Inapplicable);
+ effectList->push_back(Deny);
+ effectList->push_back(PromptOneShot);
+ effectList->push_back(Inapplicable);
+
+ Effect eff = firstMatchingTargetTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Inapplicable));
+}
+
+TESTSUITE04(39_firstMatching){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Undetermined);
+ effectList->push_back(Deny);
+ effectList->push_back(PromptOneShot);
+ effectList->push_back(Inapplicable);
+
+ Effect eff = firstMatchingTargetTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Undetermined));
+}
+
+TESTSUITE04(39a_firstMatching){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Deny);
+ effectList->push_back(Inapplicable);
+
+ Effect eff = firstMatchingTargetTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Deny));
+}
+
+TESTSUITE04(39b_firstMatching){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Permit);
+
+ Effect eff = firstMatchingTargetTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Permit));
+}
+
+TESTSUITE04(40_firstMatching){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Undetermined);
+ effectList->push_back(Undetermined);
+ effectList->push_back(Undetermined);
+
+ Effect eff = firstMatchingTargetTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Undetermined));
+}
+
+TESTSUITE04(41_firstMatching){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+
+ Effect eff = firstMatchingTargetTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Inapplicable));
+}
+
+TESTSUITE04(42_firstMatching){
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Inapplicable);
+
+ Effect eff = firstMatchingTargetTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Inapplicable));
+}
+
+TESTSUITE04(43_firstMatching){
+
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Undetermined);
+ effectList->push_back(Undetermined);
+ effectList->push_back(Undetermined);
+ effectList->push_back(Deny);
+ effectList->push_back(Inapplicable);
+ effectList->push_back(Undetermined);
+ effectList->push_back(Deny);
+ effectList->push_back(PromptOneShot);
+ effectList->push_back(Inapplicable);
+
+ Effect eff = firstMatchingTargetTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Undetermined));
+}
+
+TESTSUITE04(44_firstMatching){
+
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Inapplicable);
+ effectList->push_back(Deny);
+ effectList->push_back(PromptOneShot);
+ effectList->push_back(Error);
+ effectList->push_back(Inapplicable);
+
+ Effect eff = firstMatchingTargetTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Error));
+}
+
+TESTSUITE04(45_firstMatching){
+
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Undetermined);
+ effectList->push_back(Undetermined);
+ effectList->push_back(Error);
+ effectList->push_back(Undetermined);
+ effectList->push_back(Deny);
+ effectList->push_back(Inapplicable);
+ effectList->push_back(Undetermined);
+ effectList->push_back(Deny);
+ effectList->push_back(PromptOneShot);
+ effectList->push_back(Inapplicable);
+
+ Effect eff = firstMatchingTargetTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Error));
+}
+
+TESTSUITE04(46_firstMatching){
+
+ std::list<Effect> * effectList = new std::list<Effect > ();
+ effectList->push_back(Error);
+
+ Effect eff = firstMatchingTargetTest(*effectList);
+ RUNNER_ASSERT(assertEffectEqual(eff, Error));
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file TestSuite05.cpp
+ * @author unknown
+ * @version 1.0
+ * @brief Test cases for Attribute class.
+ */
+
+#include <iostream>
+#include <list>
+#include <set>
+#include <string>
+
+#include <dpl/test/test_runner.h>
+
+#include <dpl/ace/Attribute.h>
+#include <dpl/ace-dao-ro/BaseAttribute.h>
+
+#define TESTSUITE05(n) \
+RUNNER_TEST(ts05_attr_tests_ ## n)
+
+class AT : public Attribute {
+public:
+ AT(std::string nm)
+ : Attribute(nm)
+ {}
+
+ static std::string* uriAuthorityStatic(const std::string *input) {
+ AT at("Micky");
+ return at.uriAuthority(input);
+ }
+
+ static std::string* uriHostStatic(const std::string *input) {
+ AT at("Pluto");
+ return at.uriHost(input);
+ }
+
+ static std::string* uriSchemeStatic(const std::string *input) {
+ AT at("Donald");
+ return at.uriScheme(input);
+ }
+
+ static std::string* uriSchemeAuthorityStatic(const std::string *input) {
+ AT at("Winnie the Pooh");
+ return at.uriSchemeAuthority(input);
+ }
+
+ static std::string* uriPathStatic(const std::string *input) {
+ AT at("Hannibal");
+ return at.uriPath(input);
+ }
+
+ static bool markTest(){
+ bool result = true;
+ for(int i =0; i<128; ++i){
+ if( i == '-' || i == '_' || i == '.'|| i == '!'|| i == '~' || i == '*' || i == '\'' || i == ')' || i == '(' ){
+ if (!mark[i]){
+ result = false;
+ break;
+ }
+ }
+ else{
+ if(mark[i]){
+ result =false;
+ break;
+ }
+ }
+ }
+ return result;
+ }
+
+ static bool digitTest(){
+ bool result = true;
+ for(int i =0; i<128; ++i){
+ if( i > 47 && i < 58 ){
+ if (!digit[i]){
+ result = false;
+ break;
+ }
+ }
+ else{
+ if(digit[i]){
+ result =false;
+ break;
+ }
+ }
+ }
+ return result;
+ }
+
+ static bool alphaTest(){
+ bool result = true;
+ for(int i =0; i<128; ++i){
+ if( ( i>64 && i<91 ) || ( i>96 && i<123 ) ) {
+ if (!alpha[i]){
+ result = false;
+ break;
+ }
+ }
+ else{
+ if(alpha[i]){
+ result =false;
+ break;
+ }
+ }
+ }
+ return result;
+ }
+
+ static bool isEscapedStatic(const char esc[3]) {
+ AT at("Swinka");
+ return at.isEscaped(esc);
+ }
+};
+
+bool assertEqual(const std::string * actual, const char * intended) {
+ if (actual == NULL || intended == NULL) {
+ if (intended == NULL && actual == NULL) {
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ std::string temp(intended);
+
+ if (temp == *actual) {
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
+bool assertTrue(bool condition){
+ return condition;
+}
+
+bool assertFalse(bool condition){
+ return !condition;
+}
+
+TESTSUITE05(01_uriAuthority){
+ std::string * outcome = NULL;
+ std::string query("http://www.wp.pl");
+ outcome = AT::uriAuthorityStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, "www.wp.pl"));
+ delete outcome;
+}
+
+TESTSUITE05(02_uriAuthority){
+ std::string * outcome = NULL;
+ std::string query("http://authority?path/asdf");
+ outcome = AT::uriAuthorityStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, "authority"));
+ delete outcome;
+}
+
+TESTSUITE05(03_uriAuthority){
+ std::string * outcome = NULL;
+ std::string query("abcd"); //This should be interpreted as schema
+ outcome = AT::uriAuthorityStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, ""));
+ delete outcome;
+}
+
+TESTSUITE05(04_uriAuthority){
+ std::string * outcome = NULL;
+ std::string query("http://authority/asdf");
+ outcome = AT::uriAuthorityStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, "authority"));
+ delete outcome;
+}
+
+TESTSUITE05(05_uriAuthority){
+ std::string * outcome = NULL;
+ std::string query("http://user@host:20?ds");
+ outcome = AT::uriAuthorityStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, "user@host:20"));
+ delete outcome;
+}
+
+TESTSUITE05(06_uriAuthority){
+ std::string * outcome = NULL;
+ std::string query("http://hostname:23");
+ outcome = AT::uriAuthorityStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, "hostname:23"));
+ delete outcome;
+}
+
+TESTSUITE05(07_uriAuthority){
+ std::string * outcome = NULL;
+ std::string query("http://user@host:port");
+ outcome = AT::uriAuthorityStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, "user@host:port"));
+ delete outcome;
+}
+
+TESTSUITE05(08_uriAuthority){
+ std::string * outcome = NULL;
+ std::string query("http://1user@host:port"); //This is a VALID URI
+ outcome = AT::uriAuthorityStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, "1user@host:port"));
+ delete outcome;
+}
+
+TESTSUITE05(09_uriAuthority){
+ std::string * outcome = NULL;
+ std::string query("http://abc%30"); //This is not a valid uri
+ outcome = AT::uriAuthorityStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, "abc%30"));
+ delete outcome;
+}
+
+TESTSUITE05(10_uriAuthority){
+ std::string * outcome = NULL;
+ std::string query("http:///asd"); //This is not a valid uri
+ outcome = AT::uriAuthorityStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, ""));
+ delete outcome;
+}
+
+TESTSUITE05(11_uriAuthority){
+ std::string * outcome = NULL;
+ std::string query("http://?asd"); //This is not a valid uri
+ outcome = AT::uriAuthorityStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, ""));
+ delete outcome;
+}
+
+TESTSUITE05(12_uriAuthority){
+ std::string * outcome = NULL;
+ std::string query("http://%34%56%67%ab");
+ outcome = AT::uriAuthorityStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, "%34%56%67%ab"));
+ delete outcome;
+}
+
+TESTSUITE05(13_uriAuthority){
+ std::string * outcome = NULL;
+ std::string query("http://<>"); //This is not a valid uri
+ outcome = AT::uriAuthorityStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, NULL));
+ delete outcome;
+}
+
+TESTSUITE05(14_uriAuthority){
+ std::string * outcome = NULL;
+ std::string query("http://\\/"); //This is not a valid uri
+ outcome = AT::uriAuthorityStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, NULL));
+ delete outcome;
+}
+
+TESTSUITE05(15_uriHost){
+ std::string * outcome = NULL;
+ std::string query("http://user@host:23");
+ outcome = AT::uriHostStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, "host"));
+ delete outcome;
+}
+
+TESTSUITE05(16_uriHost){
+ std::string * outcome = NULL;
+ std::string query("http://user@host:name"); //This is not a valid uri
+ outcome = AT::uriHostStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, ""));
+ delete outcome;
+}
+
+TESTSUITE05(17_uriHost){
+ std::string * outcome = NULL;
+ std::string query("http::::"); //This is a valid uri
+ outcome = AT::uriHostStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, ""));
+ delete outcome;
+}
+
+TESTSUITE05(18_uriHost){
+ std::string * outcome = NULL;
+ std::string query("..%%%."); //This is not a valid uri
+ outcome = AT::uriHostStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, NULL));
+ delete outcome;
+}
+
+TESTSUITE05(19_uriHost){
+ std::string * outcome = NULL;
+ std::string query("ftp://abds.eu/fda");
+ outcome = AT::uriHostStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, "abds.eu"));
+ delete outcome;
+}
+
+TESTSUITE05(20_uriHost){
+ std::string * outcome = NULL;
+ std::string query("abs%14ccc");
+ //This is a valid uri because it's interpreted as a path not a host
+ outcome = AT::uriHostStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, ""));
+ delete outcome;
+}
+
+TESTSUITE05(21_uriHost){
+ std::string * outcome = NULL;
+ std::string query("http://abc@123.2.23.213:982");
+ outcome = AT::uriHostStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, "123.2.23.213"));
+ delete outcome;
+}
+
+TESTSUITE05(22_uriHost){
+ std::string * outcome = NULL;
+ std::string query("http://abc@1233.2.23.213:982");
+ //Hostname is invalid, but uri is valid
+ outcome = AT::uriHostStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, ""));
+ delete outcome;
+}
+
+TESTSUITE05(23_uriHost){
+ std::string * outcome = NULL;
+ std::string query("http://ab%23c@host"); //Valid escaped characters
+ outcome = AT::uriHostStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, "host"));
+ delete outcome;
+}
+
+TESTSUITE05(24_uriHost){
+ std::string * outcome = NULL;
+ std::string query("http://ab%23c@host%34"); //Invalid escaped characters in hostname
+ outcome = AT::uriHostStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, ""));
+ delete outcome;
+}
+
+TESTSUITE05(25_uriHost){
+ std::string * outcome = NULL;
+ std::string query("http://ab%GGc@host"); //Wrong character %
+ outcome = AT::uriHostStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, NULL));
+ delete outcome;
+}
+
+TESTSUITE05(26_uriHost){
+ std::string * outcome = NULL;
+ std::string query("http://www.example.pl");
+ outcome = AT::uriHostStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, "www.example.pl"));
+ delete outcome;
+}
+
+TESTSUITE05(27_uriScheme){
+ std::string * outcome = NULL;
+ std::string query("http://host");
+ outcome = AT::uriSchemeStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, "http"));
+ delete outcome;
+}
+
+TESTSUITE05(28_uriScheme){
+ std::string * outcome = NULL;
+ //Wrong character '1' in scheme , it's not an URI because two slashes are not acceptable
+ //in any other place than in separation between scheme and pat
+ std::string query("1http://host");
+ outcome = AT::uriSchemeStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, NULL));
+ delete outcome;
+}
+
+TESTSUITE05(29_uriScheme){
+ std::string * outcome = NULL;
+ std::string query("ftp+a-fdf.ads://host");
+ outcome = AT::uriSchemeStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, "ftp+a-fdf.ads"));
+ delete outcome;
+}
+
+TESTSUITE05(30_uriScheme){
+ std::string * outcome = NULL;
+ //Scheme cannot start with plus, it's not an URI because two slashes are not acceptable
+ //in any other place than in separation between scheme and path
+ std::string query("+++://host");
+ outcome = AT::uriSchemeStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, NULL));
+ delete outcome;
+}
+
+TESTSUITE05(31_uriScheme){
+ std::string * outcome = NULL;
+ std::string query("aaaac"); //It's a path not a scheme'a
+ outcome = AT::uriSchemeStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, ""));
+ delete outcome;
+}
+
+TESTSUITE05(32_uriScheme){
+ std::string * outcome = NULL;
+ //no escaped characters in schema, it's not an URI because two slashes are not acceptable
+ //in any other place than in separation between scheme and path
+ std::string query("ftpa%34fdfads://host");
+ outcome = AT::uriSchemeStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, NULL));
+ delete outcome;
+}
+
+TESTSUITE05(33_uriScheme){
+ std::string * outcome = NULL;
+ //no escaped characters in schema, it's not an URI because two slashes are not acceptable
+ //in any other place than in separation between scheme and path
+ std::string query("meaninglessstring://host%34");
+ outcome = AT::uriSchemeStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, "meaninglessstring"));
+ delete outcome;
+}
+
+TESTSUITE05(34_uriScheme){
+ std::string * outcome = NULL;
+ std::string query("meaninglessstring2://");
+ outcome = AT::uriSchemeStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, "meaninglessstring2"));
+ delete outcome;
+}
+
+TESTSUITE05(35_uriScheme){
+ std::string * outcome = NULL;
+ std::string query("http://www.samsung.com/ace/bondi#5");
+ outcome = AT::uriSchemeStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, "http"));
+ delete outcome;
+}
+
+TESTSUITE05(36_uriScheme){
+ std::string * outcome = NULL;
+ std::string query("www.samsung.com");
+ outcome = AT::uriSchemeStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, ""));
+ delete outcome;
+}
+
+TESTSUITE05(37_uriSchemeAuthority){
+ std::string * outcome = NULL;
+ std::string query("http://www.samsung.com");
+ outcome = AT::uriSchemeAuthorityStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, "http://www.samsung.com"));
+ delete outcome;
+}
+
+TESTSUITE05(38_uriSchemeAuthority){
+ std::string * outcome = NULL;
+ std::string query("ftp23://www.samsung.com/avc%23");
+ outcome = AT::uriSchemeAuthorityStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, "ftp23://www.samsung.com"));
+ delete outcome;
+}
+
+TESTSUITE05(39_uriSchemeAuthority){
+ std::string * outcome = NULL;
+ std::string query("ftp++://anonymous@hostname:12/avc%23");
+ outcome = AT::uriSchemeAuthorityStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, "ftp++://anonymous@hostname:12"));
+ delete outcome;
+}
+
+TESTSUITE05(40_uriSchemeAuthority){
+ std::string * outcome = NULL;
+ std::string query("32ftp://anonymous@hostname:12/avc%23");
+ outcome = AT::uriSchemeAuthorityStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, NULL));
+ delete outcome;
+}
+
+TESTSUITE05(41_uriSchemeAuthority){
+ std::string * outcome = NULL;
+ std::string query("http://aaabbb?acd");
+ outcome = AT::uriSchemeAuthorityStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, "http://aaabbb"));
+ delete outcome;
+}
+
+TESTSUITE05(42_uriSchemeAuthority){
+ std::string * outcome = NULL;
+ std::string query("http://aaabbb/acd;sdf;sdf");
+ outcome = AT::uriSchemeAuthorityStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, "http://aaabbb"));
+ delete outcome;
+}
+
+TESTSUITE05(43_uriPath){
+ std::string * outcome = NULL;
+ std::string query("ftp://authority//invalidpath");
+ outcome = AT::uriPathStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, NULL));
+ delete outcome;
+}
+
+TESTSUITE05(44_uriPath){
+ std::string * outcome = NULL;
+ std::string query("ftp://authority/validpath");
+ outcome = AT::uriPathStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, "validpath"));
+ delete outcome;
+}
+
+TESTSUITE05(45_uriPath){
+ std::string * outcome = NULL;
+ std::string query("ftp://authority/validpath;param;param");
+ outcome = AT::uriPathStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, "validpath;param;param"));
+ delete outcome;
+}
+
+TESTSUITE05(46_uriPath){
+ std::string * outcome = NULL;
+ std::string query("ftp://authority/validpath;param;param?query");
+ outcome = AT::uriPathStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, "validpath;param;param"));
+ delete outcome;
+}
+
+TESTSUITE05(47_uriPath){
+ std::string * outcome = NULL;
+ std::string query("ftp://authority/validpath;?param;param?query");
+ outcome = AT::uriPathStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, "validpath;"));
+ delete outcome;
+}
+
+TESTSUITE05(48_uriPath){
+ std::string * outcome = NULL;
+ std::string query("ftp://authority/validpath;param?;param?query");
+ outcome = AT::uriPathStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, "validpath;param"));
+ delete outcome;
+}
+
+TESTSUITE05(49_uriPath){
+ std::string * outcome = NULL;
+ std::string query("ftp://authority/valid:path?query");
+ outcome = AT::uriPathStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, "valid:path"));
+ delete outcome;
+}
+
+TESTSUITE05(50_uriPath){
+ std::string * outcome = NULL;
+ std::string query("ftp://authority/:::");
+ outcome = AT::uriPathStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, ":::"));
+ delete outcome;
+}
+
+TESTSUITE05(51_uriPath){
+ std::string * outcome = NULL;
+ std::string query("/path1/path2?abc#fragment");
+ outcome = AT::uriPathStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, "path1/path2"));
+ delete outcome;
+}
+
+TESTSUITE05(52_uriPath){
+ std::string * outcome = NULL;
+ std::string query("http://www.samsung.com/normalpath/path2?query");
+ outcome = AT::uriPathStatic(&query);
+ RUNNER_ASSERT(assertEqual(outcome, "normalpath/path2"));
+ delete outcome;
+}
+
+TESTSUITE05(53_markTest){
+ RUNNER_ASSERT(AT::markTest());
+}
+
+TESTSUITE05(54_digitTest){
+ RUNNER_ASSERT(AT::digitTest());
+}
+
+TESTSUITE05(55_alphaTest){
+ RUNNER_ASSERT(AT::alphaTest());
+}
+
+TESTSUITE05(56_escapedTest){
+ const char * query = "%23";
+ RUNNER_ASSERT(assertTrue(AT::isEscapedStatic(query)));
+ query = "%ab";
+ RUNNER_ASSERT(assertTrue(AT::isEscapedStatic(query)));
+
+ query = "%a";
+ RUNNER_ASSERT(assertFalse(AT::isEscapedStatic(query)));
+
+ query = "%rw";
+ RUNNER_ASSERT(assertFalse(AT::isEscapedStatic(query)));
+
+ query = NULL;
+ RUNNER_ASSERT(assertFalse(AT::isEscapedStatic(query)));
+
+ query = "abc";
+ RUNNER_ASSERT(assertFalse(AT::isEscapedStatic(query)));
+
+ query = "%bc";
+ RUNNER_ASSERT(assertTrue(AT::isEscapedStatic(query)));
+
+ query = "%DF";
+ RUNNER_ASSERT(assertTrue(AT::isEscapedStatic(query)));
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file TestSuite06.cpp
+ * @author unknown
+ * @version 1.0
+ * @brief Test cases for AceDAO implementation.
+ */
+#include <iostream>
+#include <string>
+
+#include <dpl/foreach.h>
+#include <dpl/test/test_runner.h>
+
+#include <dpl/ace-dao-rw/AceDAO.h>
+#include <dpl/ace/Attribute.h>
+#include <dpl/ace/Preference.h>
+#include <dpl/ace/SettingsLogic.h>
+
+#define TESTSUITE06(n) \
+RUNNER_TEST(ts06_ace_dao_ ## n)
+
+#define CLEANENV \
+ do{ \
+ AceDB::AceDAO::clearWidgetDevCapSettings(); \
+ AceDB::AceDAO::clearDevCapSettings(); \
+ }while(0)
+
+using namespace AceDB;
+
+int operator==(const Attribute& left, const Attribute& right)
+{
+ return ( (*left.getName() == *right.getName()));
+}
+
+bool UserSettingsAgreed(std::list<PermissionTriple>* expected,
+ std::list<PermissionTriple>* allRules)
+{
+ if (allRules->empty() && expected->empty())
+ {
+ return true;
+ }
+
+ std::list<PermissionTriple>::iterator itA;
+ FOREACH(itE, *expected)
+ {
+ if (itE->devCap.empty()){
+ return false; //some error occur
+ }
+
+ for (itA = allRules->begin(); itA != allRules->end(); ++itA){
+ if (itA->appId == itE->appId &&
+ itA->devCap == itE->devCap)
+ {
+ if (itA->access == itE->access){
+ break;
+ }
+ else{
+ return false; //optimization
+ }
+ }
+ }
+
+ if (itA == allRules->end())
+ {
+ if (itE->access == Preference::PREFERENCE_DEFAULT)
+ { // this value is not set in DB
+ continue;
+ }
+ //if we are here -it means that expected values doesnt exist in DB
+ return false;
+ }
+ else
+ {
+ continue; //go to next expected attr
+ }
+ }
+
+ //it means that all required values exist in DB
+ return true;
+}
+
+
+bool UserSettingNotStored(std::list<PermissionTriple>* userSettings,
+ std::string res,
+ WidgetHandle handler,
+ Preference pref)
+{
+ if (userSettings->empty())
+ {
+ return true;
+ }
+
+ FOREACH(iter, *userSettings)
+ {
+ if (iter->appId == handler && iter->devCap == res){
+ if (iter->access == pref){
+ return false; //this value has been saved
+ }
+ else{
+ continue; //value has been saved
+ }
+ }
+ }
+
+ return true;
+}
+
+
+
+bool ResourceSettingsAgreed(
+ std::list< std::pair<const std::string*,Preference> > *expected,
+ std::map<std::string, Preference>* allRules)
+{
+ std::list< std::pair<const std::string*,Preference> >::iterator itE;
+ std::map<std::string, Preference>::iterator itA;
+
+ FOREACH(itE, *expected)
+ {
+ itA = allRules->find(*(itE->first));
+ if (itA != allRules->end() && itA->second == itE->second)
+ {
+ continue;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ResourceSettingsEqual(
+ std::list< std::pair<const std::string*,Preference> > * actual,
+ std::map<std::string, Preference>* expected)
+{
+ bool flag = false;
+ FOREACH(iterA, *actual)
+ {
+ FOREACH(iterE, *expected)
+ {
+ if (*(iterA->first) == iterE->first &&
+ iterA->second == iterE->second)
+ {
+ flag = true;
+ }
+ }
+ if (!flag)
+ {
+ return false;
+ }
+ flag = false;
+ }
+
+ return true;
+}
+
+//bool VSPAssertEqual(Verdict actual, Verdict expected){
+// return (actual == expected);
+//}
+
+
+bool AttributeEqual(AttributeSet actual, AttributeSet expected){
+ return (actual == expected);
+}
+
+bool ResourceSettingEqual(std::map<std::string, Preference>* rSettings,
+ std::string res,
+ Preference pref)
+{
+ std::map<std::string, Preference>::iterator iter = rSettings->find(res);
+
+ if (iter != rSettings->end() && iter->second ==pref)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+
+bool UserSettingEqual(std::list<PermissionTriple>* userSettings,
+ std::string res,
+ WidgetHandle handler,
+ Preference pref)
+{
+ if (userSettings->empty() && pref == Preference::PREFERENCE_DEFAULT)
+ {
+ return true;
+ }
+ FOREACH(iter, *userSettings)
+ {
+ if (iter->devCap.empty())
+ {
+ return false; //some error occurred
+ }
+ if (iter->appId == handler && iter->devCap == res){
+ if (iter->access == pref)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+
+ return false;
+}
+
+//Test does verdict PERMIT is saved when validity is once
+TESTSUITE06(01){
+ CLEANENV;
+ AttributeSet attributeSet;
+ std::string tmp("atrS");
+ std::string tmpValue("Buu");
+ BaseAttributePtr atr(new Attribute(&tmp,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ DPL::StaticPointerCast<Attribute>(atr)->addValue(&tmpValue);
+ attributeSet.insert(atr);
+
+ AceDAO::setPolicyResult(attributeSet, PolicyEffect::PERMIT);
+ OptionalPolicyResult opt = AceDAO::getPolicyResult(attributeSet);
+
+ PolicyResult effect(PolicyEffect::DENY);
+ if (!opt.IsNull()) {
+ effect = *opt;
+ }
+
+ RUNNER_ASSERT(effect == PolicyEffect::PERMIT);
+}
+
+TESTSUITE06(02){
+ CLEANENV;
+ AttributeSet attributeSet;
+ std::string tmp("atrS");
+ std::string tmpValue("Buu");
+ BaseAttributePtr atr(new Attribute(&tmp,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ DPL::StaticPointerCast<Attribute>(atr)->addValue(&tmpValue);
+ attributeSet.insert(atr);
+
+ AceDAO::setPolicyResult(attributeSet, PolicyEffect::DENY);
+ OptionalPolicyResult opt = AceDAO::getPolicyResult(attributeSet);
+
+ PolicyResult effect(PolicyEffect::PERMIT);
+ if (!opt.IsNull()) {
+ effect = *opt;
+ }
+
+ RUNNER_ASSERT(effect == PolicyEffect::DENY);
+}
+
+TESTSUITE06(03){
+ CLEANENV;
+ AttributeSet attributeSet;
+ std::string tmp("atrS");
+ std::string tmpValue("Buu");
+ BaseAttributePtr atr(new Attribute(&tmp,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ DPL::StaticPointerCast<Attribute>(atr)->addValue(&tmpValue);
+ attributeSet.insert(atr);
+
+ AceDAO::setPolicyResult(attributeSet, PolicyEffect::PROMPT_ONESHOT);
+ OptionalPolicyResult opt = AceDAO::getPolicyResult(attributeSet);
+
+ PolicyResult effect(PolicyEffect::DENY);
+ if (!opt.IsNull()) {
+ effect = *opt;
+ }
+
+ RUNNER_ASSERT(effect == PolicyEffect::PROMPT_ONESHOT);
+}
+
+TESTSUITE06(04){
+ CLEANENV;
+ AttributeSet attributeSet;
+ std::string tmp("atrS");
+ std::string tmpValue("Buu");
+ BaseAttributePtr atr(new Attribute(&tmp,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ DPL::StaticPointerCast<Attribute>(atr)->addValue(&tmpValue);
+ attributeSet.insert(atr);
+
+ AceDAO::setPolicyResult(attributeSet, PolicyEffect::PROMPT_SESSION);
+ OptionalPolicyResult opt = AceDAO::getPolicyResult(attributeSet);
+
+ PolicyResult effect(PolicyEffect::DENY);
+ if (!opt.IsNull()) {
+ effect = *opt;
+ }
+
+ RUNNER_ASSERT(effect == PolicyEffect::PROMPT_SESSION);
+}
+
+TESTSUITE06(05){
+ CLEANENV;
+ AttributeSet attributeSet;
+ std::string tmp("atrS");
+ std::string tmpValue("Buu");
+ BaseAttributePtr atr(new Attribute(&tmp,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ DPL::StaticPointerCast<Attribute>(atr)->addValue(&tmpValue);
+ attributeSet.insert(atr);
+
+ AceDAO::setPolicyResult(attributeSet, PolicyEffect::PROMPT_BLANKET);
+ OptionalPolicyResult opt = AceDAO::getPolicyResult(attributeSet);
+
+ PolicyResult effect(PolicyEffect::DENY);
+ if (!opt.IsNull()) {
+ effect = *opt;
+ }
+
+ RUNNER_ASSERT(effect == PolicyEffect::PROMPT_BLANKET);
+}
+
+TESTSUITE06(06){
+ CLEANENV;
+ AttributeSet attributeSet;
+ std::string tmp("atrS");
+ std::string tmpValue("Buu");
+ BaseAttributePtr atr(new Attribute(&tmp,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ DPL::StaticPointerCast<Attribute>(atr)->addValue(&tmpValue);
+ attributeSet.insert(atr);
+
+ AceDAO::setPolicyResult(attributeSet, PolicyDecision::NOT_APPLICABLE);
+ OptionalPolicyResult opt = AceDAO::getPolicyResult(attributeSet);
+
+ PolicyResult effect(PolicyEffect::DENY);
+ if (!opt.IsNull()) {
+ effect = *opt;
+ }
+
+ RUNNER_ASSERT(effect == PolicyDecision::NOT_APPLICABLE);
+}
+
+TESTSUITE06(07){
+ CLEANENV;
+ AttributeSet attributeSet;
+ std::string tmp("atrS");
+ std::string tmpValue("Buu");
+ BaseAttributePtr atr(new Attribute(&tmp,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ DPL::StaticPointerCast<Attribute>(atr)->addValue(&tmpValue);
+ attributeSet.insert(atr);
+
+ AceDAO::setPolicyResult(attributeSet, PolicyResult::UNDETERMINED);
+ OptionalPolicyResult opt = AceDAO::getPolicyResult(attributeSet);
+
+ PolicyResult effect(PolicyEffect::DENY);
+ if (!opt.IsNull()) {
+ effect = *opt;
+ }
+
+ RUNNER_ASSERT(effect == PolicyResult::UNDETERMINED);
+}
+
+TESTSUITE06(08){
+ CLEANENV;
+ AttributeSet attributeSet;
+ std::string tmp("atrS2");
+ std::string tmpValue("Buu2");
+ BaseAttributePtr atr(new Attribute(&tmp,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ DPL::StaticPointerCast<Attribute>(atr)->addValue(&tmpValue);
+ attributeSet.insert(atr);
+
+ std::string session = "jlakjhqrwebn234324987";
+ std::string param = "xxx";
+
+ AceDAO::setPromptDecision(attributeSet,
+ DPL::FromUTF8String(param),
+ DPL::FromUTF8String(session),
+ PromptDecision::ALLOW_ALWAYS);
+
+ OptionalCachedPromptDecision decision =
+ AceDAO::getPromptDecision(attributeSet, param);
+
+ DPL::String session1;
+ PromptDecision dec = PromptDecision::DENY_FOR_SESSION;
+ if (!decision.IsNull()){
+ dec = (*decision).decision;
+ if (!decision.IsNull()) {
+ session1 = *((*decision).session);
+ }
+ }
+ RUNNER_ASSERT(dec == PromptDecision::ALLOW_ALWAYS);
+ RUNNER_ASSERT(DPL::ToUTF8String(session1) == session);
+}
+
+TESTSUITE06(09){
+ CLEANENV;
+ AttributeSet attributeSet;
+ std::string tmp("atrS2");
+ std::string tmpValue("Buu2");
+ BaseAttributePtr atr(new Attribute(&tmp,
+ Attribute::Match::Equal,
+ Attribute::Type::Subject));
+ DPL::StaticPointerCast<Attribute>(atr)->addValue(&tmpValue);
+ attributeSet.insert(atr);
+
+ std::string param = "xxx";
+
+ AceDAO::setPromptDecision(attributeSet,
+ DPL::FromUTF8String(param),
+ DPL::OptionalString(),
+ PromptDecision::ALLOW_FOR_SESSION);
+
+ OptionalCachedPromptDecision decision =
+ AceDAO::getPromptDecision(attributeSet, param);
+
+ std::string session1;
+ PromptDecision dec = PromptDecision::DENY_FOR_SESSION;
+ if (!decision.IsNull()){
+ dec = (*decision).decision;
+ RUNNER_ASSERT((*decision).session.IsNull());
+ }
+ RUNNER_ASSERT(dec == PromptDecision::ALLOW_FOR_SESSION);
+}
+
+///*findVerdict*/
+//
+//void AceDAOTester::test3()
+//{
+//// Tests does verdict is stored for validity always
+// Request request("subject", "resource");
+// AttributeSet attributeSet;
+// std::string tmp("atrS3");
+// std::string tmpValue("Buu3");
+// BaseAttributePtr atr(
+// new Attribute(&tmp, Attribute::Match::Equal, Attribute::Type::Subject));
+// DPL::StaticPointerCast<Attribute>(atr)->addValue(&tmpValue);
+// attributeSet.insert(atr);
+// Verdict ver = Verdict::VERDICT_PERMIT;
+// Validity val = Validity::ALWAYS;
+// std::string session = getSession();
+// VerdictLogic::addVerdict(request, session, attributeSet, ver, val);
+// Verdict verdict = VerdictLogic::findVerdict(request, session, attributeSet);
+// bool result = VSPAssertEqual(verdict, Verdict::VERDICT_PERMIT);
+// handleResult(result, "find Verdict test 3");
+//}
+///*findVerdict*/
+//
+//void AceDAOTester::test4()
+//{
+////tests does verdict is propertly stored (NOT saved)when session is Validity::ONCE
+////and verdict is DENY
+// Request request("subject", "resource");
+// AttributeSet attributeSet;
+// std::string tmp("atrS4");
+// std::string tmpValue("Buu4");
+// BaseAttributePtr atr(
+// new Attribute(&tmp, Attribute::Match::Equal, Attribute::Type::Subject));
+// DPL::StaticPointerCast<Attribute>(atr)->addValue(&tmpValue);
+// attributeSet.insert(atr);
+// Verdict ver = Verdict::VERDICT_DENY;
+// Validity val = Validity::ONCE;
+// std::string session = getSession();
+// VerdictLogic::addVerdict(request, session, attributeSet, ver, val);
+// Verdict verdict = VerdictLogic::findVerdict(request, session, attributeSet);
+// bool result = VSPAssertEqual(verdict, Verdict::VERDICT_UNKNOWN);
+// handleResult(result, "find Verdict test 4");
+//}
+///*findVerdict*/
+//
+//void AceDAOTester::test5()
+//{
+////tests does verdict is properly set when validity is session
+////and verdict is deny
+// Request request("subject", "resource");
+// AttributeSet attributeSet;
+// std::string tmp("atrS5");
+// std::string tmpValue("Buu5");
+// BaseAttributePtr atr(
+// new Attribute(&tmp, Attribute::Match::Equal, Attribute::Type::Subject));
+// DPL::StaticPointerCast<Attribute>(atr)->addValue(&tmpValue);
+// attributeSet.insert(atr);
+// Verdict ver = Verdict::VERDICT_DENY;
+// Validity val = Validity::SESSION;
+// pip.setSessionId("5");
+// std::string session = getSession();
+// VerdictLogic::addVerdict(request, session, attributeSet, ver, val);
+// pip.setSessionId("5");
+// session = getSession();
+// Verdict verdict = VerdictLogic::findVerdict(request, session, attributeSet);
+// bool result = VSPAssertEqual(verdict, Verdict::VERDICT_DENY);
+// handleResult(result, "find Verdict test 5");
+//}
+///*findVerdict*/
+//
+//void AceDAOTester::test6()
+//{
+////tests does verdict is properly stored for DENY Validity::ALWAYS
+// Request request("subject", "resource");
+// AttributeSet attributeSet;
+// std::string tmp("atrS6");
+// std::string tmpValue("Buu6");
+// BaseAttributePtr atr(
+// new Attribute(&tmp, Attribute::Match::Equal, Attribute::Type::Subject));
+// DPL::StaticPointerCast<Attribute>(atr)->addValue(&tmpValue);
+// attributeSet.insert(atr);
+// Verdict ver = Verdict::VERDICT_DENY;
+// Validity val = Validity::ALWAYS;
+// std::string session = getSession();
+// VerdictLogic::addVerdict(request, session, attributeSet, ver, val);
+// Verdict verdict = VerdictLogic::findVerdict(request, session, attributeSet);
+// bool result = VSPAssertEqual(verdict, Verdict::VERDICT_DENY);
+// handleResult(result, "find Verdict test 6");
+//}
+//
+//
+//void AceDAOTester::test7()
+//{
+////tests stored version fo INAPPLICABLE Validity::ONCE
+//
+// Request request("subject", "resource");
+// AttributeSet attributeSet;
+// attributeSet.insert(constructAttribute("atrS7","Buu7"));
+// Verdict ver = Verdict::VERDICT_INAPPLICABLE;
+// Validity val = Validity::ONCE;
+// std::string session = getSession();
+// VerdictLogic::addVerdict(request, session, attributeSet, ver, val);
+// Verdict verdict = VerdictLogic::findVerdict(request, session, attributeSet);
+// //Verdict with 'Once' validity should not be stored, therefore
+// //the outcome should be UNKNOWN
+// bool result = VSPAssertEqual(verdict, Verdict::VERDICT_UNKNOWN);
+// handleResult(result, "find Verdict test 7");
+//}
+//
+//
+//void AceDAOTester::test8()
+//{
+////tests storing data for verdict INAPLICABLE and Validity::SESSION
+//
+// Request request("subject", "resource");
+// AttributeSet attributeSet;
+// attributeSet.insert(constructAttribute("atrS8","Buuu8"));
+// Verdict ver = Verdict::VERDICT_INAPPLICABLE;
+// Validity val = Validity::SESSION;
+// pip.setSessionId("8");
+// std::string session = getSession();
+// VerdictLogic::addVerdict(request, session, attributeSet, ver, val);
+// pip.setSessionId("9");
+// session = getSession();
+// Verdict verdict = VerdictLogic::findVerdict(request, session, attributeSet);
+// bool result = VSPAssertEqual(verdict, Verdict::VERDICT_UNKNOWN);
+// handleResult(result, "find Verdict test 8");
+//}
+///*findVerdict*/
+//
+//void AceDAOTester::test9()
+//{
+// Request request("subject", "resource");
+// AttributeSet attributeSet;
+// std::string tmp("atrS9");
+// std::string tmpValue("Buu9");
+// BaseAttributePtr atr(
+// new Attribute(&tmp, Attribute::Match::Equal, Attribute::Type::Subject));
+// DPL::StaticPointerCast<Attribute>(atr)->addValue(&tmpValue);
+// attributeSet.insert(atr);
+// Verdict ver = Verdict::VERDICT_INAPPLICABLE;
+// Validity val = Validity::ALWAYS;
+// std::string session = getSession();
+// VerdictLogic::addVerdict(request, session, attributeSet, ver, val);
+// Verdict verdict = VerdictLogic::findVerdict(request, session, attributeSet);
+// bool result = VSPAssertEqual(verdict, Verdict::VERDICT_INAPPLICABLE);
+// handleResult(result, "find Verdict test 9");
+//}
+///*findVerdict*/
+//
+//void AceDAOTester::test10()
+//{
+////tests does verdict is properly stored for verdict undetermined
+////and validity Validity::ONCE - thats why verdict is UNKNOWN
+// Request request("subject", "resource");
+// AttributeSet attributeSet;
+// std::string tmp("atrS10");
+// std::string tmpValue("Buu10");
+// BaseAttributePtr atr(
+// new Attribute(&tmp, Attribute::Match::Equal, Attribute::Type::Subject));
+// DPL::StaticPointerCast<Attribute>(atr)->addValue(&tmpValue);
+// attributeSet.insert(atr);
+// Verdict ver = Verdict::VERDICT_UNDETERMINED;
+// Validity val = Validity::ONCE;
+// std::string session = getSession();
+// VerdictLogic::addVerdict(request, session, attributeSet, ver, val);
+// Verdict verdict = VerdictLogic::findVerdict(request, session, attributeSet);
+// bool result = VSPAssertEqual(verdict, Verdict::VERDICT_UNKNOWN);
+// handleResult(result, "find Verdict test 10");
+//}
+///*findVerdict*/
+//
+//void AceDAOTester::test11()
+//{
+////tests does verdict is properly stored for verdict undetermined
+////and validity Validity::SESSION - TODO Verdicts for undetermined are not stored??
+// Request request("subject", "resource");
+// AttributeSet attributeSet;
+// std::string tmp("atrS11");
+// std::string tmpValue("Buu11");
+// BaseAttributePtr atr(
+// new Attribute(&tmp, Attribute::Match::Equal, Attribute::Type::Subject));
+// DPL::StaticPointerCast<Attribute>(atr)->addValue(&tmpValue);
+// attributeSet.insert(atr);
+// Verdict ver = Verdict::VERDICT_UNDETERMINED;
+// pip.setSessionId("8");
+// Validity val = Validity::SESSION;
+// pip.setSessionId("8");
+// std::string session = getSession();
+// VerdictLogic::addVerdict(request, session, attributeSet, ver, val);
+// Verdict verdict = VerdictLogic::findVerdict(request, session, attributeSet);
+// bool result = VSPAssertEqual(verdict, Verdict::VERDICT_UNKNOWN);
+// handleResult(result, "find Verdict test 11");
+//}
+///*findVerdict*/
+//
+//void AceDAOTester::test12()
+//{
+////tests does verdict is properly stored for verdict undetermined
+////and validity Validity::ALWAYS - TODO Verdicts for undetermined are not stored??
+// Request request("subject", "resource");
+// AttributeSet attributeSet;
+// std::string tmp("atrS12");
+// std::string tmpValue("Buu12");
+// BaseAttributePtr atr(
+// new Attribute(&tmp, Attribute::Match::Equal, Attribute::Type::Subject));
+// DPL::StaticPointerCast<Attribute>(atr)->addValue(&tmpValue);
+// attributeSet.insert(atr);
+// Verdict ver = Verdict::VERDICT_UNDETERMINED;
+// Validity val = Validity::ALWAYS;
+// std::string session = getSession();
+// VerdictLogic::addVerdict(request, session, attributeSet, ver, val);
+// Verdict verdict = VerdictLogic::findVerdict(request, session, attributeSet);
+// bool result = VSPAssertEqual(verdict, Verdict::VERDICT_UNKNOWN);
+// handleResult(result, "find Verdict test 12");
+//}
+///*findVerdict*/
+//
+//void AceDAOTester::test13()
+//{
+////tests does verdict is properly stored for verdict unknown
+////and validity Validity::ONCE-thats why verdict is not stored
+// Request request("subject", "resource");
+// AttributeSet attributeSet;
+// std::string tmp("atrS13");
+// std::string tmpValue("Buu13");
+// BaseAttributePtr atr(
+// new Attribute(&tmp, Attribute::Match::Equal, Attribute::Type::Subject));
+// DPL::StaticPointerCast<Attribute>(atr)->addValue(&tmpValue);
+// attributeSet.insert(atr);
+// Verdict ver = Verdict::VERDICT_UNKNOWN;
+// Validity val = Validity::ONCE;
+// std::string session = getSession();
+// VerdictLogic::addVerdict(request, session, attributeSet, ver, val);
+// Verdict verdict = VerdictLogic::findVerdict(request, session, attributeSet);
+// bool result = VSPAssertEqual(verdict, Verdict::VERDICT_UNKNOWN);
+// handleResult(result, "find Verdict test 13");
+//}
+///*findVerdict*/
+//
+//void AceDAOTester::test14()
+//{
+////tests does verdict is properly stored for verdict unknown
+////and validity session- TODO why is the verdict not stored?
+// Request request("subject", "resource");
+// AttributeSet attributeSet;
+// std::string tmp("atrS14");
+// std::string tmpValue("Buu14");
+// BaseAttributePtr atr(
+// new Attribute(&tmp, Attribute::Match::Equal, Attribute::Type::Subject));
+// DPL::StaticPointerCast<Attribute>(atr)->addValue(&tmpValue);
+// attributeSet.insert(atr);
+// Verdict ver = Verdict::VERDICT_UNKNOWN;
+// Validity val = Validity::SESSION;
+// pip.setSessionId("8");
+// std::string session = getSession();
+// VerdictLogic::addVerdict(request, session, attributeSet, ver, val);
+// pip.setSessionId("8");
+// session = getSession();
+// Verdict verdict = VerdictLogic::findVerdict(request, session, attributeSet);
+// bool result = VSPAssertEqual(verdict, Verdict::VERDICT_UNKNOWN);
+// handleResult(result, "find Verdict test 14");
+//}
+///*findVerdict*/
+//
+//void AceDAOTester::test15()
+//{
+////tests does verdict is properly stored for verdict unknown and
+////validity Validity::ALWAYS - TODO should we save Unknown verdict?
+// Request request("subject", "resource");
+// AttributeSet attributeSet;
+// std::string tmp("atrS15");
+// std::string tmpValue("Buu15");
+// BaseAttributePtr atr(
+// new Attribute(&tmp, Attribute::Match::Equal, Attribute::Type::Subject));
+// DPL::StaticPointerCast<Attribute>(atr)->addValue(&tmpValue);
+// attributeSet.insert(atr);
+// Verdict ver = Verdict::VERDICT_UNKNOWN;
+// Validity val = Validity::ALWAYS;
+// std::string session = getSession();
+// VerdictLogic::addVerdict(request, session, attributeSet, ver, val);
+// Verdict verdict = VerdictLogic::findVerdict(request, session, attributeSet);
+// bool result = VSPAssertEqual(verdict, Verdict::VERDICT_UNKNOWN);
+// handleResult(result, "find Verdict test 15");
+//}
+//
+///*removeVerdict*/ //tests does verdict is properly removed
+//void AceDAOTester::test16()
+//{
+// Request request("subject", "resource");
+// AttributeSet attributeSet;
+// std::string tmp("atrS15");
+// std::string tmpValue("Buu15");
+// BaseAttributePtr atr(
+// new Attribute(&tmp, Attribute::Match::Equal, Attribute::Type::Subject));
+// DPL::StaticPointerCast<Attribute>(atr)->addValue(&tmpValue);
+// attributeSet.insert(atr);
+//
+// Verdict ver = Verdict::VERDICT_PERMIT;
+// Validity val = Validity::ALWAYS;
+// //add verdict
+// std::string session = getSession();
+// VerdictLogic::addVerdict(request, session, attributeSet, ver, val);
+// //check has verdict been stored?
+// Verdict verdict = VerdictLogic::findVerdict(request, session, attributeSet);
+// bool result = VSPAssertEqual(verdict, Verdict::VERDICT_PERMIT);
+// handleResult(result, "find Verdict test 16: partA");
+//
+// //remove verdict
+// VerdictLogic::removeVerdict(request, attributeSet);
+// //verified removed
+// verdict = VerdictLogic::findVerdict(request, session, attributeSet);
+// result = VSPAssertEqual(verdict, Verdict::VERDICT_UNKNOWN);
+// handleResult(result, "find Verdict test 16: partB");
+//}
+//
+///*findVerdict*/
+//void AceDAOTester::test18()
+//{
+////verdict for 3 elements on the set of attributes
+// Request request("subject18","resource");
+// AttributeSet attributeSet;
+// std::string tmp("atrS60");
+// std::string tmpValue("Buu60");
+// BaseAttributePtr atr(
+// new Attribute(&tmp, Attribute::Match::Equal, Attribute::Type::Subject));
+// DPL::StaticPointerCast<Attribute>(atr)->addValue(&tmpValue);
+// attributeSet.insert(atr);
+//
+// std::string tmp1("atrS61");
+// std::string tmpValue1("Buu61");
+// BaseAttributePtr atr1(
+// new Attribute(&tmp1,Attribute::Match::Equal, Attribute::Type::Subject));
+// DPL::StaticPointerCast<Attribute>(atr1)->addValue(&tmpValue1);
+// attributeSet.insert(atr1);
+//
+// std::string tmp2("atrS62");
+// std::string tmpValue2("Buu62");
+// BaseAttributePtr atr2(
+// new Attribute(&tmp2,Attribute::Match::Equal, Attribute::Type::Subject));
+// DPL::StaticPointerCast<Attribute>(atr2)->addValue(&tmpValue2);
+// attributeSet.insert(atr2);
+//
+// Verdict ver = Verdict::VERDICT_DENY;
+// Validity val = Validity::ALWAYS;
+// std::string session = getSession();
+// VerdictLogic::addVerdict(request, session, attributeSet, ver, val);
+// Verdict verdict = VerdictLogic::findVerdict(request, session, attributeSet);
+// bool result = VSPAssertEqual(verdict, Verdict::VERDICT_DENY);
+// handleResult(result, "find Verdict test 18");
+//}
+//
+///*resetDatabase*/
+//void AceDAOTester::test19()
+//{
+// //tests reset DB
+// Request request("subject", "resource");
+// AttributeSet attributeSet;
+// std::string tmp("atrS15");
+// std::string tmpValue("Buu15");
+// BaseAttributePtr atr(
+// new Attribute(&tmp, Attribute::Match::Equal, Attribute::Type::Subject));
+// DPL::StaticPointerCast<Attribute>(atr)->addValue(&tmpValue);
+// attributeSet.insert(atr);
+//
+// Verdict ver = Verdict::VERDICT_PERMIT;
+// Validity val = Validity::ALWAYS;
+// //add verdict
+// std::string session = getSession();
+// VerdictLogic::addVerdict(request, session, attributeSet, ver, val);
+// //check has verdict been stored?
+// Verdict verdict = VerdictLogic::findVerdict(request, session, attributeSet);
+// bool result = VSPAssertEqual(verdict, Verdict::VERDICT_PERMIT);
+// handleResult(result, "reset database test 19: partA");
+//
+// AceDAO::resetDatabase();
+//
+// verdict = VerdictLogic::findVerdict(request, session, attributeSet);
+// result = VSPAssertEqual(verdict, Verdict::VERDICT_UNKNOWN);
+// handleResult(result, "reset database test 19: partB");
+//}
+
+
+/*setWidgetDevCapSetting*/
+
+TESTSUITE06(26){
+ CLEANENV;
+ std::string res("res20");
+ WidgetHandle sub = 20;
+
+ SettingsLogic::setWidgetDevCapSetting(res, sub, Preference::PREFERENCE_PERMIT);
+ std::list<PermissionTriple> userSettings;
+ SettingsLogic::getWidgetDevCapSettings(&userSettings);
+ RUNNER_ASSERT(
+ UserSettingEqual(
+ &userSettings, res, sub, Preference::PREFERENCE_PERMIT));
+}
+
+/*setWidgetDevCapSetting*/
+
+TESTSUITE06(27){
+ CLEANENV;
+ std::string res("res21");
+ WidgetHandle sub = 21;
+
+ SettingsLogic::setWidgetDevCapSetting(res, sub, Preference::PREFERENCE_DENY);
+ std::list<PermissionTriple> userSettings;
+ SettingsLogic::getWidgetDevCapSettings(&userSettings);
+ RUNNER_ASSERT(
+ UserSettingEqual(
+ &userSettings, res, sub, Preference::PREFERENCE_DENY));
+}
+
+/*setWidgetDevCapSetting*/
+
+TESTSUITE06(28){
+ CLEANENV;
+ std::string res("res22");
+ WidgetHandle sub = 22;
+ AceDAO::clearAllSettings();
+ SettingsLogic::setWidgetDevCapSetting(res, sub, Preference::PREFERENCE_DEFAULT);
+ std::list<PermissionTriple> userSettings;
+ SettingsLogic::getWidgetDevCapSettings(&userSettings);
+ RUNNER_ASSERT(
+ UserSettingEqual(
+ &userSettings, res, sub, Preference::PREFERENCE_DEFAULT));
+}
+
+TESTSUITE06(29){
+ CLEANENV;
+ std::string res("res23");
+ WidgetHandle sub = 23;
+
+ SettingsLogic::setWidgetDevCapSetting(res, sub, Preference::PREFERENCE_DEFAULT);
+ SettingsLogic::setWidgetDevCapSetting(res, sub, Preference::PREFERENCE_DENY);
+ std::list<PermissionTriple> userSettings;
+ SettingsLogic::getWidgetDevCapSettings(&userSettings);
+ RUNNER_ASSERT(
+ UserSettingEqual(
+ &userSettings, res, sub, Preference::PREFERENCE_DENY));
+}
+
+/*setWidgetDevCapSettings*/
+
+TESTSUITE06(30){
+ CLEANENV;
+ std::string resa("res24a");
+ WidgetHandle suba = 241;
+ std::string resb("res24b");
+ WidgetHandle subb = 242;
+
+ std::list<PermissionTriple> permissionsL;
+
+ permissionsL.push_back(
+ PermissionTriple(suba, resa, Preference::PREFERENCE_DENY));
+ permissionsL.push_back(
+ PermissionTriple(subb, resb, Preference::PREFERENCE_PERMIT));
+
+ SettingsLogic::setWidgetDevCapSettings(permissionsL);
+
+ std::list<PermissionTriple> userSettings;
+ SettingsLogic::getWidgetDevCapSettings(&userSettings);
+ RUNNER_ASSERT(
+ UserSettingsAgreed(&permissionsL, &userSettings));
+}
+
+
+
+TESTSUITE06(31){
+ CLEANENV;
+//multi set - if value is not set in DB or has DEFAUL value it is not
+//send by getWidgetDevCapSettings - optimization
+
+ std::string resa("res25a");
+ WidgetHandle suba = 251;
+ std::string resb("res25b");
+ WidgetHandle subb = 252;
+ std::string resc("res25c");
+ WidgetHandle subc = 253;
+
+ std::list<PermissionTriple> permissionsL;
+
+ permissionsL.push_back(
+ PermissionTriple(suba, resa, Preference::PREFERENCE_DENY));
+ permissionsL.push_back(
+ PermissionTriple(subb, resb, Preference::PREFERENCE_PERMIT));
+ permissionsL.push_back(
+ PermissionTriple(subc, resc, Preference::PREFERENCE_DEFAULT));
+
+
+ SettingsLogic::setWidgetDevCapSettings(permissionsL);
+
+ std::list<PermissionTriple> userSettings;
+ SettingsLogic::getWidgetDevCapSettings(&userSettings);
+ RUNNER_ASSERT(UserSettingsAgreed(&permissionsL, &userSettings));
+}
+
+TESTSUITE06(32){
+ CLEANENV;
+ //empty list -- TODO what is it testing?
+ std::list<PermissionTriple> permissionsL;
+
+ std::list<PermissionTriple> userSettings;
+ SettingsLogic::getWidgetDevCapSettings(&userSettings);
+ RUNNER_ASSERT(UserSettingsAgreed(&permissionsL, &userSettings));
+}
+
+TESTSUITE06(33){
+ CLEANENV;
+ //test resource setting PERMIT
+ std::string res("res27");
+ SettingsLogic::setDevCapSetting(res, Preference::PREFERENCE_PERMIT);
+ std::map<std::string, Preference> resourceSettings;
+ SettingsLogic::getDevCapSettings(&resourceSettings);
+
+ RUNNER_ASSERT(
+ ResourceSettingEqual(&resourceSettings,
+ res,
+ Preference::PREFERENCE_PERMIT));
+}
+
+TESTSUITE06(34){
+ CLEANENV;
+ //test resource setting DENY
+ std::string res("res28");
+ SettingsLogic::setDevCapSetting(res, Preference::PREFERENCE_DENY);
+ std::map<std::string, Preference> resourceSettings;
+ SettingsLogic::getDevCapSettings(&resourceSettings);
+
+ RUNNER_ASSERT(
+ ResourceSettingEqual(&resourceSettings,
+ res,
+ Preference::PREFERENCE_DENY));
+}
+
+TESTSUITE06(35){
+ CLEANENV;
+ //test resource setting Preference::PREFERENCE_DEFAULT
+
+ std::string res("res29");
+ SettingsLogic::setDevCapSetting(res, Preference::PREFERENCE_DEFAULT);
+ std::map<std::string, Preference> resourceSettings;
+ SettingsLogic::getDevCapSettings(&resourceSettings);
+
+ RUNNER_ASSERT(
+ ResourceSettingEqual(
+ &resourceSettings,
+ res,
+ Preference::PREFERENCE_DEFAULT));
+}
+
+TESTSUITE06(36){
+ CLEANENV;
+ //multi set for Resource settings
+
+ std::string resa("res30a");
+ std::string resb("res30b");
+
+ std::list< std::pair<const std::string*,Preference> >* resourcesL =
+ new std::list< std::pair<const std::string*, Preference> >();
+
+ resourcesL->push_back(make_pair(&resa, Preference::PREFERENCE_DENY));
+ resourcesL->push_back(make_pair(&resb, Preference::PREFERENCE_PERMIT));
+
+ SettingsLogic::setAllDevCapSettings (*resourcesL);
+
+ std::map<std::string, Preference> resourceSettings;
+ SettingsLogic::getDevCapSettings(&resourceSettings);
+ RUNNER_ASSERT(ResourceSettingsAgreed(resourcesL, &resourceSettings));
+ delete resourcesL;
+}
+
+
+//void AceDAOTester::test31()
+//{
+// // session has changed (PERMIT).
+// //What is the verdict now?
+//
+// Request request("subject", "resource");
+// AttributeSet attributeSet;
+// std::string tmp("atrS31");
+// std::string tmpValue("Buu31");
+// BaseAttributePtr atr(
+// new Attribute(&tmp, Attribute::Match::Equal, Attribute::Type::Subject));
+// DPL::StaticPointerCast<Attribute>(atr)->addValue(&tmpValue);
+// attributeSet.insert(atr);
+// Verdict ver = Verdict::VERDICT_PERMIT;
+// Validity val = Validity::SESSION;
+// pip.setSessionId("aaa");
+//
+// std::string session = getSession();
+// VerdictLogic::addVerdict(request, session, attributeSet, ver, val);
+//
+// Verdict verdictA =
+// VerdictLogic::findVerdict(request, session, attributeSet);
+// bool resultA = VSPAssertEqual(verdictA, Verdict::VERDICT_PERMIT);
+// handleResult(resultA, "Verdict session test 31 session a");
+//
+// pip.setSessionId("bbb");
+// session = getSession();
+// Verdict verdictB =
+// VerdictLogic::findVerdict(request, session, attributeSet);
+// bool resultB = VSPAssertEqual(verdictB, Verdict::VERDICT_UNKNOWN);
+// handleResult(resultB, "Verdict session test 31 session b");
+//}
+
+
+//void AceDAOTester::test32()
+//{
+// //session has changed (DENY).
+// //what is the verdict?
+//
+// Request request("subject", "resource");
+// AttributeSet attributeSet;
+// std::string tmp("atrS32");
+// std::string tmpValue("Buu32");
+// BaseAttributePtr atr(
+// new Attribute(&tmp, Attribute::Match::Equal, Attribute::Type::Subject));
+// DPL::StaticPointerCast<Attribute>(atr)->addValue(&tmpValue);
+// attributeSet.insert(atr);
+// Verdict ver = Verdict::VERDICT_DENY;
+// Validity val = Validity::SESSION;
+// pip.setSessionId("aaa");
+// std::string session = getSession();
+// VerdictLogic::addVerdict(request, session, attributeSet, ver, val);
+//
+// Verdict verdictA =
+// VerdictLogic::findVerdict(request, session, attributeSet);
+// bool resultA = VSPAssertEqual(verdictA, Verdict::VERDICT_DENY);
+// handleResult(resultA, "Verdict session test 32 session a");
+//
+// pip.setSessionId("ccc");
+//
+// session = getSession();
+// Verdict verdictB =
+// VerdictLogic::findVerdict(request, session, attributeSet);
+// bool resultB = VSPAssertEqual(verdictB, Verdict::VERDICT_UNKNOWN);
+// handleResult(resultB, "Verdict session test 32 session b");
+//}
+
+//void AceDAOTester::test33(){
+//
+// Request request("subject", "resource");
+// AttributeSet attributeSet;
+// std::string tmp("atrS33");
+// std::string tmpValue("Buu33");
+// BaseAttributePtr atr(new Attribute(&tmp, Attribute::Match::Equal, Attribute::Type::Subject));
+// DPL::StaticPointerCast<Attribute>(atr)->addValue(&tmpValue);
+// attributeSet.insert(atr);
+// Verdict ver = Verdict::VERDICT_INAPPLICABLE;
+// Validity val = Validity::SESSION;
+// pip.setSessionId("aaa");
+// std::string session = getSession();
+// VerdictLogic::addVerdict(request, session, attributeSet, ver, val);
+//
+// Verdict verdictA = VerdictLogic::findVerdict(request, session, attributeSet);
+// bool resultA = VSPAssertEqual(verdictA, Verdict::VERDICT_INAPPLICABLE);
+// handleResult(resultA, "Verdict session test 33 session a");
+//
+// pip.setSessionId("bbb");
+//
+// session = getSession();
+// Verdict verdictB = VerdictLogic::findVerdict(request, session, attributeSet);
+// bool resultB = VSPAssertEqual(verdictB, Verdict::VERDICT_UNKNOWN);
+// handleResult(resultB, "Verdict session test 33 session b");
+//}
+
+//void AceDAOTester::test34(){ //session has changed (UNDETERMINED).
+////what is the verdict?
+//
+// Request request("subject", "resource");
+// AttributeSet attributeSet;
+// std::string tmp("atrS34");
+// std::string tmpValue("Buu34");
+// BaseAttributePtr atr(new Attribute(&tmp, Attribute::Match::Equal, Attribute::Type::Subject));
+// DPL::StaticPointerCast<Attribute>(atr)->addValue(&tmpValue);
+// attributeSet.insert(atr);
+// Verdict ver = Verdict::VERDICT_UNDETERMINED;
+// Validity val = Validity::SESSION;
+// pip.setSessionId("aaa");
+// std::string session = getSession();
+// VerdictLogic::addVerdict(request, session, attributeSet, ver, val);
+//
+// Verdict verdictA = VerdictLogic::findVerdict(request, session, attributeSet);
+// bool resultA = VSPAssertEqual(verdictA, Verdict::VERDICT_UNKNOWN);
+// handleResult(resultA, "Verdict session test 34 session a");
+//
+// pip.setSessionId("bbb");
+//
+// session = getSession();
+// Verdict verdictB = VerdictLogic::findVerdict(request, session, attributeSet);
+// bool resultB = VSPAssertEqual(verdictB, Verdict::VERDICT_UNKNOWN);
+// handleResult(resultB, "Verdict session test 34 session b");
+//}
+
+//void AceDAOTester::test35(){ //session has changed(UNKNOWN),
+////what is the verdict?
+//
+// Request request("subject", "resource");
+// AttributeSet attributeSet;
+// std::string tmp("atrS35");
+// std::string tmpValue("Buu35");
+// BaseAttributePtr atr(new Attribute(&tmp, Attribute::Match::Equal, Attribute::Type::Subject));
+// DPL::StaticPointerCast<Attribute>(atr)->addValue(&tmpValue);
+// attributeSet.insert(atr);
+// Verdict ver = Verdict::VERDICT_UNKNOWN;
+// Validity val = Validity::SESSION;
+// pip.setSessionId("aaa");
+// std::string session = getSession();
+// VerdictLogic::addVerdict(request, session, attributeSet, ver, val);
+//
+// Verdict verdictA = VerdictLogic::findVerdict(request, session, attributeSet);
+// bool resultA = VSPAssertEqual(verdictA, Verdict::VERDICT_UNKNOWN);
+// handleResult(resultA, "Verdict session test 35 session a");
+// pip.setSessionId("bbb");
+//
+// session = getSession();
+// Verdict verdictB = VerdictLogic::findVerdict(request, session,attributeSet);
+// bool resultB = VSPAssertEqual(verdictB, Verdict::VERDICT_UNKNOWN);
+// handleResult(resultB, "Verdict session test 35 session b");
+//}
+
+//void AceDAOTester::test36(){ //changed verdict in the same session
+//
+// Request request("subject", "resource");
+// AttributeSet attributeSet;
+// std::string tmp("atrS36");
+// std::string tmpValue("Buu36");
+// BaseAttributePtr atr(new Attribute(&tmp, Attribute::Match::Equal, Attribute::Type::Subject));
+// DPL::StaticPointerCast<Attribute>(atr)->addValue(&tmpValue);
+// attributeSet.insert(atr);
+// Verdict ver = Verdict::VERDICT_DENY;
+// Validity val = Validity::SESSION;
+// pip.setSessionId("aaa");
+// std::string session = getSession();
+// VerdictLogic::addVerdict(request, session, attributeSet, ver, val);
+//
+// Verdict verdictA = VerdictLogic::findVerdict(request, session, attributeSet);
+// bool resultA = VSPAssertEqual(verdictA ,Verdict::VERDICT_DENY);
+// handleResult(resultA, "Verdict session test 36 session a");
+//
+// ver = Verdict::VERDICT_PERMIT;
+// VerdictLogic::addVerdict(request, session, attributeSet, ver, val);
+//
+// Verdict verdictB = VerdictLogic::findVerdict(request, session, attributeSet);
+// bool resultB = VSPAssertEqual(verdictB ,Verdict::VERDICT_PERMIT);
+// handleResult(resultB, "Verdict session test 36 session b");
+//}
+//
+///* User settings crash tests */
+//
+//
+//void AceDAOTester::test37(){ //empty attribute and verdict permit always
+// Request request("subject", "resource");
+// AttributeSet attributeSet;
+//
+// Verdict ver = Verdict::VERDICT_PERMIT;
+// Validity val = Validity::ALWAYS;
+//
+// std::string session = getSession();
+// VerdictLogic::addVerdict(request, session, attributeSet, ver, val);
+//
+// Verdict verdict = VerdictLogic::findVerdict(request, session, attributeSet);
+// bool result = VSPAssertEqual(verdict,Verdict::VERDICT_PERMIT);
+// handleResult(result, "find Verdict empty attribute set test 37 ");
+//}
+//
+//void AceDAOTester::test38(){ //empty attribute and verdict deny always
+// Request request("subject", "resource");
+// AttributeSet attributeSet;
+//
+// Verdict ver = Verdict::VERDICT_DENY;
+// Validity val = Validity::ALWAYS;
+//
+// std::string session = getSession();
+// VerdictLogic::addVerdict(request, session, attributeSet, ver, val);
+//
+// Verdict verdict = VerdictLogic::findVerdict(request, session, attributeSet);
+// bool result = VSPAssertEqual(verdict,Verdict::VERDICT_DENY);
+// handleResult(result, "find Verdict empty attribute set test 38 ");
+//}
+//
+//void AceDAOTester::test39(){
+//
+// Request request("subject", "resource");
+// AttributeSet attributeSet;
+//
+// Verdict ver = Verdict::VERDICT_INAPPLICABLE;
+// Validity val = Validity::ALWAYS;
+//
+// std::string session = getSession();
+// VerdictLogic::addVerdict(request, session, attributeSet, ver, val);
+//
+// Verdict verdict = VerdictLogic::findVerdict(request, session, attributeSet);
+// bool result = VSPAssertEqual(verdict,Verdict::VERDICT_INAPPLICABLE);
+// handleResult(result, "find Verdict empty attribute set test 39 ");
+//}
+//
+//void AceDAOTester::test40(){ //empty attribute and verdict unknown
+// Request request("subject", "resource");
+// AttributeSet attributeSet;
+//
+// Verdict ver = Verdict::VERDICT_UNKNOWN;
+// Validity val = Validity::ALWAYS;
+//
+// std::string session = getSession();
+// VerdictLogic::addVerdict(request, session, attributeSet, ver, val);
+//
+// Verdict verdict = VerdictLogic::findVerdict(request, session, attributeSet);
+// bool result = VSPAssertEqual(verdict,Verdict::VERDICT_UNKNOWN);
+// handleResult(result, "find Verdict empty attribute set test 40 ");
+//}
+//
+//void AceDAOTester::test41()
+//{
+// //empty string as subject and resource,
+// //without attributes and verdit DENY Validity::ALWAYS
+// Request request("", "");
+// //TODO is it OK to store Verdict::VERDICT for empty request?
+// AttributeSet attributeSet;
+//
+// Verdict ver = Verdict::VERDICT_DENY;
+// Validity val = Validity::ALWAYS;
+//
+// std::string session = getSession();
+// VerdictLogic::addVerdict(request, session, attributeSet, ver, val);
+//
+// Verdict verdict = VerdictLogic::findVerdict(request, session, attributeSet);
+// bool result = VSPAssertEqual(verdict,Verdict::VERDICT_DENY);
+// //bool result = VSPAssertEqual(verdict,Verdict::VERDICT_UNKNOWN);
+// handleResult(result, "find Verdict empty request empty "
+// "attribute set test 41 ");
+//}
+//
+//void AceDAOTester::test42(){
+// //empty string as subject and resource, without attributes
+// //and verdict is PERMIT Validity::ALWAYS
+// Request request("", "");
+//
+// AttributeSet attributeSet;
+// std::string tmp("atrS42");
+// std::string tmpValue("Buu342");
+// BaseAttributePtr atr(new Attribute(&tmp, Attribute::Match::Equal, Attribute::Type::Subject));
+// DPL::StaticPointerCast<Attribute>(atr)->addValue(&tmpValue);
+// attributeSet.insert(atr);
+//
+// Verdict ver = Verdict::VERDICT_PERMIT;
+// Validity val = Validity::ALWAYS;
+//
+// std::string session = getSession();
+// VerdictLogic::addVerdict(request, session, attributeSet, ver, val);
+//
+// Verdict verdict = VerdictLogic::findVerdict(request, session, attributeSet);
+// bool result = VSPAssertEqual(verdict,Verdict::VERDICT_PERMIT);
+// handleResult(result, "find Verdict empty request test 42 ");
+//}
+//
+//void AceDAOTester::test43(){
+// //TODO I have changed it! verdict
+// //has changed and stored in DB. does current verdict is the last one?
+//
+// Request request("ac", "ca");
+// AttributeSet attributeSet;
+//
+// Verdict ver = Verdict::VERDICT_DENY;
+// Verdict verp = Verdict::VERDICT_PERMIT;
+// Validity val = Validity::ALWAYS;
+//
+// std::string session = getSession();
+// VerdictLogic::addVerdict(request, session, attributeSet, ver, val);
+// VerdictLogic::addVerdict(request, session, attributeSet, verp, val);
+//
+// Verdict verdict = VerdictLogic::findVerdict(request, session, attributeSet);
+// bool result = VSPAssertEqual(verdict,Verdict::VERDICT_PERMIT);
+// handleResult(result, "find Verdict empty request empty "
+// "attribute set test 43 ");
+//}
+//
+//void AceDAOTester::test44(){
+// //empty subject and resource name - get Atributes list
+// Request request("","");
+//
+// AttributeSet attributeSet;
+// std::string tmp("atrS44");
+// std::string tmpValue("Buu44");
+// BaseAttributePtr atr(new Attribute(&tmp, Attribute::Match::Equal, Attribute::Type::Subject));
+// DPL::StaticPointerCast<Attribute>(atr)->addValue(&tmpValue);
+// attributeSet.insert(atr);
+//
+// Verdict ver = Verdict::VERDICT_PERMIT;
+// Validity val = Validity::ALWAYS;
+// std::string session = getSession();
+// VerdictLogic::addVerdict(request, session, attributeSet, ver, val);
+//
+// AttributeSet attributeS;
+// AceDAO::getAttributes(&attributeS);
+//
+// bool result = false;
+//
+// result = AttributeEqual(attributeSet,attributeS);
+//
+// handleResult(!result,"find Attributes empty request test 44");
+//}
+//
+//void AceDAOTester::test45(){
+// //empty subject and resource name - what is the verdict? - is it OK??
+// Request request("", "");
+// AttributeSet attributeSet;
+// std::string tmp("atrS15");
+// std::string tmpValue("Buu15");
+// BaseAttributePtr atr(new Attribute(&tmp, Attribute::Match::Equal, Attribute::Type::Subject));
+// DPL::StaticPointerCast<Attribute>(atr)->addValue(&tmpValue);
+// attributeSet.insert(atr);
+//
+// Verdict ver = Verdict::VERDICT_PERMIT;
+// Validity val = Validity::ALWAYS;
+// std::string session = getSession();
+// VerdictLogic::addVerdict(request, session, attributeSet, ver, val);
+//
+// VerdictLogic::removeVerdict(request, attributeSet);
+//
+// Verdict verdict = VerdictLogic::findVerdict(request, session, attributeSet);
+// bool result = VSPAssertEqual(verdict,Verdict::VERDICT_UNKNOWN);
+// handleResult(result, "find Verdict test 45");
+//}
+//
+//void AceDAOTester::test46(){
+// // TODO is it ok that for empty subject and resource name
+// // the verdict is not stored
+// Request requestemp("", "");
+// Request request("aa","bb");
+//
+// AttributeSet attributeSet;
+// std::string tmp("atrS46");
+// std::string tmpValue("Buu146");
+// BaseAttributePtr atr(new Attribute(&tmp, Attribute::Match::Equal, Attribute::Type::Subject));
+// DPL::StaticPointerCast<Attribute>(atr)->addValue(&tmpValue);
+// attributeSet.insert(atr);
+//
+// Verdict verAdd = Verdict::VERDICT_PERMIT;
+// Validity val = Validity::ALWAYS;
+// std::string session = getSession();
+// VerdictLogic::addVerdict(requestemp, session, attributeSet, verAdd, val);
+// VerdictLogic::addVerdict(request, session, attributeSet, verAdd, val);
+//
+// VerdictLogic::removeVerdict(requestemp, attributeSet);
+//
+// Verdict verdictA = VerdictLogic::findVerdict(requestemp, session, attributeSet);
+// bool resultA = VSPAssertEqual(verdictA,Verdict::VERDICT_UNKNOWN);
+// handleResult(resultA,"find Verdict test 46 A ");
+//
+// Verdict verdictB = VerdictLogic::findVerdict(request, session, attributeSet);
+// bool resultB = VSPAssertEqual(verdictB, Verdict::VERDICT_PERMIT);
+// handleResult(resultB,"find Verdict test 46 B ");
+//
+//}
+
+TESTSUITE06(53){
+ CLEANENV;
+ //Empty resource name
+ std::string res("");
+ SettingsLogic::setDevCapSetting(res, Preference::PREFERENCE_PERMIT);
+ std::map<std::string, Preference> resourceSettings;
+ SettingsLogic::getDevCapSettings(&resourceSettings);
+
+ RUNNER_ASSERT(
+ ResourceSettingEqual(
+ &resourceSettings,
+ res,
+ Preference::PREFERENCE_PERMIT));
+}
+
+//void AceDAOTester::test48(){
+// SettingsLogic::setResourceSetting(NULL, PERMIT);
+// std::map<std::string, Preference>* resourceSettings =
+// SettingsLogic::getResourceSettings();
+//
+// bool result = ResourceSettingEqual(resourceSettings, NULL,PERMIT );
+// handleResult(result, "get Resource Settings empty resource test 48");
+// printf("get Resource Settings empty resource test 48 -----> "
+// "Segmentation fault\n");
+//}
+
+TESTSUITE06(55){
+ CLEANENV;
+ //resource settings list with empty elemen
+
+ std::string resb("");
+
+ std::list< std::pair<const std::string*,Preference> > *resourcesL = new
+ std::list< std::pair<const std::string*, Preference> >();
+
+ resourcesL->push_back(make_pair(&resb, Preference::PREFERENCE_PERMIT));
+
+ SettingsLogic::setAllDevCapSettings (*resourcesL);
+
+ std::map<std::string, Preference> resourceSettings;
+ SettingsLogic::getDevCapSettings(&resourceSettings);
+ RUNNER_ASSERT(ResourceSettingsEqual(resourcesL, &resourceSettings));
+ delete resourcesL;
+}
+
+TESTSUITE06(56){
+ CLEANENV;
+ //user settings with empty subject and resource
+ //if resource or subject name is empty, values are not saved in DB
+ std::string resb("fake-resource");
+ WidgetHandle subb = 0;
+
+ std::list<PermissionTriple> permissionsL;
+
+ permissionsL.push_back(PermissionTriple(subb, resb, Preference::PREFERENCE_PERMIT));
+
+ SettingsLogic::setWidgetDevCapSettings(permissionsL);
+
+ std::list<PermissionTriple> userSettings;
+ SettingsLogic::getWidgetDevCapSettings(&userSettings);
+ RUNNER_ASSERT(UserSettingsAgreed(&permissionsL, &userSettings));
+}
+
+TESTSUITE06(57){
+ CLEANENV;
+ //user setting equal
+ // settings with at least one empty value is not set
+ std::string res("");
+ WidgetHandle sub = 0;
+
+ SettingsLogic::setWidgetDevCapSetting(res, sub, Preference::PREFERENCE_PERMIT);
+ std::list<PermissionTriple> userSettings;
+ SettingsLogic::getWidgetDevCapSettings(&userSettings);
+ RUNNER_ASSERT(
+ UserSettingNotStored(
+ &userSettings,
+ res,
+ sub,
+ Preference::PREFERENCE_PERMIT));
+}
+
+TESTSUITE06(58){
+ CLEANENV;
+ //user settings empty values and Default access
+
+ std::string res("");
+ WidgetHandle sub = 0;
+
+ SettingsLogic::setWidgetDevCapSetting(res, sub, Preference::PREFERENCE_DEFAULT);
+ std::list<PermissionTriple> userSettings;
+ SettingsLogic::getWidgetDevCapSettings(&userSettings);
+ RUNNER_ASSERT(
+ UserSettingNotStored(
+ &userSettings,
+ res,
+ sub,
+ Preference::PREFERENCE_DEFAULT));
+}
+
+//void AceDAOTester::test53(){
+// Request request("1 OR sv.verdict=1 --", "r53");
+// AttributeSet attributeSet;
+// std::string tmp("atrS53");
+// std::string tmpValue("Buu15");
+// BaseAttributePtr atr(new Attribute(&tmp, Attribute::Match::Equal, Attribute::Type::Subject));
+// DPL::StaticPointerCast<Attribute>(atr)->addValue(&tmpValue);
+// attributeSet.insert(atr);
+//
+//// Verdict ver = Verdict::VERDICT_PERMIT;
+//// Validity val = Validity::ALWAYS;
+//
+// std::string session = getSession();
+// Verdict verdict = VerdictLogic::findVerdict(request, session, attributeSet);
+// bool result = VSPAssertEqual(verdict, Verdict::VERDICT_UNKNOWN);
+// handleResult(result, "find Verdict test 53 sql injection");
+//}
+
+//void AceDAOTester::test54()
+//{
+// Request request("1' OR sv.verdict=1 --", "r53");
+// AttributeSet attributeSet;
+// std::string tmp("atrS54");
+// std::string tmpValue("Buu15");
+// BaseAttributePtr atr(new Attribute(&tmp, Attribute::Match::Equal, Attribute::Type::Subject));
+// DPL::StaticPointerCast<Attribute>(atr)->addValue(&tmpValue);
+// attributeSet.insert(atr);
+//
+// std::string session = getSession();
+// Verdict verdict = VerdictLogic::findVerdict(request, session, attributeSet);
+// bool result = VSPAssertEqual(verdict, Verdict::VERDICT_UNKNOWN);
+// handleResult(result, "find Verdict test 54 sql injection");
+//}
+//
+//void AceDAOTester::test55()
+//{
+// Request request("s55","r55");
+// AttributeSet attributeSet;
+// std::string session = getSession();
+// Verdict verdict = Verdict::VERDICT_PERMIT;
+// Validity validity = Validity::ALWAYS;
+//
+// VerdictLogic::addVerdict(request, session, attributeSet, verdict, validity);
+//
+// verdict = VerdictLogic::findVerdict(request, session, attributeSet);
+// bool result = VSPAssertEqual(verdict, Verdict::VERDICT_PERMIT);
+// handleResult(result, "Test 55a - clean database");
+//
+// SettingsLogic::setWidgetDevCapSetting(request.getResourceId(),
+// request.getSubjectId(),
+// Preference::PREFERENCE_DENY);
+//
+// Preference preference = SettingsLogic::findGlobalUserSettings(request);
+// handleResult(preference == Preference::PREFERENCE_DENY, "Test 55b - clean database");
+//
+// AceDAO::resetDatabase();
+//
+// verdict = VerdictLogic::findVerdict(request, session, attributeSet);
+// result = VSPAssertEqual(verdict, Verdict::VERDICT_UNKNOWN);
+// handleResult(result, "Test 55c - clean database");
+//
+// preference = SettingsLogic::findGlobalUserSettings(request);
+// handleResult(preference == Preference::PREFERENCE_DEFAULT,
+// "Test 55d - clean database");
+//}
+//
+//void AceDAOTester::test56(){
+// Request request("s56","r56");
+// AttributeSet attributeSet;
+// std::string session = getSession();
+// Verdict verdict = Verdict::VERDICT_PERMIT;
+// Validity validity = Validity::ALWAYS;
+//
+// std::string aName("atrS15");
+// std::string aValue1("a;");
+// std::string aValue2("b");
+// BaseAttributePtr atr(new Attribute(&aName, Attribute::Match::Equal, Attribute::Type::Subject));
+// DPL::StaticPointerCast<Attribute>(atr)->addValue(&aValue1);
+// DPL::StaticPointerCast<Attribute>(atr)->addValue(&aValue2);
+// attributeSet.insert(atr);
+//
+// VerdictLogic::addVerdict(request, session, attributeSet, verdict, validity);
+//
+// attributeSet.clear();
+// BaseAttributePtr atr1(new Attribute(&aName, Attribute::Match::Equal, Attribute::Type::Subject));
+// aValue1 = "a";
+// aValue2 = ";b";
+// DPL::StaticPointerCast<Attribute>(atr1)->addValue(&aValue1);
+// DPL::StaticPointerCast<Attribute>(atr1)->addValue(&aValue2);
+// attributeSet.insert(atr1);
+//
+// verdict = VerdictLogic::findVerdict(request, session, attributeSet);
+// bool result = VSPAssertEqual(verdict, Verdict::VERDICT_UNKNOWN);
+// handleResult(result, "Test 56 - attribute hash calculation check");
+//}
+
+
+//BaseAttributePtr AceDAOTester::constructAttribute(
+// const char * name,
+// const char * value,
+// Attribute::Match match,
+// Attribute::Type type)
+//{
+// std::string tmp(name);
+// std::string tmpValue(value);
+// BaseAttributePtr attr(new Attribute(&tmp, match, type));
+// DPL::StaticPointerCast<Attribute>(attr)->addValue(&tmpValue);
+// return attr;
+//}
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file TestSuite07.cpp
+ * @author unknown
+ * @version 1.0
+ * @brief Test cases for ConfigurationManager
+ */
+
+
+#include <dirent.h>
+#include <sys/types.h>
+
+#include <list>
+#include <string>
+
+#include <dpl/log/log.h>
+#include <dpl/test/test_runner.h>
+
+#include <dpl/ace/ConfigurationManager.h>
+
+#define TESTSUITE07(n,path) \
+RUNNER_TEST(ts07_configuration_mng_ ## n){ \
+ ConfigurationManagerTester cm; \
+ cm.setUp(); \
+ cm.parseTest(path);
+
+#define TESTSUITEEND \
+ cm.cleanUp(); \
+}
+
+class ConfigurationManagerTester : public ConfigurationManager {
+public:
+ int parseTest(const std::string &file) {
+ return parse(file);
+ }
+
+ const std::string& getConfigFileTest() const {
+ return getConfigFile();
+ }
+
+ void prepareDir(std::string & path);
+ void cleanUp();
+ void setUp();
+ bool assertPolicyNOTinAList(const char *) const;
+ bool assertIsCurrentPolicy(const char * policy);
+ bool assertEqual(const std::string& original, const std::string & intended);
+ bool assertFileExists(const char * policyFile) const;
+ bool assertFileDoesntExist(const char * policyFile) const;
+ bool assertEqual(const int original,const int intended) const;
+ bool assertPolicyInAList(const char *)const;
+
+ ConfigurationManagerTester() { }
+};
+
+TESTSUITE07(01,CONFIGURATION_MGR_TEST_CONFIG)
+ RUNNER_ASSERT(cm.assertIsCurrentPolicy("pms_general-test.xml") && cm.assertPolicyInAList("pms_general-test.xml"));
+TESTSUITEEND
+
+TESTSUITE07(02,CONFIGURATION_MGR_TEST_CONFIG)
+ RUNNER_ASSERT(cm.assertEqual(cm.getStoragePath(),
+ std::string(CONFIGURATION_MGR_TEST_POLICY_STORAGE)));
+TESTSUITEEND
+
+TESTSUITE07(03,CONFIGURATION_MGR_TEST_CONFIG)
+ LogInfo("Full path "<<cm.getFullPathToCurrentPolicyFile());
+ RUNNER_ASSERT(cm.assertEqual(cm.getFullPathToCurrentPolicyFile(),
+ std::string(CONFIGURATION_MGR_TEST_POLICY)));
+TESTSUITEEND
+
+TESTSUITE07(04,CONFIGURATION_MGR_TEST_CONFIG)
+ int ret = cm.addPolicyFile(std::string(CONFIGURATION_MGR_TEST_PATH"policyTest1.xml"));
+ RUNNER_ASSERT(cm.assertFileExists(CONFIGURATION_MGR_TEST_POLICY_STORAGE"/policyTest1.xml"));
+ RUNNER_ASSERT(cm.assertEqual(ret, ConfigurationManager::CM_OPERATION_SUCCESS));
+ RUNNER_ASSERT(cm.assertPolicyInAList("policyTest1.xml"));
+TESTSUITEEND
+
+TESTSUITE07(05,CONFIGURATION_MGR_TEST_CONFIG)
+ int ret = cm.addPolicyFile(std::string(CONFIGURATION_MGR_TEST_PATH"policyTest1.xml"));
+ RUNNER_ASSERT(cm.assertFileExists(CONFIGURATION_MGR_TEST_POLICY_STORAGE"/policyTest1.xml"));
+ RUNNER_ASSERT(cm.assertEqual(ret, ConfigurationManager::CM_OPERATION_SUCCESS));
+ ret = cm.removePolicyFile(std::string("policyTest1.xml"));
+ RUNNER_ASSERT(cm.assertFileDoesntExist(CONFIGURATION_MGR_TEST_POLICY_STORAGE"/policyTest1.xml"));
+ RUNNER_ASSERT(cm.assertEqual(ret, ConfigurationManager::CM_OPERATION_SUCCESS));
+ RUNNER_ASSERT(cm.assertPolicyNOTinAList("policyTest1.xml"));
+TESTSUITEEND
+
+//Try to upload the file once again
+TESTSUITE07(06,CONFIGURATION_MGR_TEST_CONFIG)
+ int ret = cm.addPolicyFile(std::string(CONFIGURATION_MGR_TEST_PATH"policyTest1.xml"));
+ RUNNER_ASSERT(cm.assertFileExists(CONFIGURATION_MGR_TEST_POLICY_STORAGE"/policyTest1.xml"));
+ RUNNER_ASSERT(cm.assertEqual(ret, ConfigurationManager::CM_OPERATION_SUCCESS));
+ RUNNER_ASSERT(cm.assertPolicyInAList("policyTest1.xml"));
+TESTSUITEEND
+
+TESTSUITE07(07,CONFIGURATION_MGR_TEST_CONFIG)
+ int ret = cm.addPolicyFile(std::string(CONFIGURATION_MGR_TEST_PATH"policyTest2.xml"));
+ RUNNER_ASSERT(cm.assertFileExists(CONFIGURATION_MGR_TEST_POLICY_STORAGE"/policyTest2.xml"));
+ RUNNER_ASSERT(cm.assertEqual(ret, ConfigurationManager::CM_OPERATION_SUCCESS));
+ RUNNER_ASSERT(cm.assertPolicyInAList("policyTest2.xml"));
+TESTSUITEEND
+
+TESTSUITE07(08,CONFIGURATION_MGR_TEST_CONFIG)
+ int ret = cm.addPolicyFile(std::string(CONFIGURATION_MGR_TEST_PATH"notExitingPolicy.xml"));
+ RUNNER_ASSERT(cm.assertFileDoesntExist(CONFIGURATION_MGR_TEST_POLICY_STORAGE"/notExitingPolicy.xml"));
+ RUNNER_ASSERT(cm.assertEqual(ret, ConfigurationManager::CM_GENERAL_ERROR));
+ RUNNER_ASSERT(cm.assertPolicyNOTinAList("notExitingPolicy.xml"));
+TESTSUITEEND
+
+TESTSUITE07(09,CONFIGURATION_MGR_TEST_CONFIG)
+ int ret = cm.addPolicyFile(CONFIGURATION_MGR_TEST_PATH"policyTest1.xml");
+ RUNNER_ASSERT(cm.assertFileExists(CONFIGURATION_MGR_TEST_POLICY_STORAGE"/policyTest1.xml"));
+ RUNNER_ASSERT(cm.assertPolicyInAList("policyTest1.xml"));
+ ret = cm.addPolicyFile(CONFIGURATION_MGR_TEST_PATH"policyTest1.xml");
+ RUNNER_ASSERT(cm.assertEqual(ret, ConfigurationManager::CM_FILE_EXISTS));
+TESTSUITEEND
+
+TESTSUITE07(10,CONFIGURATION_MGR_TEST_CONFIG)
+ int ret = cm.removePolicyFile("policyTest12.xml");
+ RUNNER_ASSERT(cm.assertFileDoesntExist(CONFIGURATION_MGR_TEST_POLICY_STORAGE"/policyTest12.xml"));
+ RUNNER_ASSERT(cm.assertEqual(ret, ConfigurationManager::CM_REMOVE_NOT_EXISTING));
+ RUNNER_ASSERT(cm.assertPolicyNOTinAList("policyTest12.xml"));
+TESTSUITEEND
+
+TESTSUITE07(11,CONFIGURATION_MGR_TEST_CONFIG)
+ int ret = cm.removePolicyFile(cm.getCurrentPolicyFile());
+ RUNNER_ASSERT(cm.assertFileExists(cm.getFullPathToCurrentPolicyFile().c_str()));
+ RUNNER_ASSERT(cm.assertEqual(ret, ConfigurationManager::CM_REMOVE_CURRENT));
+ RUNNER_ASSERT(cm.assertPolicyInAList(cm.getCurrentPolicyFile().c_str()));
+TESTSUITEEND
+
+TESTSUITE07(12,CONFIGURATION_MGR_TEST_CONFIG)
+ std::string fullPathToCurrentPolicy(CONFIGURATION_MGR_TEST_PATH);
+ fullPathToCurrentPolicy+="active/";
+ fullPathToCurrentPolicy+= cm.getCurrentPolicyFile();
+ RUNNER_ASSERT(cm.assertEqual(cm.getFullPathToCurrentPolicyFile(), fullPathToCurrentPolicy));
+TESTSUITEEND
+
+TESTSUITE07(13,CONFIGURATION_MGR_TEST_CONFIG)
+ system("mv "CONFIGURATION_MGR_TEST_POLICY_STORAGE" "CONFIGURATION_MGR_TEST_POLICY_STORAGE_MOVED);
+ int ret = cm.addPolicyFile(CONFIGURATION_MGR_TEST_PATH"policyTest3.xml");
+ bool result = cm.assertEqual(ret, ConfigurationManager::CM_GENERAL_ERROR)
+ && cm.assertPolicyNOTinAList("policyTest3.xml");
+ system("mv "CONFIGURATION_MGR_TEST_POLICY_STORAGE_MOVED" "CONFIGURATION_MGR_TEST_POLICY_STORAGE);
+ RUNNER_ASSERT(result);
+TESTSUITEEND
+
+TESTSUITE07(14,CONFIGURATION_MGR_TEST_CONFIG)
+ cm.addPolicyFile(CONFIGURATION_MGR_TEST_PATH"policyTest3.xml");
+
+ system("mv "CONFIGURATION_MGR_TEST_POLICY_STORAGE" "CONFIGURATION_MGR_TEST_POLICY_STORAGE_MOVED);
+ int ret = cm.removePolicyFile("policyTest3.xml");
+ bool result = cm.assertEqual(ret, ConfigurationManager::CM_REMOVE_NOT_EXISTING)
+ && cm.assertPolicyNOTinAList("policyTest3.xml");
+ system("mv "CONFIGURATION_MGR_TEST_POLICY_STORAGE_MOVED" "CONFIGURATION_MGR_TEST_POLICY_STORAGE);
+ RUNNER_ASSERT(result);
+TESTSUITEEND
+
+/*
+ *
+ * Changing configuration
+ *
+ */
+TESTSUITE07(15,CONFIGURATION_MGR_TEST_CONFIG)
+ //Just make sure that policyTest1.xml has been added to the storage
+ cm.removePolicyFile("policyTest1.xml");
+ int ret = cm.addPolicyFile(CONFIGURATION_MGR_TEST_PATH"policyTest1.xml");
+ bool result = cm.assertEqual(ret,ConfigurationManager::CM_OPERATION_SUCCESS);
+
+ ret = cm.changeCurrentPolicyFile("policyTest1.xml");
+ result &= cm.assertEqual(ret, ConfigurationManager::CM_OPERATION_SUCCESS);
+ RUNNER_ASSERT(result);
+
+ cm.parseTest(cm.getConfigFileTest());
+ result = cm.assertEqual(cm.getCurrentPolicyFile(),"policyTest1.xml");
+ RUNNER_ASSERT(result);
+
+ ret = cm.changeCurrentPolicyFile("pms_general-test.xml");
+ result = cm.assertEqual(ret, ConfigurationManager::CM_OPERATION_SUCCESS);
+ RUNNER_ASSERT(result);
+
+ cm.parseTest(cm.getConfigFileTest());
+ result = cm.assertEqual(cm.getCurrentPolicyFile(),"pms_general-test.xml");
+ RUNNER_ASSERT(result);
+TESTSUITEEND
+
+/*
+ *===============
+ *
+ *END OF TESTS
+ *
+ *===============
+ */
+
+bool ConfigurationManagerTester::assertIsCurrentPolicy(const char * policy){
+
+ return getCurrentPolicyFile() == std::string(policy);
+
+}
+
+bool ConfigurationManagerTester::assertEqual(const std::string & actual,const std::string & intended){
+ LogDebug("Comparing "<<actual<<" with "<<intended);
+ return actual == intended;
+}
+
+bool ConfigurationManagerTester::assertEqual(const int original,const int intended) const{
+
+ bool tmp = original == intended;
+ LogInfo("Results comparing with outcome "<<tmp);
+ return tmp;
+}
+
+bool ConfigurationManagerTester::assertFileExists(const char * policyFile) const {
+ bool tmp = checkIfFileExistst(std::string(policyFile));
+ LogDebug("Assert File exists with result: "<<tmp);
+ return tmp;
+}
+
+bool ConfigurationManagerTester::assertFileDoesntExist(const char * policyFile) const {
+
+ bool temp = !checkIfFileExistst(std::string(policyFile));
+ LogDebug("Assert file doesn't exists result: "<<temp);
+ return temp;
+
+}
+
+bool ConfigurationManagerTester::assertPolicyInAList(const char * name)const{
+ bool found = false;
+ std::string expected(name);
+ for(std::list<std::string>::const_iterator it = getPolicyFiles().begin(); it!=getPolicyFiles().end(); ++it){
+ if( *it == expected ){
+ found = true;
+ break;
+ }
+ }
+
+ LogDebug("assert Policy in a list result: "<<found);
+ return found;
+}
+
+
+bool ConfigurationManagerTester::assertPolicyNOTinAList(const char * name) const{
+ return !assertPolicyInAList(name);
+}
+
+void ConfigurationManagerTester::cleanUp(){
+ DIR *dp;
+ struct dirent *dirp;
+ if( (dp = opendir(CONFIGURATION_MGR_TEST_POLICY_STORAGE) )== NULL ){
+ LogError("Error while cleaning up");
+ return;
+ }
+
+ while( (dirp = readdir(dp)) != NULL ) {
+ std::string fileName(dirp->d_name);
+ if( fileName == "pms_general-test.xml" || fileName == "bondixml.dtd" ||
+ fileName == "." || fileName ==".." ){
+ continue;
+ }
+ std::string fullPath(CONFIGURATION_MGR_TEST_POLICY_STORAGE"/");
+ fullPath.append(dirp->d_name);
+ if (removePolicyFile(fullPath) == CM_REMOVE_ERROR){
+ LogError("Cannot clean up. Exiting");
+ break;
+ };
+ }
+ //Restore the backup of config file
+ system("cp "CONFIGURATION_MGR_TEST_PATH"backup.xml "CONFIGURATION_MGR_TEST_CONFIG);
+}
+
+void ConfigurationManagerTester::setUp(){
+ //Create backup of config file
+ system("cp "CONFIGURATION_MGR_TEST_CONFIG" "CONFIGURATION_MGR_TEST_PATH"backup.xml");
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 Bartlomiej Grzelewski <b.grzelewski@samsung.com>
+ * @version 1.0
+ * @brief This file is the implementation file of main
+ */
+#include <string>
+
+#include <dpl/test/test_runner.h>
+#include <dpl/log/log.h>
+
+#include <loop_control.h>
+
+#include <dpl/ace-dao-rw/AceDAO.h>
+
+#include "Interfaces.h"
+#include "PEPSingleton.h"
+
+
+using namespace LoopControl;
+
+class UnitTestThread
+{
+public:
+ UnitTestThread()
+ {
+ // Attach databases
+ AceDB::AceDAO::attachToThread();
+ }
+
+ ~UnitTestThread()
+ {
+ // Detach databases
+ AceDB::AceDAO::detachFromThread();
+ }
+};
+
+int main (int argc, char *argv[])
+{
+ init_loop(argc, argv);
+
+ LogInfo("Initializing PEPSingleton.");
+
+ UnitTestThread attacher;
+
+ PEPSingleton::Instance().initialize(
+ new WebRuntimeImp(),
+ new ResourceInformationImp(),
+ new OperationSystemImp());
+
+ LogInfo("Starting tests.");
+
+ int status = DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv);
+
+ PEPSingleton::Instance().terminate();
+
+ quit_loop();
+ return status;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <dpl/log/log.h>
+
+#include <dpl/framework_efl.h>
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <loop_control.h>
+
+namespace LoopControl
+{
+void init_loop(int argc, char *argv[])
+{
+ (void)argc;
+ (void)argv;
+ g_type_init();
+ g_thread_init(NULL);
+
+ LogInfo("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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_ */
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+INSTALL(FILES
+ ${PROJECT_SOURCE_DIR}/tests/ace/test-configuration/CMTest/pms_config.xml
+ ${PROJECT_SOURCE_DIR}/tests/ace/test-configuration/CMTest/pms_general-test.xml
+ ${PROJECT_SOURCE_DIR}/tests/ace/test-configuration/CMTest/policyTest1.xml
+ ${PROJECT_SOURCE_DIR}/tests/ace/test-configuration/CMTest/policyTest2.xml
+ ${PROJECT_SOURCE_DIR}/tests/ace/test-configuration/CMTest/policyTest3.xml
+ DESTINATION /usr/etc/ace/CMTest
+ PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ GROUP_WRITE
+ )
+
+ADD_SUBDIRECTORY(active)
+
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+INSTALL(FILES
+ ${PROJECT_SOURCE_DIR}/tests/ace/test-configuration/CMTest/active/pms_general-test.xml
+ ${PROJECT_SOURCE_DIR}/tests/ace/test-configuration/CMTest/active/bondixml.dtd
+ DESTINATION /usr/etc/ace/CMTest/active
+ PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ GROUP_WRITE
+ )
+
--- /dev/null
+<!ENTITY % Object.ANY ''>
+<!ENTITY % Method.ANY ''>
+<!ENTITY % Transform.ANY ''>
+<!ENTITY % SignatureProperty.ANY ''>
+<!ENTITY % KeyInfo.ANY ''>
+<!ENTITY % KeyValue.ANY ''> <!-- TODO ECDSA IS NOT HANDLED YET -->
+<!ENTITY % PGPData.ANY ''>
+<!ENTITY % X509Data.ANY ''>
+<!ENTITY % SPKIData.ANY ''>
+
+
+<!ELEMENT signed-policy (Signature, ( policy-set | policy )* ) >
+<!-- Start Core Signature declarations, these should NOT be altered -->
+
+<!ELEMENT Signature (SignedInfo, SignatureValue, KeyInfo?, Object*) >
+<!ATTLIST Signature
+ xmlns CDATA #FIXED 'http://www.w3.org/2000/09/xmldsig#'
+ Id ID #IMPLIED >
+
+<!ELEMENT SignatureValue (#PCDATA) >
+<!ATTLIST SignatureValue
+ Id ID #IMPLIED>
+
+<!ELEMENT SignedInfo (CanonicalizationMethod,
+ SignatureMethod, Reference+) >
+<!ATTLIST SignedInfo
+ Id ID #IMPLIED
+>
+
+<!ELEMENT CanonicalizationMethod (#PCDATA %Method.ANY;)* >
+<!ATTLIST CanonicalizationMethod
+ Algorithm CDATA #REQUIRED >
+
+<!ELEMENT SignatureMethod (#PCDATA|HMACOutputLength %Method.ANY;)* >
+<!ATTLIST SignatureMethod
+ Algorithm CDATA #REQUIRED >
+
+<!ELEMENT Reference (DigestMethod, DigestValue) >
+<!ATTLIST Reference
+ Id ID #IMPLIED
+ URI CDATA #IMPLIED
+ Type CDATA #IMPLIED>
+
+
+<!ELEMENT XPath (#PCDATA) >
+
+<!ELEMENT DigestMethod (#PCDATA %Method.ANY;)* >
+<!ATTLIST DigestMethod
+ Algorithm CDATA #REQUIRED >
+
+<!ELEMENT DigestValue (#PCDATA) >
+
+<!ELEMENT KeyInfo (#PCDATA|KeyName|KeyValue|RetrievalMethod|
+ X509Data|PGPData|SPKIData|MgmtData %KeyInfo.ANY;)* >
+<!ATTLIST KeyInfo
+ Id ID #IMPLIED >
+
+<!-- Key Information -->
+
+<!ELEMENT KeyName (#PCDATA) >
+<!ELEMENT KeyValue (#PCDATA|DSAKeyValue|RSAKeyValue %KeyValue.ANY;)* >
+<!ELEMENT MgmtData (#PCDATA) >
+
+<!ELEMENT RetrievalMethod EMPTY>
+<!ATTLIST RetrievalMethod
+ URI CDATA #REQUIRED
+ Type CDATA #IMPLIED >
+
+<!-- X.509 Data -->
+
+<!ELEMENT X509Data ((X509IssuerSerial | X509SKI | X509SubjectName |
+ X509Certificate | X509CRL )+ %X509Data.ANY;)>
+<!ELEMENT X509IssuerSerial (X509IssuerName, X509SerialNumber) >
+<!ELEMENT X509IssuerName (#PCDATA) >
+<!ELEMENT X509SubjectName (#PCDATA) >
+<!ELEMENT X509SerialNumber (#PCDATA) >
+<!ELEMENT X509SKI (#PCDATA) >
+<!ELEMENT X509Certificate (#PCDATA) >
+<!ELEMENT X509CRL (#PCDATA) >
+
+<!-- PGPData -->
+
+<!ELEMENT PGPData ((PGPKeyID, PGPKeyPacket?) | (PGPKeyPacket) %PGPData.ANY;) >
+<!ELEMENT PGPKeyPacket (#PCDATA) >
+<!ELEMENT PGPKeyID (#PCDATA) >
+
+<!-- SPKI Data -->
+
+<!ELEMENT SPKIData (SPKISexp %SPKIData.ANY;) >
+<!ELEMENT SPKISexp (#PCDATA) >
+
+<!-- Extensible Content -->
+
+<!ELEMENT Object (#PCDATA|Signature|SignatureProperties|Manifest %Object.ANY;)* >
+<!ATTLIST Object
+ Id ID #IMPLIED
+ MimeType CDATA #IMPLIED
+ Encoding CDATA #IMPLIED >
+
+<!ELEMENT Manifest (Reference+) >
+<!ATTLIST Manifest
+ Id ID #IMPLIED >
+
+<!ELEMENT SignatureProperties (SignatureProperty+) >
+<!ATTLIST SignatureProperties
+ Id ID #IMPLIED >
+
+<!ELEMENT SignatureProperty (#PCDATA %SignatureProperty.ANY;)* >
+<!ATTLIST SignatureProperty
+ Target CDATA #REQUIRED
+ Id ID #IMPLIED >
+
+<!-- Algorithm Parameters -->
+
+<!ELEMENT HMACOutputLength (#PCDATA) >
+
+<!ELEMENT DSAKeyValue ((P, Q)?, G?, Y, J?, (Seed, PgenCounter)?) >
+<!ELEMENT P (#PCDATA) >
+<!ELEMENT Q (#PCDATA) >
+<!ELEMENT G (#PCDATA) >
+<!ELEMENT Y (#PCDATA) >
+<!ELEMENT J (#PCDATA) >
+<!ELEMENT Seed (#PCDATA) >
+<!ELEMENT PgenCounter (#PCDATA) >
+
+<!ELEMENT RSAKeyValue (Modulus, Exponent) >
+<!ELEMENT Modulus (#PCDATA) >
+<!ELEMENT Exponent (#PCDATA) >
+
+
+
+
+
+
+
+
+<!ELEMENT policy-set (target?, assert*, (policy-set | policy)*) >
+<!ATTLIST policy-set
+ combine (deny-overrides|permit-overrides|first-matching-target) "deny-overrides"
+ id ID #IMPLIED
+>
+
+<!ELEMENT policy (target?, assert*, rule*) >
+<!ATTLIST policy
+ combine (deny-overrides|permit-overrides|first-applicable) "deny-overrides"
+ description CDATA #IMPLIED
+ id ID #IMPLIED
+>
+
+<!ELEMENT assert (condition?, set*) >
+
+<!ELEMENT set EMPTY >
+<!ATTLIST set attr CDATA #REQUIRED >
+<!ATTLIST set value CDATA #REQUIRED >
+
+<!ELEMENT rule (condition?) >
+<!ATTLIST rule
+ effect (permit|prompt-blanket|prompt-session|prompt-oneshot|deny) "permit"
+>
+
+<!ELEMENT target (subject+) >
+
+<!ELEMENT subject (subject-match+) >
+
+<!ELEMENT condition ((condition | subject-match | resource-match | environment-match)+) >
+<!ATTLIST condition
+ combine (and|or) "and"
+>
+
+<!ENTITY % match-attrs '
+ attr CDATA #REQUIRED
+ match CDATA #IMPLIED
+ func (equal|glob|regexp) "glob"
+'>
+
+<!ELEMENT subject-match (#PCDATA)>
+<!ATTLIST subject-match %match-attrs; >
+
+<!ENTITY % match-model '
+ (#PCDATA | subject-attr | resource-attr | environment-attr)*
+'>
+
+<!ELEMENT resource-match %match-model;>
+<!ATTLIST resource-match %match-attrs;>
+
+<!ELEMENT environment-match %match-model;>
+<!ATTLIST environment-match %match-attrs;>
+
+<!ENTITY % attr-attrs 'attr CDATA #REQUIRED'>
+
+<!ELEMENT subject-attr EMPTY>
+<!ATTLIST subject-attr %attr-attrs;>
+
+<!ELEMENT resource-attr EMPTY>
+<!ATTLIST resource-attr %attr-attrs;>
+
+<!ELEMENT environment-attr EMPTY>
+<!ATTLIST environment-attr %attr-attrs;>
+
--- /dev/null
+<!DOCTYPE signed-policy SYSTEM "bondixml.dtd">
+
+<signed-policy>
+
+ <Signature Id="SignatureExample" xmlns="http://www.w3.org/2000/09/xmldsig#">
+ <SignedInfo>
+ <CanonicalizationMethod Algorithm="http://www.w2.org/2006/12/xml-c14n11"/>
+ <SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
+ <Reference URI="Policy-1">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-2">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-3">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-4">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-5">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-6">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-7">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-8">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-9">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-10">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-11">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-12">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-13">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-14">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-15">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-16">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-17">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ </SignedInfo>
+ <SignatureValue>asdfkjlhxvczxnbcvnjahfjhsdfklahfdas</SignatureValue>
+ <KeyInfo>
+ <KeyValue>
+ <DSAKeyValue>
+ <P> PValue </P><Q> QValue </Q><G> Gvalue </G><Y> laj?</Y>
+ </DSAKeyValue>
+ <RSAKeyValue>
+ <Modulus>
+ modulus
+ </Modulus>
+ <Exponent>
+ exponent
+ </Exponent>
+ </RSAKeyValue>
+ </KeyValue>
+ <X509Data>
+ <X509SubjectName> Subject name </X509SubjectName>
+ <X509SKI> SKI </X509SKI>
+ </X509Data>
+ </KeyInfo>
+ </Signature>
+
+
+
+<policy-set id="Policy-1">
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">
+ subject
+ </subject-match>
+ </subject>
+ <subject>
+ <subject-match attr="id" match="subject2" />
+ </subject>
+ </target>
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="id" match="subject" />
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource
+ </resource-match>
+ <subject-match attr="version" match="3" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="id" match="subject2" />
+ </subject>
+ </target>
+ <rule effect="deny">
+ <condition>
+ <resource-match attr="resource-id">
+ resource
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<policy-set >
+ <target>
+ <subject>
+ <subject-match attr="id">
+ subject3
+ </subject-match>
+ </subject>
+ <subject>
+ <subject-match attr="id" match="subject4" />
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource2
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition>
+ <resource-match attr="resource-id">
+ resource2
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="id">
+ subject4
+ </subject-match>
+ <subject-match attr="version" match="4" />
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<policy-set id="Policy-2" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id" match="subject5" />
+ </subject>
+ <subject>
+ <subject-match attr="id" match="subject6" />
+ </subject>
+ </target>
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="id">
+ subject5
+ </subject-match>
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource5
+ </resource-match>
+ <subject-match attr="version" match="5" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <resource-match attr="resource-id">
+ resource6
+ </resource-match>
+ <subject-match attr="version" match="6" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-3" combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id" match="subject7" />
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource7
+ </resource-match>
+ <condition combine="and">
+ <condition combine="or">
+ <subject-match attr="version" match="7" />
+ <subject-match attr="version" match="6" />
+ </condition>
+ <resource-match attr="author" match="author2" />
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource7
+ </resource-match>
+ <condition combine="or">
+ <condition combine="or">
+ <subject-match attr="version" match="1" />
+ <subject-match attr="version" match="2" />
+ </condition>
+ <resource-match attr="author" match="author3" />
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource7
+ </resource-match>
+ <condition combine="or">
+ <condition combine="or">
+ <subject-match attr="version" match="1" />
+ <subject-match attr="version" match="2" />
+ </condition>
+ <resource-match attr="author" match="author3" />
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+
+<policy-set id="Policy-4" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s8a</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r8</resource-match>
+ <resource-match attr="r8v1" match="1" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r8</resource-match>
+ <resource-match attr="r8v2" match="2" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-5" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s8b</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r8</resource-match>
+ <resource-match attr="r8v2" match="2" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r8</resource-match>
+ <resource-match attr="r8v1" match="1" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-6" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s8c</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r8</resource-match>
+ <resource-match attr="r8v1" match="1" />
+ <resource-match attr="r8v2" match="1" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny" />
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-7" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9a</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9a.scheme" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9a" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-8" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9b</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9b.authority" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9b" match="777" func="equal" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-9" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9c</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9c.scheme" match="http" />
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9c.authority" match="onet.pl" />
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9c.scheme-authority" match="http://onet.pl" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9c" match="*" func="glob" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-10" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9d</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9d.scheme" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9d.authority" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9d" match="*" func="glob" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9d.scheme-authority" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-11" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9e</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9e.host" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9e" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-12" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9f</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9e.host" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9e" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-13" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9g</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9g.path" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9g" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-14" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9h</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9g.path" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9g" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-15" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s10a</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10a" match="[1234567890]+[ab]+" func="regexp" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10a" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-16" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s10b</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10a" match="[1234567890]+[ab]+" func="regexp" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10a" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-17" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s10c</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10c" match="[1234567890]+[ab]+" func="regexp" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10c" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!-- justyna -->
+
+<!--- test 13 (old name: test 100)-->
+
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s13</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 14 (old name: test 101)-->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s14</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 15 (old name: test 102) -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="uri.host" match="//buu.com.pl"/>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 16 (old name: test 103) -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s16</subject-match>
+ <subject-match attr="uri.host" match="v.com.pl"/>
+
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 17 (old name: test 104)-->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">subject4</subject-match>
+ <subject-match attr="version" match="4" />
+ </subject>
+ </target>
+<policy>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">subject5</subject-match>
+ <subject-match attr="version" match="4" />
+ </subject>
+ </target>
+<policy>
+ <rule effect="deny">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 18 (old name: test 105)-->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="uri" match="buu.com.pl"/>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id" match="s18b"/>
+ <subject-match attr="uri" match="buu.s18b.pl"/>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id" match="s18c"/>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="uri" match="buu.s18c.pl"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 19 (old name: test 106)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s19.1</subject-match>
+ <subject-match attr="key-root-trust" match="voperator"/>
+ </subject>
+ </target>
+<policy>
+ <rule effect="deny">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s19.2</subject-match>
+ <subject-match attr="key-root-trust" match="voperator"/>
+ </subject>
+ </target>
+<policy>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 20 (old name: test 107)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s20.1</subject-match>
+ <subject-match attr="signer-id" match="v7zha89%49x£$"/>
+ </subject>
+ </target>
+<policy>
+ <rule effect="deny">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s20.2</subject-match>
+ <subject-match attr="signer-id" match="v7zha89%49x£$"/>
+ </subject>
+ </target>
+<policy>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!-- justyna -->
+
+
+<!--- test 21 (old name: test 103 U)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s21</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 23 (old name: test 105 U)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s23</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 24 (old name: test 106 U)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s24</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <subject-match attr="version" match="5"/>
+ <resource-match attr="resource-id" match="device:pim"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 25.1 (old name: test 107 U)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s25.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 25.2 (old name: test 107 a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s25.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 25.3 (old name: test 107 b U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s25.3</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 25.4 (old name: test 107 c U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s25.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 26.1 (old name: test 108 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s26.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 26.2 (old name: test 108 a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s26.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 26.3 (old name: test 108 b U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s26.3</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 26.4 (old name: test 108 c U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s26.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 27.1 (old name: test 109 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s27.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 27.2 (old name: test 109a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s27.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 27.3 (old name: test 109b U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s27.3</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 27.4 (old name: test 109c U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s27.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 28 (old name: test 110 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s28</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 29 (old name: test 111 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s29</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 30.1 (old name: test 112 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s30.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 30.2 (old name: test 112a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s30.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 30.3 (old name: test 112b U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s30.3</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 30.4 (old name: test 112c U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s30.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+</policy-set>
+
+
+
+<!--- test 31.1 (old name: test 113 U -->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s31.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 31.2.1 (old name: test 113a U -->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s31.2.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 31.2.2 (old name: test 113aa U -->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s31.2.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 31.3 (old name: test 113b U -->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s31.3</subject-match>
+ </subject>
+ </target>
+
+
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+</policy-set>
+
+<!--- test 32.1 (old name: test 114 U -->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s32.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 32.2.1 (old name: test 114a U -->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s32.2.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 32.2.2 (old name: test 114aa U -->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s32.2.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 32.3 (old name: test 114b U -->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s32.3</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 33.1 (old name: test 115 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s33.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 33.2 (old name: test 115a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s33.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 33.3 (old name: test 115b U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s33.3</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 34.1 (old name: test 116 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s34.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="permit-overrides">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 34.2 (old name: test 116 a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s34.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="permit-overrides">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 35.1 (old name: test 117 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s35.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="deny-overrides">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 35.2 (old name: test 117 a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s35.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="deny-overrides">
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set>
+ <target>
+ <subject>
+ <subject-match attr="id">org.tizen.widget.analogclock</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="http://helloheloo/"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 36 (old name: test 102 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s36</subject-match>
+ <subject-match attr="version" match="5"/>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+
+<!--- test 37 (old name: test 108 -->
+<!-- mbialota modified -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s37</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="prompt-oneshot">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 38 (old name: test 109 -->
+<!-- mbialota modified -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s38</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="prompt-session">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s38.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="prompt-session">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 39 (old name: test 110 -->
+<!-- mbialota modified -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s39</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="prompt-blanket">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s39.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="prompt-blanket">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!-- Maria -->
+<!-- testing different methods of policies and rules combining-->
+<!--- test 40 (old name: test 200 -->
+
+<!--- two opposite rules put into different policies in one policy set -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s40</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r40</resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r40</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 41 (old name: test 201 -->
+
+<!--- two different rules put into different policies in one policy set-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s41</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r41</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r41.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 42.1 (old name: test 202 -->
+<!--- two opposite rules put into one policy in one policy set-->
+<!--- this case will have the result of deny because of default rules combining==deny override, which is not the same as policies combining -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s42.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r42.1</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r42.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 42.2 (old name: test 202b -->
+<!--- two opposite rules put into one policy in one policy set-->
+<!--- this case will have the result of deny because of default rules combining==deny override, which is not the same as policies combining -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s42.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r42.2</resource-match>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r42.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 43.1 (old name: test 203 -->
+
+<!--- two opposite rules put into different policies in one policy set-->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s43.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r43.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r43.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<!--- test 43.2 (old name: test 203b -->
+
+<!--- two opposite rules put into different policies in one policy set-->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s43.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r43.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r43.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 44.1 (old name: test 204 -->
+<!--- two different rules put into different policies in one policy set-->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s44.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r44.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r44.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 44.2 (old name: test 204b -->
+<!--- two different rules put into different policies in one policy set-->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s44.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r44.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r44.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 45.1 (old name: test 205 -->
+<!--- two opposite rules put into one policy -->
+<!--- testing rules combining methods-->
+<!--- this case should have the result of permit in contradiction to test 202 -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s45.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r45.1</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r45.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<!--- test 45.2 (old name: test 205b -->
+<!--- two opposite rules put into one policy -->
+<!--- testing rules combining methods-->
+<!--- this case should have the result of deny-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s45.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r45.2</resource-match>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r45.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 46.1 (old name: test 206 -->
+<!--- two opposite rules put into one policy -->
+
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s46.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="permit-overrides">
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r46.1</resource-match>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r46.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<!--- test 46.2 (old name: test 206b -->
+<!--- two opposite rules put into one policy -->
+
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s46.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="permit-overrides">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r46.2</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r46.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 47.1 (old name: test 207 -->
+<!--- two opposite rules put into one policy -->
+
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s47.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="deny-overrides">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r47.1</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r47.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<!--- test 47.2 (old name: test 207b -->
+<!--- two opposite rules put into one policy -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s47.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="deny-overrides">
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r47.2</resource-match>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r47.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 48 (old name: test 101)-->
+
+<policy-set combine="first-matching-target">
+<target>
+<subject>
+<subject-match attr="id">s48</subject-match>
+<subject-match attr="uri.host" match="www.test.pl"/>
+
+</subject>
+</target>
+<policy>
+<rule effect="permit">
+<condition combine="and">
+<resource-match attr="resource-id" match="device:pim.contacts"/>
+<!--<subject-match attr="uri" match="http://www.test.pl:80"/>-->
+</condition>
+</rule>
+</policy>
+</policy-set>
+
+</policy-set>
+
+</signed-policy>
--- /dev/null
+<?xml version="1.0" ?>
+<!DOCTYPE manager-settings SYSTEM "../config.dtd">
+<manager-settings>
+ <storage-path>/usr/etc/ace/CMTest/active</storage-path>
+ <policy-files>
+ <file active="true">pms_general-test.xml</file>
+ </policy-files>
+</manager-settings>
+
+
--- /dev/null
+<!DOCTYPE signed-policy SYSTEM "bondixml.dtd">
+
+<signed-policy>
+
+ <Signature Id="SignatureExample" xmlns="http://www.w3.org/2000/09/xmldsig#">
+ <SignedInfo>
+ <CanonicalizationMethod Algorithm="http://www.w2.org/2006/12/xml-c14n11"/>
+ <SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
+ <Reference URI="Policy-1">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-2">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-3">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-4">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-5">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-6">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-7">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-8">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-9">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-10">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-11">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-12">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-13">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-14">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-15">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-16">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-17">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ </SignedInfo>
+ <SignatureValue>asdfkjlhxvczxnbcvnjahfjhsdfklahfdas</SignatureValue>
+ <KeyInfo>
+ <KeyValue>
+ <DSAKeyValue>
+ <P> PValue </P><Q> QValue </Q><G> Gvalue </G><Y> laj?</Y>
+ </DSAKeyValue>
+ <RSAKeyValue>
+ <Modulus>
+ modulus
+ </Modulus>
+ <Exponent>
+ exponent
+ </Exponent>
+ </RSAKeyValue>
+ </KeyValue>
+ <X509Data>
+ <X509SubjectName> Subject name </X509SubjectName>
+ <X509SKI> SKI </X509SKI>
+ </X509Data>
+ </KeyInfo>
+ </Signature>
+
+
+
+<policy-set id="Policy-1">
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">
+ subject
+ </subject-match>
+ </subject>
+ <subject>
+ <subject-match attr="id" match="subject2" />
+ </subject>
+ </target>
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="id" match="subject" />
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource
+ </resource-match>
+ <subject-match attr="version" match="3" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="id" match="subject2" />
+ </subject>
+ </target>
+ <rule effect="deny">
+ <condition>
+ <resource-match attr="resource-id">
+ resource
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<policy-set >
+ <target>
+ <subject>
+ <subject-match attr="id">
+ subject3
+ </subject-match>
+ </subject>
+ <subject>
+ <subject-match attr="id" match="subject4" />
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource2
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition>
+ <resource-match attr="resource-id">
+ resource2
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="id">
+ subject4
+ </subject-match>
+ <subject-match attr="version" match="4" />
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<policy-set id="Policy-2" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id" match="subject5" />
+ </subject>
+ <subject>
+ <subject-match attr="id" match="subject6" />
+ </subject>
+ </target>
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="id">
+ subject5
+ </subject-match>
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource5
+ </resource-match>
+ <subject-match attr="version" match="5" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <resource-match attr="resource-id">
+ resource6
+ </resource-match>
+ <subject-match attr="version" match="6" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-3" combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id" match="subject7" />
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource7
+ </resource-match>
+ <condition combine="and">
+ <condition combine="or">
+ <subject-match attr="version" match="7" />
+ <subject-match attr="version" match="6" />
+ </condition>
+ <resource-match attr="author" match="author2" />
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource7
+ </resource-match>
+ <condition combine="or">
+ <condition combine="or">
+ <subject-match attr="version" match="1" />
+ <subject-match attr="version" match="2" />
+ </condition>
+ <resource-match attr="author" match="author3" />
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource7
+ </resource-match>
+ <condition combine="or">
+ <condition combine="or">
+ <subject-match attr="version" match="1" />
+ <subject-match attr="version" match="2" />
+ </condition>
+ <resource-match attr="author" match="author3" />
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+
+<policy-set id="Policy-4" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s8a</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r8</resource-match>
+ <resource-match attr="r8v1" match="1" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r8</resource-match>
+ <resource-match attr="r8v2" match="2" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-5" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s8b</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r8</resource-match>
+ <resource-match attr="r8v2" match="2" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r8</resource-match>
+ <resource-match attr="r8v1" match="1" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-6" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s8c</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r8</resource-match>
+ <resource-match attr="r8v1" match="1" />
+ <resource-match attr="r8v2" match="1" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny" />
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-7" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9a</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9a.scheme" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9a" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-8" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9b</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9b.authority" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9b" match="777" func="equal" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-9" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9c</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9c.scheme" match="http" />
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9c.authority" match="onet.pl" />
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9c.scheme-authority" match="http://onet.pl" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9c" match="*" func="glob" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-10" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9d</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9d.scheme" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9d.authority" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9d" match="*" func="glob" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9d.scheme-authority" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-11" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9e</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9e.host" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9e" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-12" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9f</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9e.host" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9e" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-13" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9g</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9g.path" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9g" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-14" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9h</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9g.path" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9g" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-15" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s10a</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10a" match="[1234567890]+[ab]+" func="regexp" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10a" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-16" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s10b</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10a" match="[1234567890]+[ab]+" func="regexp" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10a" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-17" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s10c</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10c" match="[1234567890]+[ab]+" func="regexp" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10c" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!-- justyna -->
+
+<!--- test 13 (old name: test 100)-->
+
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s13</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 14 (old name: test 101)-->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s14</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 15 (old name: test 102) -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="uri.host" match="//buu.com.pl"/>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 16 (old name: test 103) -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s16</subject-match>
+ <subject-match attr="uri.host" match="v.com.pl"/>
+
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 17 (old name: test 104)-->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">subject4</subject-match>
+ <subject-match attr="version" match="4" />
+ </subject>
+ </target>
+<policy>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">subject5</subject-match>
+ <subject-match attr="version" match="4" />
+ </subject>
+ </target>
+<policy>
+ <rule effect="deny">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 18 (old name: test 105)-->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="uri" match="buu.com.pl"/>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id" match="s18b"/>
+ <subject-match attr="uri" match="buu.s18b.pl"/>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id" match="s18c"/>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="uri" match="buu.s18c.pl"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 19 (old name: test 106)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s19.1</subject-match>
+ <subject-match attr="key-root-trust" match="voperator"/>
+ </subject>
+ </target>
+<policy>
+ <rule effect="deny">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s19.2</subject-match>
+ <subject-match attr="key-root-trust" match="voperator"/>
+ </subject>
+ </target>
+<policy>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 20 (old name: test 107)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s20.1</subject-match>
+ <subject-match attr="signer-id" match="v7zha89%49x£$"/>
+ </subject>
+ </target>
+<policy>
+ <rule effect="deny">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s20.2</subject-match>
+ <subject-match attr="signer-id" match="v7zha89%49x£$"/>
+ </subject>
+ </target>
+<policy>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!-- justyna -->
+
+
+<!--- test 21 (old name: test 103 U)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s21</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 23 (old name: test 105 U)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s23</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 24 (old name: test 106 U)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s24</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <subject-match attr="version" match="5"/>
+ <resource-match attr="resource-id" match="device:pim"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 25.1 (old name: test 107 U)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s25.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 25.2 (old name: test 107 a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s25.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 25.3 (old name: test 107 b U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s25.3</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 25.4 (old name: test 107 c U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s25.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 26.1 (old name: test 108 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s26.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 26.2 (old name: test 108 a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s26.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 26.3 (old name: test 108 b U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s26.3</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 26.4 (old name: test 108 c U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s26.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 27.1 (old name: test 109 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s27.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 27.2 (old name: test 109a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s27.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 27.3 (old name: test 109b U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s27.3</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 27.4 (old name: test 109c U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s27.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 28 (old name: test 110 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s28</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 29 (old name: test 111 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s29</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 30.1 (old name: test 112 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s30.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 30.2 (old name: test 112a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s30.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 30.3 (old name: test 112b U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s30.3</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 30.4 (old name: test 112c U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s30.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+</policy-set>
+
+
+
+<!--- test 31.1 (old name: test 113 U -->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s31.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 31.2.1 (old name: test 113a U -->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s31.2.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 31.2.2 (old name: test 113aa U -->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s31.2.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 31.3 (old name: test 113b U -->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s31.3</subject-match>
+ </subject>
+ </target>
+
+
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+</policy-set>
+
+<!--- test 32.1 (old name: test 114 U -->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s32.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 32.2.1 (old name: test 114a U -->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s32.2.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 32.2.2 (old name: test 114aa U -->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s32.2.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 32.3 (old name: test 114b U -->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s32.3</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 33.1 (old name: test 115 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s33.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 33.2 (old name: test 115a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s33.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 33.3 (old name: test 115b U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s33.3</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 34.1 (old name: test 116 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s34.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="permit-overrides">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 34.2 (old name: test 116 a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s34.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="permit-overrides">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 35.1 (old name: test 117 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s35.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="deny-overrides">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 35.2 (old name: test 117 a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s35.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="deny-overrides">
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set>
+ <target>
+ <subject>
+ <subject-match attr="id">org.tizen.widget.analogclock</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="http://helloheloo/"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 36 (old name: test 102 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s36</subject-match>
+ <subject-match attr="version" match="5"/>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+
+<!--- test 37 (old name: test 108 -->
+<!-- mbialota modified -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s37</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="prompt-oneshot">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 38 (old name: test 109 -->
+<!-- mbialota modified -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s38</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="prompt-session">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s38.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="prompt-session">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 39 (old name: test 110 -->
+<!-- mbialota modified -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s39</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="prompt-blanket">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s39.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="prompt-blanket">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!-- Maria -->
+<!-- testing different methods of policies and rules combining-->
+<!--- test 40 (old name: test 200 -->
+
+<!--- two opposite rules put into different policies in one policy set -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s40</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r40</resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r40</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 41 (old name: test 201 -->
+
+<!--- two different rules put into different policies in one policy set-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s41</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r41</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r41.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 42.1 (old name: test 202 -->
+<!--- two opposite rules put into one policy in one policy set-->
+<!--- this case will have the result of deny because of default rules combining==deny override, which is not the same as policies combining -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s42.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r42.1</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r42.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 42.2 (old name: test 202b -->
+<!--- two opposite rules put into one policy in one policy set-->
+<!--- this case will have the result of deny because of default rules combining==deny override, which is not the same as policies combining -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s42.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r42.2</resource-match>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r42.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 43.1 (old name: test 203 -->
+
+<!--- two opposite rules put into different policies in one policy set-->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s43.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r43.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r43.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<!--- test 43.2 (old name: test 203b -->
+
+<!--- two opposite rules put into different policies in one policy set-->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s43.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r43.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r43.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 44.1 (old name: test 204 -->
+<!--- two different rules put into different policies in one policy set-->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s44.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r44.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r44.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 44.2 (old name: test 204b -->
+<!--- two different rules put into different policies in one policy set-->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s44.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r44.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r44.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 45.1 (old name: test 205 -->
+<!--- two opposite rules put into one policy -->
+<!--- testing rules combining methods-->
+<!--- this case should have the result of permit in contradiction to test 202 -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s45.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r45.1</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r45.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<!--- test 45.2 (old name: test 205b -->
+<!--- two opposite rules put into one policy -->
+<!--- testing rules combining methods-->
+<!--- this case should have the result of deny-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s45.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r45.2</resource-match>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r45.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 46.1 (old name: test 206 -->
+<!--- two opposite rules put into one policy -->
+
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s46.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="permit-overrides">
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r46.1</resource-match>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r46.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<!--- test 46.2 (old name: test 206b -->
+<!--- two opposite rules put into one policy -->
+
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s46.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="permit-overrides">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r46.2</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r46.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 47.1 (old name: test 207 -->
+<!--- two opposite rules put into one policy -->
+
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s47.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="deny-overrides">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r47.1</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r47.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<!--- test 47.2 (old name: test 207b -->
+<!--- two opposite rules put into one policy -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s47.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="deny-overrides">
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r47.2</resource-match>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r47.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 48 (old name: test 101)-->
+
+<policy-set combine="first-matching-target">
+<target>
+<subject>
+<subject-match attr="id">s48</subject-match>
+<subject-match attr="uri.host" match="www.test.pl"/>
+
+</subject>
+</target>
+<policy>
+<rule effect="permit">
+<condition combine="and">
+<resource-match attr="resource-id" match="device:pim.contacts"/>
+<!--<subject-match attr="uri" match="http://www.test.pl:80"/>-->
+</condition>
+</rule>
+</policy>
+</policy-set>
+
+</policy-set>
+
+</signed-policy>
--- /dev/null
+<!DOCTYPE signed-policy SYSTEM "bondixml.dtd">
+
+<signed-policy>
+
+ <Signature Id="SignatureExample" xmlns="http://www.w3.org/2000/09/xmldsig#">
+ <SignedInfo>
+ <CanonicalizationMethod Algorithm="http://www.w2.org/2006/12/xml-c14n11"/>
+ <SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
+ <Reference URI="Policy-1">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-2">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-3">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-4">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-5">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-6">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-7">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-8">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-9">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-10">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-11">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-12">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-13">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-14">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-15">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-16">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-17">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ </SignedInfo>
+ <SignatureValue>asdfkjlhxvczxnbcvnjahfjhsdfklahfdas</SignatureValue>
+ <KeyInfo>
+ <KeyValue>
+ <DSAKeyValue>
+ <P> PValue </P><Q> QValue </Q><G> Gvalue </G><Y> laj?</Y>
+ </DSAKeyValue>
+ <RSAKeyValue>
+ <Modulus>
+ modulus
+ </Modulus>
+ <Exponent>
+ exponent
+ </Exponent>
+ </RSAKeyValue>
+ </KeyValue>
+ <X509Data>
+ <X509SubjectName> Subject name </X509SubjectName>
+ <X509SKI> SKI </X509SKI>
+ </X509Data>
+ </KeyInfo>
+ </Signature>
+
+
+
+<policy-set id="Policy-1">
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">
+ subject
+ </subject-match>
+ </subject>
+ <subject>
+ <subject-match attr="id" match="subject2" />
+ </subject>
+ </target>
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="id" match="subject" />
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource
+ </resource-match>
+ <subject-match attr="version" match="3" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="id" match="subject2" />
+ </subject>
+ </target>
+ <rule effect="deny">
+ <condition>
+ <resource-match attr="resource-id">
+ resource
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<policy-set >
+ <target>
+ <subject>
+ <subject-match attr="id">
+ subject3
+ </subject-match>
+ </subject>
+ <subject>
+ <subject-match attr="id" match="subject4" />
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource2
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition>
+ <resource-match attr="resource-id">
+ resource2
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="id">
+ subject4
+ </subject-match>
+ <subject-match attr="version" match="4" />
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<policy-set id="Policy-2" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id" match="subject5" />
+ </subject>
+ <subject>
+ <subject-match attr="id" match="subject6" />
+ </subject>
+ </target>
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="id">
+ subject5
+ </subject-match>
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource5
+ </resource-match>
+ <subject-match attr="version" match="5" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <resource-match attr="resource-id">
+ resource6
+ </resource-match>
+ <subject-match attr="version" match="6" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-3" combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id" match="subject7" />
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource7
+ </resource-match>
+ <condition combine="and">
+ <condition combine="or">
+ <subject-match attr="version" match="7" />
+ <subject-match attr="version" match="6" />
+ </condition>
+ <resource-match attr="author" match="author2" />
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource7
+ </resource-match>
+ <condition combine="or">
+ <condition combine="or">
+ <subject-match attr="version" match="1" />
+ <subject-match attr="version" match="2" />
+ </condition>
+ <resource-match attr="author" match="author3" />
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource7
+ </resource-match>
+ <condition combine="or">
+ <condition combine="or">
+ <subject-match attr="version" match="1" />
+ <subject-match attr="version" match="2" />
+ </condition>
+ <resource-match attr="author" match="author3" />
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+
+<policy-set id="Policy-4" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s8a</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r8</resource-match>
+ <resource-match attr="r8v1" match="1" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r8</resource-match>
+ <resource-match attr="r8v2" match="2" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-5" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s8b</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r8</resource-match>
+ <resource-match attr="r8v2" match="2" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r8</resource-match>
+ <resource-match attr="r8v1" match="1" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-6" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s8c</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r8</resource-match>
+ <resource-match attr="r8v1" match="1" />
+ <resource-match attr="r8v2" match="1" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny" />
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-7" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9a</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9a.scheme" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9a" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-8" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9b</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9b.authority" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9b" match="777" func="equal" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-9" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9c</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9c.scheme" match="http" />
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9c.authority" match="onet.pl" />
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9c.scheme-authority" match="http://onet.pl" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9c" match="*" func="glob" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-10" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9d</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9d.scheme" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9d.authority" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9d" match="*" func="glob" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9d.scheme-authority" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-11" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9e</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9e.host" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9e" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-12" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9f</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9e.host" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9e" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-13" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9g</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9g.path" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9g" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-14" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9h</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9g.path" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9g" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-15" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s10a</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10a" match="[1234567890]+[ab]+" func="regexp" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10a" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-16" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s10b</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10a" match="[1234567890]+[ab]+" func="regexp" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10a" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-17" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s10c</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10c" match="[1234567890]+[ab]+" func="regexp" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10c" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!-- justyna -->
+
+<!--- test 13 (old name: test 100)-->
+
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s13</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 14 (old name: test 101)-->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s14</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 15 (old name: test 102) -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="uri.host" match="//buu.com.pl"/>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 16 (old name: test 103) -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s16</subject-match>
+ <subject-match attr="uri.host" match="v.com.pl"/>
+
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 17 (old name: test 104)-->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">subject4</subject-match>
+ <subject-match attr="version" match="4" />
+ </subject>
+ </target>
+<policy>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">subject5</subject-match>
+ <subject-match attr="version" match="4" />
+ </subject>
+ </target>
+<policy>
+ <rule effect="deny">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 18 (old name: test 105)-->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="uri" match="buu.com.pl"/>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id" match="s18b"/>
+ <subject-match attr="uri" match="buu.s18b.pl"/>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id" match="s18c"/>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="uri" match="buu.s18c.pl"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 19 (old name: test 106)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s19.1</subject-match>
+ <subject-match attr="key-root-trust" match="voperator"/>
+ </subject>
+ </target>
+<policy>
+ <rule effect="deny">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s19.2</subject-match>
+ <subject-match attr="key-root-trust" match="voperator"/>
+ </subject>
+ </target>
+<policy>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 20 (old name: test 107)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s20.1</subject-match>
+ <subject-match attr="signer-id" match="v7zha89%49x£$"/>
+ </subject>
+ </target>
+<policy>
+ <rule effect="deny">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s20.2</subject-match>
+ <subject-match attr="signer-id" match="v7zha89%49x£$"/>
+ </subject>
+ </target>
+<policy>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!-- justyna -->
+
+
+<!--- test 21 (old name: test 103 U)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s21</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 23 (old name: test 105 U)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s23</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 24 (old name: test 106 U)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s24</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <subject-match attr="version" match="5"/>
+ <resource-match attr="resource-id" match="device:pim"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 25.1 (old name: test 107 U)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s25.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 25.2 (old name: test 107 a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s25.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 25.3 (old name: test 107 b U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s25.3</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 25.4 (old name: test 107 c U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s25.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 26.1 (old name: test 108 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s26.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 26.2 (old name: test 108 a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s26.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 26.3 (old name: test 108 b U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s26.3</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 26.4 (old name: test 108 c U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s26.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 27.1 (old name: test 109 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s27.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 27.2 (old name: test 109a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s27.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 27.3 (old name: test 109b U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s27.3</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 27.4 (old name: test 109c U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s27.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 28 (old name: test 110 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s28</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 29 (old name: test 111 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s29</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 30.1 (old name: test 112 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s30.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 30.2 (old name: test 112a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s30.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 30.3 (old name: test 112b U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s30.3</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 30.4 (old name: test 112c U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s30.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+</policy-set>
+
+
+
+<!--- test 31.1 (old name: test 113 U -->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s31.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 31.2.1 (old name: test 113a U -->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s31.2.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 31.2.2 (old name: test 113aa U -->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s31.2.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 31.3 (old name: test 113b U -->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s31.3</subject-match>
+ </subject>
+ </target>
+
+
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+</policy-set>
+
+<!--- test 32.1 (old name: test 114 U -->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s32.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 32.2.1 (old name: test 114a U -->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s32.2.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 32.2.2 (old name: test 114aa U -->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s32.2.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 32.3 (old name: test 114b U -->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s32.3</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 33.1 (old name: test 115 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s33.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 33.2 (old name: test 115a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s33.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 33.3 (old name: test 115b U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s33.3</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 34.1 (old name: test 116 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s34.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="permit-overrides">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 34.2 (old name: test 116 a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s34.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="permit-overrides">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 35.1 (old name: test 117 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s35.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="deny-overrides">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 35.2 (old name: test 117 a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s35.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="deny-overrides">
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set>
+ <target>
+ <subject>
+ <subject-match attr="id">org.tizen.widget.analogclock</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="http://helloheloo/"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 36 (old name: test 102 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s36</subject-match>
+ <subject-match attr="version" match="5"/>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+
+<!--- test 37 (old name: test 108 -->
+<!-- mbialota modified -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s37</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="prompt-oneshot">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 38 (old name: test 109 -->
+<!-- mbialota modified -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s38</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="prompt-session">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s38.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="prompt-session">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 39 (old name: test 110 -->
+<!-- mbialota modified -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s39</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="prompt-blanket">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s39.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="prompt-blanket">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!-- Maria -->
+<!-- testing different methods of policies and rules combining-->
+<!--- test 40 (old name: test 200 -->
+
+<!--- two opposite rules put into different policies in one policy set -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s40</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r40</resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r40</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 41 (old name: test 201 -->
+
+<!--- two different rules put into different policies in one policy set-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s41</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r41</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r41.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 42.1 (old name: test 202 -->
+<!--- two opposite rules put into one policy in one policy set-->
+<!--- this case will have the result of deny because of default rules combining==deny override, which is not the same as policies combining -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s42.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r42.1</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r42.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 42.2 (old name: test 202b -->
+<!--- two opposite rules put into one policy in one policy set-->
+<!--- this case will have the result of deny because of default rules combining==deny override, which is not the same as policies combining -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s42.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r42.2</resource-match>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r42.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 43.1 (old name: test 203 -->
+
+<!--- two opposite rules put into different policies in one policy set-->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s43.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r43.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r43.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<!--- test 43.2 (old name: test 203b -->
+
+<!--- two opposite rules put into different policies in one policy set-->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s43.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r43.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r43.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 44.1 (old name: test 204 -->
+<!--- two different rules put into different policies in one policy set-->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s44.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r44.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r44.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 44.2 (old name: test 204b -->
+<!--- two different rules put into different policies in one policy set-->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s44.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r44.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r44.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 45.1 (old name: test 205 -->
+<!--- two opposite rules put into one policy -->
+<!--- testing rules combining methods-->
+<!--- this case should have the result of permit in contradiction to test 202 -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s45.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r45.1</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r45.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<!--- test 45.2 (old name: test 205b -->
+<!--- two opposite rules put into one policy -->
+<!--- testing rules combining methods-->
+<!--- this case should have the result of deny-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s45.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r45.2</resource-match>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r45.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 46.1 (old name: test 206 -->
+<!--- two opposite rules put into one policy -->
+
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s46.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="permit-overrides">
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r46.1</resource-match>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r46.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<!--- test 46.2 (old name: test 206b -->
+<!--- two opposite rules put into one policy -->
+
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s46.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="permit-overrides">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r46.2</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r46.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 47.1 (old name: test 207 -->
+<!--- two opposite rules put into one policy -->
+
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s47.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="deny-overrides">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r47.1</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r47.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<!--- test 47.2 (old name: test 207b -->
+<!--- two opposite rules put into one policy -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s47.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="deny-overrides">
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r47.2</resource-match>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r47.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 48 (old name: test 101)-->
+
+<policy-set combine="first-matching-target">
+<target>
+<subject>
+<subject-match attr="id">s48</subject-match>
+<subject-match attr="uri.host" match="www.test.pl"/>
+
+</subject>
+</target>
+<policy>
+<rule effect="permit">
+<condition combine="and">
+<resource-match attr="resource-id" match="device:pim.contacts"/>
+<!--<subject-match attr="uri" match="http://www.test.pl:80"/>-->
+</condition>
+</rule>
+</policy>
+</policy-set>
+
+</policy-set>
+
+</signed-policy>
--- /dev/null
+<!DOCTYPE signed-policy SYSTEM "bondixml.dtd">
+
+<signed-policy>
+
+ <Signature Id="SignatureExample" xmlns="http://www.w3.org/2000/09/xmldsig#">
+ <SignedInfo>
+ <CanonicalizationMethod Algorithm="http://www.w2.org/2006/12/xml-c14n11"/>
+ <SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
+ <Reference URI="Policy-1">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-2">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-3">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-4">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-5">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-6">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-7">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-8">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-9">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-10">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-11">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-12">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-13">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-14">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-15">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-16">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-17">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ </SignedInfo>
+ <SignatureValue>asdfkjlhxvczxnbcvnjahfjhsdfklahfdas</SignatureValue>
+ <KeyInfo>
+ <KeyValue>
+ <DSAKeyValue>
+ <P> PValue </P><Q> QValue </Q><G> Gvalue </G><Y> laj?</Y>
+ </DSAKeyValue>
+ <RSAKeyValue>
+ <Modulus>
+ modulus
+ </Modulus>
+ <Exponent>
+ exponent
+ </Exponent>
+ </RSAKeyValue>
+ </KeyValue>
+ <X509Data>
+ <X509SubjectName> Subject name </X509SubjectName>
+ <X509SKI> SKI </X509SKI>
+ </X509Data>
+ </KeyInfo>
+ </Signature>
+
+
+
+<policy-set id="Policy-1">
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">
+ subject
+ </subject-match>
+ </subject>
+ <subject>
+ <subject-match attr="id" match="subject2" />
+ </subject>
+ </target>
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="id" match="subject" />
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource
+ </resource-match>
+ <subject-match attr="version" match="3" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="id" match="subject2" />
+ </subject>
+ </target>
+ <rule effect="deny">
+ <condition>
+ <resource-match attr="resource-id">
+ resource
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<policy-set >
+ <target>
+ <subject>
+ <subject-match attr="id">
+ subject3
+ </subject-match>
+ </subject>
+ <subject>
+ <subject-match attr="id" match="subject4" />
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource2
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition>
+ <resource-match attr="resource-id">
+ resource2
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="id">
+ subject4
+ </subject-match>
+ <subject-match attr="version" match="4" />
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<policy-set id="Policy-2" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id" match="subject5" />
+ </subject>
+ <subject>
+ <subject-match attr="id" match="subject6" />
+ </subject>
+ </target>
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="id">
+ subject5
+ </subject-match>
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource5
+ </resource-match>
+ <subject-match attr="version" match="5" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <resource-match attr="resource-id">
+ resource6
+ </resource-match>
+ <subject-match attr="version" match="6" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-3" combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id" match="subject7" />
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource7
+ </resource-match>
+ <condition combine="and">
+ <condition combine="or">
+ <subject-match attr="version" match="7" />
+ <subject-match attr="version" match="6" />
+ </condition>
+ <resource-match attr="author" match="author2" />
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource7
+ </resource-match>
+ <condition combine="or">
+ <condition combine="or">
+ <subject-match attr="version" match="1" />
+ <subject-match attr="version" match="2" />
+ </condition>
+ <resource-match attr="author" match="author3" />
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource7
+ </resource-match>
+ <condition combine="or">
+ <condition combine="or">
+ <subject-match attr="version" match="1" />
+ <subject-match attr="version" match="2" />
+ </condition>
+ <resource-match attr="author" match="author3" />
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+
+<policy-set id="Policy-4" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s8a</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r8</resource-match>
+ <resource-match attr="r8v1" match="1" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r8</resource-match>
+ <resource-match attr="r8v2" match="2" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-5" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s8b</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r8</resource-match>
+ <resource-match attr="r8v2" match="2" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r8</resource-match>
+ <resource-match attr="r8v1" match="1" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-6" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s8c</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r8</resource-match>
+ <resource-match attr="r8v1" match="1" />
+ <resource-match attr="r8v2" match="1" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny" />
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-7" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9a</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9a.scheme" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9a" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-8" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9b</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9b.authority" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9b" match="777" func="equal" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-9" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9c</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9c.scheme" match="http" />
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9c.authority" match="onet.pl" />
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9c.scheme-authority" match="http://onet.pl" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9c" match="*" func="glob" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-10" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9d</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9d.scheme" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9d.authority" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9d" match="*" func="glob" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9d.scheme-authority" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-11" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9e</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9e.host" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9e" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-12" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9f</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9e.host" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9e" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-13" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9g</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9g.path" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9g" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-14" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9h</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9g.path" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9g" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-15" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s10a</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10a" match="[1234567890]+[ab]+" func="regexp" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10a" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-16" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s10b</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10a" match="[1234567890]+[ab]+" func="regexp" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10a" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-17" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s10c</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10c" match="[1234567890]+[ab]+" func="regexp" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10c" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!-- justyna -->
+
+<!--- test 13 (old name: test 100)-->
+
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s13</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 14 (old name: test 101)-->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s14</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 15 (old name: test 102) -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="uri.host" match="//buu.com.pl"/>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 16 (old name: test 103) -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s16</subject-match>
+ <subject-match attr="uri.host" match="v.com.pl"/>
+
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 17 (old name: test 104)-->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">subject4</subject-match>
+ <subject-match attr="version" match="4" />
+ </subject>
+ </target>
+<policy>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">subject5</subject-match>
+ <subject-match attr="version" match="4" />
+ </subject>
+ </target>
+<policy>
+ <rule effect="deny">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 18 (old name: test 105)-->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="uri" match="buu.com.pl"/>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id" match="s18b"/>
+ <subject-match attr="uri" match="buu.s18b.pl"/>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id" match="s18c"/>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="uri" match="buu.s18c.pl"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 19 (old name: test 106)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s19.1</subject-match>
+ <subject-match attr="key-root-trust" match="voperator"/>
+ </subject>
+ </target>
+<policy>
+ <rule effect="deny">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s19.2</subject-match>
+ <subject-match attr="key-root-trust" match="voperator"/>
+ </subject>
+ </target>
+<policy>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 20 (old name: test 107)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s20.1</subject-match>
+ <subject-match attr="signer-id" match="v7zha89%49x£$"/>
+ </subject>
+ </target>
+<policy>
+ <rule effect="deny">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s20.2</subject-match>
+ <subject-match attr="signer-id" match="v7zha89%49x£$"/>
+ </subject>
+ </target>
+<policy>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!-- justyna -->
+
+
+<!--- test 21 (old name: test 103 U)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s21</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 23 (old name: test 105 U)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s23</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 24 (old name: test 106 U)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s24</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <subject-match attr="version" match="5"/>
+ <resource-match attr="resource-id" match="device:pim"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 25.1 (old name: test 107 U)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s25.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 25.2 (old name: test 107 a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s25.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 25.3 (old name: test 107 b U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s25.3</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 25.4 (old name: test 107 c U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s25.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 26.1 (old name: test 108 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s26.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 26.2 (old name: test 108 a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s26.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 26.3 (old name: test 108 b U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s26.3</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 26.4 (old name: test 108 c U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s26.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 27.1 (old name: test 109 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s27.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 27.2 (old name: test 109a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s27.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 27.3 (old name: test 109b U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s27.3</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 27.4 (old name: test 109c U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s27.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 28 (old name: test 110 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s28</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 29 (old name: test 111 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s29</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 30.1 (old name: test 112 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s30.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 30.2 (old name: test 112a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s30.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 30.3 (old name: test 112b U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s30.3</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 30.4 (old name: test 112c U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s30.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+</policy-set>
+
+
+
+<!--- test 31.1 (old name: test 113 U -->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s31.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 31.2.1 (old name: test 113a U -->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s31.2.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 31.2.2 (old name: test 113aa U -->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s31.2.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 31.3 (old name: test 113b U -->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s31.3</subject-match>
+ </subject>
+ </target>
+
+
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+</policy-set>
+
+<!--- test 32.1 (old name: test 114 U -->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s32.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 32.2.1 (old name: test 114a U -->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s32.2.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 32.2.2 (old name: test 114aa U -->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s32.2.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 32.3 (old name: test 114b U -->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s32.3</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 33.1 (old name: test 115 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s33.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 33.2 (old name: test 115a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s33.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 33.3 (old name: test 115b U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s33.3</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 34.1 (old name: test 116 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s34.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="permit-overrides">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 34.2 (old name: test 116 a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s34.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="permit-overrides">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 35.1 (old name: test 117 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s35.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="deny-overrides">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 35.2 (old name: test 117 a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s35.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="deny-overrides">
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set>
+ <target>
+ <subject>
+ <subject-match attr="id">org.tizen.widget.analogclock</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="http://helloheloo/"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 36 (old name: test 102 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s36</subject-match>
+ <subject-match attr="version" match="5"/>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+
+<!--- test 37 (old name: test 108 -->
+<!-- mbialota modified -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s37</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="prompt-oneshot">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 38 (old name: test 109 -->
+<!-- mbialota modified -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s38</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="prompt-session">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s38.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="prompt-session">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 39 (old name: test 110 -->
+<!-- mbialota modified -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s39</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="prompt-blanket">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s39.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="prompt-blanket">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!-- Maria -->
+<!-- testing different methods of policies and rules combining-->
+<!--- test 40 (old name: test 200 -->
+
+<!--- two opposite rules put into different policies in one policy set -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s40</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r40</resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r40</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 41 (old name: test 201 -->
+
+<!--- two different rules put into different policies in one policy set-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s41</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r41</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r41.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 42.1 (old name: test 202 -->
+<!--- two opposite rules put into one policy in one policy set-->
+<!--- this case will have the result of deny because of default rules combining==deny override, which is not the same as policies combining -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s42.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r42.1</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r42.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 42.2 (old name: test 202b -->
+<!--- two opposite rules put into one policy in one policy set-->
+<!--- this case will have the result of deny because of default rules combining==deny override, which is not the same as policies combining -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s42.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r42.2</resource-match>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r42.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 43.1 (old name: test 203 -->
+
+<!--- two opposite rules put into different policies in one policy set-->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s43.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r43.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r43.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<!--- test 43.2 (old name: test 203b -->
+
+<!--- two opposite rules put into different policies in one policy set-->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s43.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r43.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r43.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 44.1 (old name: test 204 -->
+<!--- two different rules put into different policies in one policy set-->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s44.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r44.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r44.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 44.2 (old name: test 204b -->
+<!--- two different rules put into different policies in one policy set-->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s44.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r44.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r44.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 45.1 (old name: test 205 -->
+<!--- two opposite rules put into one policy -->
+<!--- testing rules combining methods-->
+<!--- this case should have the result of permit in contradiction to test 202 -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s45.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r45.1</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r45.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<!--- test 45.2 (old name: test 205b -->
+<!--- two opposite rules put into one policy -->
+<!--- testing rules combining methods-->
+<!--- this case should have the result of deny-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s45.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r45.2</resource-match>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r45.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 46.1 (old name: test 206 -->
+<!--- two opposite rules put into one policy -->
+
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s46.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="permit-overrides">
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r46.1</resource-match>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r46.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<!--- test 46.2 (old name: test 206b -->
+<!--- two opposite rules put into one policy -->
+
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s46.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="permit-overrides">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r46.2</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r46.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 47.1 (old name: test 207 -->
+<!--- two opposite rules put into one policy -->
+
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s47.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="deny-overrides">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r47.1</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r47.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<!--- test 47.2 (old name: test 207b -->
+<!--- two opposite rules put into one policy -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s47.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="deny-overrides">
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r47.2</resource-match>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r47.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 48 (old name: test 101)-->
+
+<policy-set combine="first-matching-target">
+<target>
+<subject>
+<subject-match attr="id">s48</subject-match>
+<subject-match attr="uri.host" match="www.test.pl"/>
+
+</subject>
+</target>
+<policy>
+<rule effect="permit">
+<condition combine="and">
+<resource-match attr="resource-id" match="device:pim.contacts"/>
+<!--<subject-match attr="uri" match="http://www.test.pl:80"/>-->
+</condition>
+</rule>
+</policy>
+</policy-set>
+
+</policy-set>
+
+</signed-policy>
--- /dev/null
+<!DOCTYPE signed-policy SYSTEM "bondixml.dtd">
+
+<signed-policy>
+
+ <Signature Id="SignatureExample" xmlns="http://www.w3.org/2000/09/xmldsig#">
+ <SignedInfo>
+ <CanonicalizationMethod Algorithm="http://www.w2.org/2006/12/xml-c14n11"/>
+ <SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
+ <Reference URI="Policy-1">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-2">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-3">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-4">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-5">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-6">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-7">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-8">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-9">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-10">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-11">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-12">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-13">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-14">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-15">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-16">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ <Reference URI="Policy-17">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...</DigestValue>
+ </Reference>
+ </SignedInfo>
+ <SignatureValue>asdfkjlhxvczxnbcvnjahfjhsdfklahfdas</SignatureValue>
+ <KeyInfo>
+ <KeyValue>
+ <DSAKeyValue>
+ <P> PValue </P><Q> QValue </Q><G> Gvalue </G><Y> laj?</Y>
+ </DSAKeyValue>
+ <RSAKeyValue>
+ <Modulus>
+ modulus
+ </Modulus>
+ <Exponent>
+ exponent
+ </Exponent>
+ </RSAKeyValue>
+ </KeyValue>
+ <X509Data>
+ <X509SubjectName> Subject name </X509SubjectName>
+ <X509SKI> SKI </X509SKI>
+ </X509Data>
+ </KeyInfo>
+ </Signature>
+
+
+
+<policy-set id="Policy-1">
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">
+ subject
+ </subject-match>
+ </subject>
+ <subject>
+ <subject-match attr="id" match="subject2" />
+ </subject>
+ </target>
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="id" match="subject" />
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource
+ </resource-match>
+ <subject-match attr="version" match="3" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="id" match="subject2" />
+ </subject>
+ </target>
+ <rule effect="deny">
+ <condition>
+ <resource-match attr="resource-id">
+ resource
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<policy-set >
+ <target>
+ <subject>
+ <subject-match attr="id">
+ subject3
+ </subject-match>
+ </subject>
+ <subject>
+ <subject-match attr="id" match="subject4" />
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource2
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition>
+ <resource-match attr="resource-id">
+ resource2
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="id">
+ subject4
+ </subject-match>
+ <subject-match attr="version" match="4" />
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<policy-set id="Policy-2" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id" match="subject5" />
+ </subject>
+ <subject>
+ <subject-match attr="id" match="subject6" />
+ </subject>
+ </target>
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="id">
+ subject5
+ </subject-match>
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource5
+ </resource-match>
+ <subject-match attr="version" match="5" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <resource-match attr="resource-id">
+ resource6
+ </resource-match>
+ <subject-match attr="version" match="6" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-3" combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id" match="subject7" />
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource7
+ </resource-match>
+ <condition combine="and">
+ <condition combine="or">
+ <subject-match attr="version" match="7" />
+ <subject-match attr="version" match="6" />
+ </condition>
+ <resource-match attr="author" match="author2" />
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource7
+ </resource-match>
+ <condition combine="or">
+ <condition combine="or">
+ <subject-match attr="version" match="1" />
+ <subject-match attr="version" match="2" />
+ </condition>
+ <resource-match attr="author" match="author3" />
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource7
+ </resource-match>
+ <condition combine="or">
+ <condition combine="or">
+ <subject-match attr="version" match="1" />
+ <subject-match attr="version" match="2" />
+ </condition>
+ <resource-match attr="author" match="author3" />
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+
+<policy-set id="Policy-4" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s8a</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r8</resource-match>
+ <resource-match attr="r8v1" match="1" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r8</resource-match>
+ <resource-match attr="r8v2" match="2" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-5" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s8b</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r8</resource-match>
+ <resource-match attr="r8v2" match="2" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r8</resource-match>
+ <resource-match attr="r8v1" match="1" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-6" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s8c</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r8</resource-match>
+ <resource-match attr="r8v1" match="1" />
+ <resource-match attr="r8v2" match="1" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny" />
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-7" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9a</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9a.scheme" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9a" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-8" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9b</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9b.authority" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9b" match="777" func="equal" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-9" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9c</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9c.scheme" match="http" />
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9c.authority" match="onet.pl" />
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9c.scheme-authority" match="http://onet.pl" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9c" match="*" func="glob" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-10" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9d</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9d.scheme" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9d.authority" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9d" match="*" func="glob" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9d.scheme-authority" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-11" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9e</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9e.host" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9e" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-12" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9f</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9e.host" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9e" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-13" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9g</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9g.path" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9g" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-14" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9h</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9g.path" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9g" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-15" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s10a</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10a" match="[1234567890]+[ab]+" func="regexp" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10a" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-16" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s10b</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10a" match="[1234567890]+[ab]+" func="regexp" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10a" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-17" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s10c</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10c" match="[1234567890]+[ab]+" func="regexp" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10c" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!-- justyna -->
+
+<!--- test 13 (old name: test 100)-->
+
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s13</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 14 (old name: test 101)-->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s14</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 15 (old name: test 102) -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="uri.host" match="//buu.com.pl"/>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 16 (old name: test 103) -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s16</subject-match>
+ <subject-match attr="uri.host" match="v.com.pl"/>
+
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 17 (old name: test 104)-->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">subject4</subject-match>
+ <subject-match attr="version" match="4" />
+ </subject>
+ </target>
+<policy>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">subject5</subject-match>
+ <subject-match attr="version" match="4" />
+ </subject>
+ </target>
+<policy>
+ <rule effect="deny">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 18 (old name: test 105)-->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="uri" match="buu.com.pl"/>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id" match="s18b"/>
+ <subject-match attr="uri" match="buu.s18b.pl"/>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id" match="s18c"/>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="uri" match="buu.s18c.pl"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 19 (old name: test 106)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s19.1</subject-match>
+ <subject-match attr="key-root-trust" match="voperator"/>
+ </subject>
+ </target>
+<policy>
+ <rule effect="deny">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s19.2</subject-match>
+ <subject-match attr="key-root-trust" match="voperator"/>
+ </subject>
+ </target>
+<policy>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 20 (old name: test 107)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s20.1</subject-match>
+ <subject-match attr="signer-id" match="v7zha89%49x£$"/>
+ </subject>
+ </target>
+<policy>
+ <rule effect="deny">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s20.2</subject-match>
+ <subject-match attr="signer-id" match="v7zha89%49x£$"/>
+ </subject>
+ </target>
+<policy>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!-- justyna -->
+
+
+<!--- test 21 (old name: test 103 U)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s21</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 23 (old name: test 105 U)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s23</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 24 (old name: test 106 U)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s24</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <subject-match attr="version" match="5"/>
+ <resource-match attr="resource-id" match="device:pim"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 25.1 (old name: test 107 U)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s25.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 25.2 (old name: test 107 a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s25.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 25.3 (old name: test 107 b U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s25.3</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 25.4 (old name: test 107 c U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s25.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 26.1 (old name: test 108 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s26.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 26.2 (old name: test 108 a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s26.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 26.3 (old name: test 108 b U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s26.3</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 26.4 (old name: test 108 c U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s26.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 27.1 (old name: test 109 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s27.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 27.2 (old name: test 109a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s27.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 27.3 (old name: test 109b U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s27.3</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 27.4 (old name: test 109c U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s27.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 28 (old name: test 110 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s28</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 29 (old name: test 111 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s29</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 30.1 (old name: test 112 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s30.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 30.2 (old name: test 112a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s30.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 30.3 (old name: test 112b U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s30.3</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 30.4 (old name: test 112c U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s30.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+</policy-set>
+
+
+
+<!--- test 31.1 (old name: test 113 U -->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s31.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 31.2.1 (old name: test 113a U -->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s31.2.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 31.2.2 (old name: test 113aa U -->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s31.2.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 31.3 (old name: test 113b U -->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s31.3</subject-match>
+ </subject>
+ </target>
+
+
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+</policy-set>
+
+<!--- test 32.1 (old name: test 114 U -->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s32.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 32.2.1 (old name: test 114a U -->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s32.2.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 32.2.2 (old name: test 114aa U -->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s32.2.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 32.3 (old name: test 114b U -->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s32.3</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 33.1 (old name: test 115 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s33.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 33.2 (old name: test 115a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s33.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 33.3 (old name: test 115b U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s33.3</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 34.1 (old name: test 116 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s34.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="permit-overrides">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 34.2 (old name: test 116 a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s34.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="permit-overrides">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 35.1 (old name: test 117 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s35.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="deny-overrides">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 35.2 (old name: test 117 a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s35.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="deny-overrides">
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set>
+ <target>
+ <subject>
+ <subject-match attr="id">org.tizen.widget.analogclock</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="http://helloheloo/"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 36 (old name: test 102 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s36</subject-match>
+ <subject-match attr="version" match="5"/>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+
+<!--- test 37 (old name: test 108 -->
+<!-- mbialota modified -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s37</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="prompt-oneshot">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 38 (old name: test 109 -->
+<!-- mbialota modified -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s38</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="prompt-session">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s38.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="prompt-session">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 39 (old name: test 110 -->
+<!-- mbialota modified -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s39</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="prompt-blanket">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s39.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="prompt-blanket">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!-- Maria -->
+<!-- testing different methods of policies and rules combining-->
+<!--- test 40 (old name: test 200 -->
+
+<!--- two opposite rules put into different policies in one policy set -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s40</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r40</resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r40</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 41 (old name: test 201 -->
+
+<!--- two different rules put into different policies in one policy set-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s41</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r41</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r41.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 42.1 (old name: test 202 -->
+<!--- two opposite rules put into one policy in one policy set-->
+<!--- this case will have the result of deny because of default rules combining==deny override, which is not the same as policies combining -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s42.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r42.1</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r42.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 42.2 (old name: test 202b -->
+<!--- two opposite rules put into one policy in one policy set-->
+<!--- this case will have the result of deny because of default rules combining==deny override, which is not the same as policies combining -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s42.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r42.2</resource-match>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r42.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 43.1 (old name: test 203 -->
+
+<!--- two opposite rules put into different policies in one policy set-->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s43.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r43.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r43.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<!--- test 43.2 (old name: test 203b -->
+
+<!--- two opposite rules put into different policies in one policy set-->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s43.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r43.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r43.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 44.1 (old name: test 204 -->
+<!--- two different rules put into different policies in one policy set-->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s44.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r44.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r44.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 44.2 (old name: test 204b -->
+<!--- two different rules put into different policies in one policy set-->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s44.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r44.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r44.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 45.1 (old name: test 205 -->
+<!--- two opposite rules put into one policy -->
+<!--- testing rules combining methods-->
+<!--- this case should have the result of permit in contradiction to test 202 -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s45.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r45.1</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r45.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<!--- test 45.2 (old name: test 205b -->
+<!--- two opposite rules put into one policy -->
+<!--- testing rules combining methods-->
+<!--- this case should have the result of deny-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s45.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r45.2</resource-match>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r45.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 46.1 (old name: test 206 -->
+<!--- two opposite rules put into one policy -->
+
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s46.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="permit-overrides">
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r46.1</resource-match>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r46.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<!--- test 46.2 (old name: test 206b -->
+<!--- two opposite rules put into one policy -->
+
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s46.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="permit-overrides">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r46.2</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r46.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 47.1 (old name: test 207 -->
+<!--- two opposite rules put into one policy -->
+
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s47.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="deny-overrides">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r47.1</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r47.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<!--- test 47.2 (old name: test 207b -->
+<!--- two opposite rules put into one policy -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s47.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="deny-overrides">
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r47.2</resource-match>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r47.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 48 (old name: test 101)-->
+
+<policy-set combine="first-matching-target">
+<target>
+<subject>
+<subject-match attr="id">s48</subject-match>
+<subject-match attr="uri.host" match="www.test.pl"/>
+
+</subject>
+</target>
+<policy>
+<rule effect="permit">
+<condition combine="and">
+<resource-match attr="resource-id" match="device:pim.contacts"/>
+<!--<subject-match attr="uri" match="http://www.test.pl:80"/>-->
+</condition>
+</rule>
+</policy>
+</policy-set>
+
+</policy-set>
+
+</signed-policy>
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+INSTALL(FILES
+ ${PROJECT_SOURCE_DIR}/tests/ace/test-configuration/policy-example.xml
+ ${PROJECT_SOURCE_DIR}/tests/ace/test-configuration/policy-wac-2.0.xml
+ ${PROJECT_SOURCE_DIR}/tests/ace/test-configuration/attr_policy-example.xml
+ ${PROJECT_SOURCE_DIR}/tests/ace/test-configuration/policy-example2.xml
+ ${PROJECT_SOURCE_DIR}/tests/ace/test-configuration/policy-example3.xml
+ ${PROJECT_SOURCE_DIR}/tests/ace/test-configuration/policy_example.xml
+ ${PROJECT_SOURCE_DIR}/tests/ace/test-configuration/general-test.xml
+ ${PROJECT_SOURCE_DIR}/tests/ace/test-configuration/interceptpolicy.xml
+ ${PROJECT_SOURCE_DIR}/tests/ace/test-configuration/policy-test.xml
+ ${PROJECT_SOURCE_DIR}/tests/ace/test-configuration/policy-test-gsettings.xml
+ ${PROJECT_SOURCE_DIR}/tests/ace/test-configuration/attre_config.xml
+ ${PROJECT_SOURCE_DIR}/tests/ace/test-configuration/attr_policy-example1.xml
+ ${PROJECT_SOURCE_DIR}/tests/ace/test-configuration/attr_policy-example2.xml
+ ${PROJECT_SOURCE_DIR}/tests/ace/test-configuration/attr_policy-example3.xml
+ ${PROJECT_SOURCE_DIR}/tests/ace/test-configuration/attr_policy-example4.xml
+ ${PROJECT_SOURCE_DIR}/tests/ace/test-configuration/attr_policy-example5.xml
+ ${PROJECT_SOURCE_DIR}/tests/ace/test-configuration/attr_policy-example6.xml
+ ${PROJECT_SOURCE_DIR}/tests/ace/test-configuration/attr_policy-example7.xml
+ ${PROJECT_SOURCE_DIR}/tests/ace/test-configuration/attr_policy-example8.xml
+ ${PROJECT_SOURCE_DIR}/tests/ace/test-configuration/undefined-test.xml
+ DESTINATION /usr/etc/ace
+ PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ GROUP_WRITE
+ )
+
+ADD_SUBDIRECTORY(CMTest)
--- /dev/null
+ <policy-set id="Policy-1" combine="first-matching-target">
+
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="name" match="analogclock"/>
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ device.simcard
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="name" match="memo" />
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ file.write
+ </resource-match>
+ <subject-match attr="name" match="memo" />
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="name" match="phonesearch" />
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ pim.contact
+ </resource-match>
+ <subject-match attr="name" match="phonesearch" />
+ </condition>
+ </rule>
+ </policy>
+
+ </policy-set>
\ No newline at end of file
--- /dev/null
+ <policy-set id="Policy-1" combine="first-matching-target">
+
+
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="uri.host" match="freebeer.evil.com" />
+ <subject-match attr="version" match="4" />
+
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="r8v2" match="2" />
+ </condition>
+ </rule>
+
+ </policy>
+
+
+
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="key-root-trust" match="manufacturer" />
+
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="author" match="author3" />
+ </condition>
+ </rule>
+
+ </policy>
+
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="id" match="urn:megacorp:widget:anapp" />
+
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="r9a.scheme" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+
+ </policy>
+
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="signer-id" match="7zha89%49x£$" />
+
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="r9b.authority" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+
+ </policy>
+
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="id" match="urn:megacorp:widget:anapp" />
+
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="r9a.scheme" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+
+ </policy>
+
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="signer-id" match="7zha89%49x£$" />
+
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="r9c.scheme-authority" match="http://onet.pl" />
+ </condition>
+ </rule>
+
+ </policy>
+
+ </policy-set>
\ No newline at end of file
--- /dev/null
+<policy-set id="Policy-3" combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id" match="subject7" />
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource7
+ </resource-match>
+ <condition combine="and">
+ <condition combine="or">
+ <subject-match attr="version" match="7" />
+ <subject-match attr="version" match="6" />
+ </condition>
+ <resource-match attr="author" match="author2" />
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource7
+ </resource-match>
+ <condition combine="or">
+ <condition combine="or">
+ <subject-match attr="version" match="1" />
+ <subject-match attr="version" match="2" />
+ </condition>
+ <resource-match attr="author" match="author3" />
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource7
+ </resource-match>
+ <condition combine="or">
+ <condition combine="or">
+ <subject-match attr="version" match="1" />
+ <subject-match attr="version" match="2" />
+ </condition>
+ <resource-match attr="author" match="author3" />
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
\ No newline at end of file
--- /dev/null
+<policy-set id="Policy-1">
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">
+ subject
+ </subject-match>
+ </subject>
+ <subject>
+ <subject-match attr="id" match="subject2" />
+ </subject>
+ </target>
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="id" match="subject" />
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource
+ </resource-match>
+ <subject-match attr="version" match="3" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="id" match="subject2" />
+ </subject>
+ </target>
+ <rule effect="deny">
+ <condition>
+ <resource-match attr="resource-id">
+ resource
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<policy-set >
+ <target>
+ <subject>
+ <subject-match attr="id">
+ subject3
+ </subject-match>
+ </subject>
+ <subject>
+ <subject-match attr="id" match="subject4" />
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource2
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition>
+ <resource-match attr="resource-id">
+ resource2
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="id">
+ subject4
+ </subject-match>
+ <subject-match attr="version" match="4" />
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-2" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id" match="subject5" />
+ </subject>
+ <subject>
+ <subject-match attr="id" match="subject6" />
+ </subject>
+ </target>
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="id">
+ subject5
+ </subject-match>
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource5
+ </resource-match>
+ <subject-match attr="version" match="5" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <resource-match attr="author">
+ resource6
+ </resource-match>
+ <subject-match attr="version" match="6" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+</policy-set>
\ No newline at end of file
--- /dev/null
+<policy-set id="Policy-3" combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id" match="subject7" />
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource7
+ </resource-match>
+ <condition combine="and">
+ <condition combine="or">
+ <subject-match attr="version" match="7" />
+ <subject-match attr="version" match="6" />
+ </condition>
+ <resource-match attr="author" match="author2" />
+ </condition>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource7
+ </resource-match>
+ <condition combine="and">
+ <condition combine="or">
+ <subject-match attr="version" match="7" />
+ <subject-match attr="version" match="6" />
+ </condition>
+ <environment-match attr="author" match="author2" />
+ </condition>
+ </condition>
+ </rule>
+
+
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource7
+ </resource-match>
+ <condition combine="or">
+ <condition combine="or">
+ <subject-match attr="version" match="1" />
+ <subject-match attr="version" match="2" />
+ </condition>
+ <resource-match attr="author" match="author3" />
+ </condition>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource7
+ </resource-match>
+ <condition combine="or">
+ <condition combine="or">
+ <subject-match attr="version" match="1" />
+ <subject-match attr="version" match="2" />
+ </condition>
+ <resource-match attr="author" match="author3" />
+ </condition>
+ </condition>
+ </rule>
+
+
+
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource7
+ </resource-match>
+ <condition combine="or">
+ <condition combine="or">
+ <subject-match attr="version" match="1" />
+ <environment-match attr="version" match="2" />
+ </condition>
+ <resource-match attr="author" match="author3" />
+ </condition>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource7
+ </resource-match>
+ <condition combine="or">
+ <condition combine="or">
+ <environment-match attr="ver" match="1" />
+ <subject-match attr="version" match="2" />
+ </condition>
+ <resource-match attr="author" match="author3" />
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
\ No newline at end of file
--- /dev/null
+<policy-set id="Policy-3" combine="deny-overrides">
+
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="name" match="analogclock"/>
+ <subject-match attr="uri.host" match="freebeer.evil.com" />
+ <subject-match attr="key-root-trust" match="manufacturer" />
+ <subject-match attr="id" match="urn:megacorp:widget:anapp" />
+ <subject-match attr="signer-id" match="7zha89%49xL$" />
+ <subject-match attr="version" match="5"/>
+
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">device.simcard</resource-match>
+ <resource-match attr="r8v2" match="2" />
+ <resource-match attr="author" match="author3" />
+ <resource-match attr="r9a.scheme" match="http://onet.pl:80/test.html" />
+ <resource-match attr="r9b.authority" match="http://onet.pl:80/test.html" />
+ <resource-match attr="r9c.scheme-authority" match="http://onet.pl" />
+
+ <environment-match attr="resource-id">device.simcard</environment-match>
+ <environment-match attr="r8v2" match="2" />
+ <environment-match attr="author" match="author3" />
+ <environment-match attr="r9a.scheme" match="http://onet.pl:80/test.html" />
+ <environment-match attr="r9b.authority" match="http://onet.pl:80/test.html" />
+ <environment-match attr="r9c.scheme-authority" match="http://onet.pl" />
+
+ <subject-match attr="resource-id">device.simcard</subject-match>
+ <subject-match attr="r8v2" match="2" />
+ <subject-match attr="author" match="author3" />
+ <subject-match attr="r9a.scheme" match="http://onet.pl:80/test.html" />
+ <subject-match attr="r9b.authority" match="http://onet.pl:80/test.html" />
+ <subject-match attr="r9c.scheme-authority" match="http://onet.pl" />
+
+ </condition>
+ </rule>
+ </policy>
+
+
+</policy-set>
\ No newline at end of file
--- /dev/null
+<policy-set id="Policy-3" combine="deny-overrides">
+
+<policy>
+ <target>
+ <subject>
+ <subject-match attr="s-name" match="analogclock"/>
+ <subject-match attr="s-uri.host" match="freebeer.evil.com" />
+ <subject-match attr="s-key-root-trust" match="manufacturer" />
+ <subject-match attr="s-id" match="urn:megacorp:widget:anapp" />
+ <subject-match attr="s-signer-id" match="7zha89%49xL$" />
+ <subject-match attr="s-version" match="5"/>
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="r-resource-id">device.simcard</resource-match>
+ <resource-match attr="r-r8v2" match="2" />
+ <resource-match attr="r-author" match="author3" />
+ <resource-match attr="r-r9a.scheme" match="http://onet.pl:80/test.html" />
+ <resource-match attr="r-r9b.authority" match="http://onet.pl:80/test.html" />
+ <resource-match attr="r-r9c.scheme-authority" match="http://onet.pl" />
+
+ <environment-match attr="e-resource-id">device.simcard</environment-match>
+ <environment-match attr="e-r8v2" match="2" />
+ <environment-match attr="e-author" match="author3" />
+ <environment-match attr="e-r9a.scheme" match="http://onet.pl:80/test.html" />
+ <environment-match attr="e-r9b.authority" match="http://onet.pl:80/test.html" />
+ <environment-match attr="e-r9c.scheme-authority" match="http://onet.pl" />
+
+ <subject-match attr="s-resource-id">device.simcard</subject-match>
+ <subject-match attr="s-r8v2" match="2" />
+ <subject-match attr="s-author" match="author3" />
+ <subject-match attr="s-r9a.scheme" match="http://onet.pl:80/test.html" />
+ <subject-match attr="s-r9b.authority" match="http://onet.pl:80/test.html" />
+ <subject-match attr="s-r9c.scheme-authority" match="http://onet.pl" />
+ </condition>
+ </rule>
+</policy>
+
+
+</policy-set>
\ No newline at end of file
--- /dev/null
+<policy-set id="Policy-3" combine="deny-overrides">
+
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="name" match="analogclock"/>
+ <subject-match attr="uri.host" match="freebeer.evil.com" />
+ <subject-match attr="key-root-trust" match="manufacturer" />
+ <subject-match attr="id" match="urn:megacorp:widget:anapp" />
+ <subject-match attr="signer-id" match="7zha89%49xL$" />
+ <subject-match attr="version" match="5"/>
+
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition>
+
+ <subject-match attr="resource-id">device.simcard</subject-match>
+ <subject-match attr="r8v2" match="2" />
+ <subject-match attr="author" match="author3" />
+ <subject-match attr="r9a.scheme" match="http://onet.pl:80/test.html" />
+ <subject-match attr="r9b.authority" match="http://onet.pl:80/test.html" />
+ <subject-match attr="r9c.scheme-authority" match="http://onet.pl" />
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition>
+
+ <environment-match attr="resource-id">device.simcard</environment-match>
+ <environment-match attr="r8v2" match="2" />
+ <environment-match attr="author" match="author3" />
+ <environment-match attr="r9a.scheme" match="http://onet.pl:80/test.html" />
+ <environment-match attr="r9b.authority" match="http://onet.pl:80/test.html" />
+ <environment-match attr="r9c.scheme-authority" match="http://onet.pl" />
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">device.simcard</resource-match>
+ <resource-match attr="r8v2" match="2" />
+ <resource-match attr="author" match="author3" />
+ <resource-match attr="r9a.scheme" match="http://onet.pl:80/test.html" />
+ <resource-match attr="r9b.authority" match="http://onet.pl:80/test.html" />
+ <resource-match attr="r9c.scheme-authority" match="http://onet.pl" />
+
+ </condition>
+ </rule>
+
+ </policy>
+
+
+</policy-set>
\ No newline at end of file
--- /dev/null
+<policy-set id="Policy-3" combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id" match="subject7" func="regexp" />
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource7
+ </resource-match>
+ <condition combine="and">
+ <condition combine="or">
+ <subject-match attr="version" match="7" func="equal" />
+ <subject-match attr="version" match="6" />
+ </condition>
+ <resource-match attr="author" match="author2" />
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource7
+ </resource-match>
+ <condition combine="or">
+ <condition combine="or">
+ <subject-match attr="version" match="1" />
+ <subject-match attr="version" match="2" />
+ </condition>
+ <resource-match attr="author" match="author3" func="regexp"/>
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource7
+ </resource-match>
+ <condition combine="or">
+ <condition combine="or">
+ <subject-match attr="version" match="1" />
+ <subject-match attr="version" match="2" />
+ </condition>
+ <resource-match attr="author" match="author3" />
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" ?>
+<!DOCTYPE manager-settings SYSTEM "config.dtd">
+<manager-settings>
+ <editable-by-user>false</editable-by-user>
+ <storage-path>/usr/etc/ace/</storage-path>
+ <policy-files>
+ <file active="true">attr_policy-example.xml</file>
+ </policy-files>
+ <trusted-providers>
+ <provider>samsung</provider>
+ </trusted-providers>
+ <untrusted-providers>
+ <provider>nokia</provider>
+ </untrusted-providers>
+</manager-settings>
+
+
--- /dev/null
+<policy-set id="Policy-1" combine="first-matching-target" >
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">
+ subject
+ </subject-match>
+ </subject>
+ <subject>
+ <subject-match attr="id" match="subject2" />
+ </subject>
+ </target>
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="id" match="subject" />
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource
+ </resource-match>
+ <subject-match attr="version" match="3" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="id" match="subject2" />
+ </subject>
+ </target>
+ <rule effect="deny">
+ <condition>
+ <resource-match attr="resource-id">
+ resource
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<policy-set >
+ <target>
+ <subject>
+ <subject-match attr="id">
+ subject3
+ </subject-match>
+ </subject>
+ <subject>
+ <subject-match attr="id" match="subject4" />
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource2
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition>
+ <resource-match attr="resource-id">
+ resource2
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="id">
+ subject4
+ </subject-match>
+ <subject-match attr="version" match="4" />
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<policy-set id="Policy-2" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id" match="subject5" />
+ </subject>
+ <subject>
+ <subject-match attr="id" match="subject6" />
+ </subject>
+ </target>
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="id">
+ subject5
+ </subject-match>
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource5
+ </resource-match>
+ <subject-match attr="version" match="5" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <resource-match attr="resource-id">
+ resource6
+ </resource-match>
+ <subject-match attr="version" match="6" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-3" combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id" match="subject7" />
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource7
+ </resource-match>
+ <condition combine="and">
+ <condition combine="or">
+ <subject-match attr="version" match="7" />
+ <subject-match attr="version" match="6" />
+ </condition>
+ <resource-match attr="author" match="author2" />
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource7
+ </resource-match>
+ <condition combine="or">
+ <condition combine="or">
+ <subject-match attr="version" match="1" />
+ <subject-match attr="version" match="2" />
+ </condition>
+ <resource-match attr="author" match="author3" />
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource7
+ </resource-match>
+ <condition combine="or">
+ <condition combine="or">
+ <subject-match attr="version" match="1" />
+ <subject-match attr="version" match="2" />
+ </condition>
+ <resource-match attr="author" match="author3" />
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+
+<policy-set id="Policy-4" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s8a</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r8</resource-match>
+ <resource-match attr="r8v1" match="1" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r8</resource-match>
+ <resource-match attr="r8v2" match="2" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-5" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s8b</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r8</resource-match>
+ <resource-match attr="r8v2" match="2" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r8</resource-match>
+ <resource-match attr="r8v1" match="1" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-6" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s8c</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r8</resource-match>
+ <resource-match attr="r8v1" match="1" />
+ <resource-match attr="r8v2" match="1" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny" />
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-7" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9a</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable" >
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9a.scheme" match="http" />
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9a" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-8" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9b</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable" >
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9b.authority" match="onet.pl:80" />
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9b" match="777" func="equal" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-9" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9c</subject-match>
+ </subject>
+ </target>
+ <policy combine="permit-overrides" >
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9c.scheme" match="http" />
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9c.authority" match="onet.pl:80" />
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9c.scheme-authority" match="http://onet.pl:80" />
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9c" match="*" func="glob" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-10" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9d</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable" >
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9d.scheme" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9d.authority" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9d" match="*" func="glob" />
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9d.scheme-authority" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-11" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9e</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable" >
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9e.host" match="onet.pl" />
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9e" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-12" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9f</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable" >
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9e.scheme-authority" match="http://onet.pl:80" />
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9e" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-13" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9g</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable" >
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9g.path" match="test.html" />
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9g" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-14" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9h</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable" >
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9g.path" match="test.html" />
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9g" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-15" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s10a</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10a" match="[1234567890]+[ab]+" func="regexp" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10a" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-16" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s10b</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10a" match="[1234567890]+[ab]+" func="regexp" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10a" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-17" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s10c</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable" >
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10c2" match="[1234567890]+[ab]+" func="regexp" />
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10c" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!-- justyna -->
+
+<!--- test 13 (old name: test 100)-->
+
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s13</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="uri.authority" match="buu.com.pl"/>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s16</subject-match>
+ <subject-match attr="uri.authority" match="v.com.pl"/>
+
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 17 (old name: test 104)-->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s17a</subject-match>
+ <subject-match attr="version" match="4" />
+ </subject>
+ </target>
+<policy>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s17b</subject-match>
+ <subject-match attr="version" match="4" />
+ </subject>
+ </target>
+<policy>
+ <rule effect="deny">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 18 (old name: test 105)-->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="uri" match="buu.com.pl"/>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id" match="s18b"/>
+ <subject-match attr="uri" match="buu.s18b.pl"/>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id" match="s18c"/>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="uri" match="buu.s18c.pl"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 19 (old name: test 106)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s19.1</subject-match>
+ <subject-match attr="key-root-trust" match="voperator"/>
+ </subject>
+ </target>
+<policy>
+ <rule effect="deny">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s19.2</subject-match>
+ <subject-match attr="key-root-trust" match="voperator"/>
+ </subject>
+ </target>
+<policy>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 20 (old name: test 107)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s20.1</subject-match>
+ <subject-match attr="signer-id" match="v7zha89%49x£$"/>
+ </subject>
+ </target>
+<policy>
+ <rule effect="deny">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s20.2</subject-match>
+ <subject-match attr="signer-id" match="v7zha89%49x£$"/>
+ </subject>
+ </target>
+<policy>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!-- justyna -->
+
+
+<!--- test 21 (old name: test 103 U)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s21</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s21a</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="undetermined"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 23 (old name: test 105 U)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s23</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 24 (old name: test 106 U)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s24</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <subject-match attr="version" match="5"/>
+ <resource-match attr="resource-id" match="device:pim"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 25.1 (old name: test 107 U)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s25.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <environment-match attr="roaming" match="off"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 25.2 (old name: test 107 a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s25.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 25.3 (old name: test 107 b U -->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s25.3</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <subject-match attr="version" match="9"/>
+ </condition>
+
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 25.4 (old name: test 107 c U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s25.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 26.1 (old name: test 108 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s26.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 26.2 (old name: test 108 a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s26.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 26.3 (old name: test 108 b U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s26.3</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 26.4 (old name: test 108 c U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s26.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 27.1 (old name: test 109 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s27.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 27.2 (old name: test 109a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s27.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 27.3 (old name: test 109b U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s27.3</subject-match>
+ <subject-match attr="version" match="5"/>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 27.4 (old name: test 109c U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s27.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 28 (old name: test 110 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s28</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 29 (old name: test 111 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s29</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 30.1 (old name: test 112 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s30.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 30.2 (old name: test 112a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s30.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 30.3 (old name: test 112b U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s30.3</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 30.4 (old name: test 112c U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s30.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+</policy-set>
+
+
+
+<!--- test 31.1 (old name: test 113 U -->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s31.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 31.2.1 (old name: test 113a U -->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s31.2.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 31.2.2 (old name: test 113aa U -->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s31.2.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 31.3 (old name: test 113b U -->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s31.3</subject-match>
+ </subject>
+ </target>
+
+
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+</policy-set>
+
+<!--- test 32.1 (old name: test 114 U -->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s32.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 32.2.1 (old name: test 114a U -->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s32.2.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 32.2.2 (old name: test 114aa U -->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s32.2.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 32.3 (old name: test 114b U -->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s32.3</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 33.1 (old name: test 115 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s33.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 33.2 (old name: test 115a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s33.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 33.3 (old name: test 115b U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s33.3</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 34.1 (old name: test 116 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s34.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="permit-overrides">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 34.2 (old name: test 116 a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s34.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="permit-overrides">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 35.1 (old name: test 117 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s35.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="deny-overrides">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 35.2 (old name: test 117 a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s35.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="deny-overrides">
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set>
+ <target>
+ <subject>
+ <subject-match attr="id">org.tizen.widget.analogclock</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="http://helloheloo/"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 36 (old name: test 102 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s36</subject-match>
+ <subject-match attr="version" match="5"/>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+
+<!--- test 37 (old name: test 108 -->
+<!-- mbialota modified -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s37</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="prompt-oneshot">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 38 (old name: test 109 -->
+<!-- mbialota modified -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s38</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="prompt-session">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s38.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="prompt-session">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 39 (old name: test 110 -->
+<!-- mbialota modified -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s39</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="prompt-blanket">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s39.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="prompt-blanket">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!-- Maria -->
+<!-- testing different methods of policies and rules combining-->
+<!--- test 40 (old name: test 200 -->
+
+<!--- two opposite rules put into different policies in one policy set -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s40</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r40</resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r40</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 41 (old name: test 201 -->
+
+<!--- two different rules put into different policies in one policy set-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s41</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r41</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r41.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 42.1 (old name: test 202 -->
+<!--- two opposite rules put into one policy in one policy set-->
+<!--- this case will have the result of deny because of default rules combining==deny override, which is not the same as policies combining -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s42.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r42.1</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r42.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 42.2 (old name: test 202b -->
+<!--- two opposite rules put into one policy in one policy set-->
+<!--- this case will have the result of deny because of default rules combining==deny override, which is not the same as policies combining -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s42.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r42.2</resource-match>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r42.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 43.1 (old name: test 203 -->
+
+<!--- two opposite rules put into different policies in one policy set-->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s43.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r43.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r43.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<!--- test 43.2 (old name: test 203b -->
+
+<!--- two opposite rules put into different policies in one policy set-->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s43.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r43.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r43.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 44.1 (old name: test 204 -->
+<!--- two different rules put into different policies in one policy set-->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s44.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r44.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r44.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 44.2 (old name: test 204b -->
+<!--- two different rules put into different policies in one policy set-->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s44.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r44.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r44.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 45.1 (old name: test 205 -->
+<!--- two opposite rules put into one policy -->
+<!--- testing rules combining methods-->
+<!--- this case should have the result of permit in contradiction to test 202 -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s45.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r45.1</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r45.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<!--- test 45.2 (old name: test 205b -->
+<!--- two opposite rules put into one policy -->
+<!--- testing rules combining methods-->
+<!--- this case should have the result of deny-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s45.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r45.2</resource-match>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r45.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 46.1 (old name: test 206 -->
+<!--- two opposite rules put into one policy -->
+
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s46.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="permit-overrides">
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r46.1</resource-match>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r46.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<!--- test 46.2 (old name: test 206b -->
+<!--- two opposite rules put into one policy -->
+
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s46.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="permit-overrides">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r46.2</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r46.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 47.1 (old name: test 207 -->
+<!--- two opposite rules put into one policy -->
+
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s47.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="deny-overrides">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r47.1</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r47.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<!--- test 47.2 (old name: test 207b -->
+<!--- two opposite rules put into one policy -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s47.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="deny-overrides">
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r47.2</resource-match>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r47.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 48 (old name: test 101)-->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s48</subject-match>
+ <subject-match attr="uri.host" match="www.test.pl"/>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <!--<subject-match attr="uri" match="http://www.test.pl:80"/>-->
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 51 - BugFest00-->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">BF00</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="BFR00"/>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="BFR00"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 52 - BugFest01-->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">BF01</subject-match>
+ </subject>
+ </target>
+ <policy-set combine="first-matching-target">
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="BFR01"/>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="BFR01"/>
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+</policy-set>
+
+
+<!--- test 53 - BugFest02-->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">BF02</subject-match>
+ </subject>
+ </target>
+ <policy-set combine="first-matching-target">
+ <policy combine="permit-overrides">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="BFR02"/>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="BFR02"/>
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+</policy-set>
+
+<!--- test 54 - BugFest03-->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">BF03</subject-match>
+ </subject>
+ </target>
+ <policy-set combine="first-matching-target">
+ <policy combine="deny-overrides">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="BFR03"/>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="BFR03"/>
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+</policy-set>
+
+
+<!--- test 55 - BugFest04-->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">BF04</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">BFR04</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">BFR04</resource-match>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s61a</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r61a</resource-match>
+ <resource-match attr="param:name">type</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r61a</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s61b</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r61b</resource-match>
+ <resource-match attr="param:name">type</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r61b</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s61c</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r61c</resource-match>
+ <resource-match attr="param:name">type</resource-match>
+ <resource-match attr="param:name">port</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r61c</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s61d</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r61d</resource-match>
+ <resource-match attr="param:name">type</resource-match>
+ <resource-match attr="param:name">port</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r61d</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">paramTestSubject</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="dev-cap">messaging</resource-match>
+ <resource-match attr="param:recipients" func="glob" >+4409*</resource-match>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="dev-cap">messaging</resource-match>
+ <resource-match attr="param:recipients" func="glob" >+4408*</resource-match>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="dev-cap">messaging</resource-match>
+ <resource-match attr="param:recipients" func="glob" >+48*</resource-match>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="dev-cap">camera</resource-match>
+ <resource-match attr="param:quality">high</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="dev-cap">camera</resource-match>
+ <resource-match attr="param:quality">low</resource-match>
+ </condition>
+ </rule>
+ </policy>
+
+</policy-set>
+
+
+</policy-set>
--- /dev/null
+ <policy-set id="Policy-1" combine="first-matching-target">
+
+ <policy-set combine="deny-overrides" >
+ <target>
+ <subject>
+ <subject-match attr="JilSecurityDomain">
+ Unidentified
+ </subject-match>
+ </subject>
+ </target>
+ <policy combine="deny-overrides">
+ <rule effect="deny">
+ <condition combine="and" >
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/device
+ </resource-match>
+ <resource-match attr="param:function">
+ getAvailableApplications
+ </resource-match>
+ </condition>
+ </rule>
+ <rule effect="prompt-oneshot">
+ <condition combine="or" >
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/addressbookitem.AddressBookItem.update
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.Camera.captureImage
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/device.Device.launchApplication
+ </resource-match>
+ <resource-match attr="resource-id">
+ DeviceStateInfo.requestPositionInfo
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/messaging.Messaging.sendMessage
+ </resource-match>
+ </condition>
+ </rule>
+ <rule effect="prompt-session">
+ <condition combine="or" >
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.1/pim.PIM.findAddressBookItems
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.1/pim.PIM.getAddressBookItem
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.1/pim.PIM.getAddressBookItemsCount
+ </resource-match>
+ </condition>
+ </rule>
+ <!-- If the resource was not specified above then the access is unrestricted -->
+ <rule effect="permit">
+ <condition combine="or" >
+ <resource-match attr="resource-id">
+ Device.PositionInfo
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/addressbookitem.AddressBookItem.getAttributeValue
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/addressbookitem.AddressBookItem.getAvailableAttributes
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/addressbookitem.AddressBookItem.setAttributeValue
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.AudioPlayer.open
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.AudioPlayer.play
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.AudioPlayer.pause
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.AudioPlayer.resume
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.AudioPlayer.stop
+ </resource-match>
+ <resource-match attr="resource-id">
+ AudioPlayer.onStateChange
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.Camera.onCameraCaptured
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.Camera.setWindow
+ </resource-match>
+ <resource-match attr="resource-id">
+ Device.PositionInfo
+ </resource-match>
+ <resource-match attr="resource-id">
+ Device.DeviceStateInfo
+ </resource-match>
+ <resource-match attr="resource-id">
+ DeviceStateInfo.onPositionRetrieved
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/messaging.Messaging.createMessage
+ </resource-match>
+ <resource-match attr="resource-id">
+ Messaging.onMessageSendingFailure
+ </resource-match>
+ <resource-match attr="resource-id">
+ Multimedia.getVolume
+ </resource-match>
+ <resource-match attr="resource-id">
+ Multimedia.stopAll
+ </resource-match>
+ <resource-match attr="resource-id">
+ Multimedia.isAudioPlaying
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.1/pim.PIM.createAddressBookItem
+ </resource-match>
+ <resource-match attr="resource-id">
+ PIM.onAddressBookItemFound
+ </resource-match>
+
+ <!-- This part contains api-features defined in WAC1.0 -->
+
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/accelerometerinfo
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/addressbookitem
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.5/applicationtypes
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.2/camera
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/device
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/devicestateinfo
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.5/exception
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.5/exceptiontypes
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/message
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/messagetypes
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/messaging
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.1/pim
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/positioninfo
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/widget
+ </resource-match>
+ </condition>
+ </rule>
+ <rule effect="permit" />
+ </policy>
+ </policy-set>
+
+ <policy-set combine="deny-overrides" >
+ <target>
+ <subject>
+ <subject-match attr="JilSecurityDomain">
+ Identified
+ </subject-match>
+ </subject>
+ </target>
+ <policy combine="deny-overrides">
+ <rule effect="prompt-session">
+ <condition combine="or" >
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/addressbookitem.AddressBookItem.update
+ </resource-match>
+ <resource-match attr="resource-id">
+ DeviceStateInfo.requestPositionInfo
+ </resource-match>
+ </condition>
+ </rule>
+ <rule effect="prompt-blanket">
+ <condition combine="or" >
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/device.Device.launchApplication
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.Camera.captureImage
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/messaging.Messaging.sendMessage
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.1/pim.PIM.findAddressBookItems
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.1/pim.PIM.getAddressBookItem
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.1/pim.PIM.getAddressBookItemsCount
+ </resource-match>
+ </condition>
+ </rule>
+ <!-- If the resource was not specified above then the access is unrestricted -->
+ <rule effect="permit">
+ <condition combine="or" >
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/device.Device.getAvailableApplications
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/addressbookitem.AddressBookItem.getAttributeValue
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/addressbookitem.AddressBookItem.getAvailableAttributes
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/addressbookitem.AddressBookItem.setAttributeValue
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.AudioPlayer.open
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.AudioPlayer.play
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.AudioPlayer.pause
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.AudioPlayer.resume
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.AudioPlayer.stop
+ </resource-match>
+ <resource-match attr="resource-id">
+ AudioPlayer.onStateChange
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.Camera.onCameraCaptured
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.Camera.setWindow
+ </resource-match>
+ <resource-match attr="resource-id">
+ Device.PositionInfo
+ </resource-match>
+ <resource-match attr="resource-id">
+ Device.DeviceStateInfo
+ </resource-match>
+ <resource-match attr="resource-id">
+ DeviceStateInfo.onPositionRetrieved
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/messaging.Messaging.createMessage
+ </resource-match>
+ <resource-match attr="resource-id">
+ Messaging.onMessageSendingFailure
+ </resource-match>
+ <resource-match attr="resource-id">
+ Multimedia.getVolume
+ </resource-match>
+ <resource-match attr="resource-id">
+ Multimedia.stopAll
+ </resource-match>
+ <resource-match attr="resource-id">
+ Multimedia.isAudioPlaying
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.1/pim.PIM.createAddressBookItem
+ </resource-match>
+ <resource-match attr="resource-id">
+ PIM.onAddressBookItemFound
+ </resource-match>
+
+ <!-- This part contains api-features defined in WAC1.0 -->
+
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/accelerometerinfo
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/addressbookitem
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.5/applicationtypes
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.2/camera
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/device
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/devicestateinfo
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.5/exception
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.5/exceptiontypes
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/message
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/messagetypes
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/messaging
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.1/pim
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/positioninfo
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/widget
+ </resource-match>
+ </condition>
+ </rule>
+ <rule effect="permit" />
+ </policy>
+ </policy-set>
+
+ <policy-set combine="deny-overrides" >
+ <target>
+ <subject>
+ <subject-match attr="JilSecurityDomain">
+ Operator
+ </subject-match>
+ </subject>
+ </target>
+ <policy combine="deny-overrides">
+ <rule effect="permit">
+ <condition combine="or" >
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/device.Device.launchApplication
+ </resource-match>
+ <resource-match attr="resource-id">
+ DeviceStateInfo.requestPositionInfo
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/addressbookitem.AddressBookItem.update
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/device.Device.getAvailableApplications
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/addressbookitem.AddressBookItem.getAttributeValue
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/addressbookitem.AddressBookItem.getAvailableAttributes
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/addressbookitem.AddressBookItem.setAttributeValue
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.AudioPlayer.open
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.AudioPlayer.play
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.AudioPlayer.pause
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.AudioPlayer.resume
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.AudioPlayer.stop
+ </resource-match>
+ <resource-match attr="resource-id">
+ AudioPlayer.onStateChange
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.Camera.onCameraCaptured
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.Camera.setWindow
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia.Camera.captureImage
+ </resource-match>
+ <resource-match attr="resource-id">
+ Device.PositionInfo
+ </resource-match>
+ <resource-match attr="resource-id">
+ Device.DeviceStateInfo
+ </resource-match>
+ <resource-match attr="resource-id">
+ DeviceStateInfo.onPositionRetrieved
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/messaging.Messaging.createMessage
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/messaging.Messaging.sendMessage
+ </resource-match>
+ <resource-match attr="resource-id">
+ Messaging.onMessageSendingFailure
+ </resource-match>
+ <resource-match attr="resource-id">
+ Multimedia.getVolume
+ </resource-match>
+ <resource-match attr="resource-id">
+ Multimedia.stopAll
+ </resource-match>
+ <resource-match attr="resource-id">
+ Multimedia.isAudioPlaying
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.1/pim.PIM.createAddressBookItem
+ </resource-match>
+ <resource-match attr="resource-id">
+ PIM.onAddressBookItemFound
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.1/pim.PIM.findAddressBookItems
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.1/pim.PIM.getAddressBookItem
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.1/pim.PIM.getAddressBookItemsCount
+ </resource-match>
+
+ <!-- This part contains api-features defined in WAC1.0 -->
+
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/accelerometerinfo
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/addressbookitem
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.5/applicationtypes
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.2/camera
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/device
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/devicestateinfo
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.5/exception
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.5/exceptiontypes
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/message
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/messagetypes
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/messaging
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/multimedia
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1.1/pim
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/positioninfo
+ </resource-match>
+ <resource-match attr="resource-id">
+ http://jil.org/jil/api/1.1/widget
+ </resource-match>
+ </condition>
+ </rule>
+ <rule effect="permit" />
+ </policy>
+ </policy-set>
+ </policy-set>
--- /dev/null
+ <policy-set id="Policy-1" combine="first-matching-target">
+
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="name" match="analogclock"/>
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ device.simcard
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="name" match="memo" />
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ file.write
+ </resource-match>
+ <subject-match attr="name" match="memo" />
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="name" match="phonesearch" />
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ pim.contact
+ </resource-match>
+ <subject-match attr="name" match="phonesearch" />
+ </condition>
+ </rule>
+ </policy>
+
+ </policy-set>
--- /dev/null
+ <policy-set id="Policy-1" combine="first-matching-target">
+ <!---
+ <policy>
+ <rule effect="permit"/>
+ </policy>
+ -->
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="name" match="analogclock"/>
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="api-feature">
+ devicestatus
+ </resource-match>
+ <!--
+ <resource-match attr="feature-install-uri">
+ ww.samsung.com1
+ </resource-match>
+ -->
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="name" match="batteryMonitor"/>
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="api-feature">
+ devicestatus
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="name" match="appconfig"/>
+ </subject>
+ </target>
+ <rule effect="deny">
+ <condition>
+ <resource-match attr="api-feature">
+ http://bondi.omtp.org/api.appconfig
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+
+
+ <policy>
+ <rule effect="permit"/>
+ </policy>
+
+
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="name" match="memo" />
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ file.write
+ </resource-match>
+ <subject-match attr="name" match="memo" />
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="name" match="phonesearch" />
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ pim.contact
+ </resource-match>
+ <subject-match attr="name" match="phonesearch" />
+ </condition>
+ </rule>
+ </policy>
+
+ </policy-set>
\ No newline at end of file
--- /dev/null
+ <policy-set id="Policy-1" combine="first-matching-target">
+
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="name" match="analogclock" />
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ device.simcard
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="name" match="memo" />
+ </subject>
+ </target>
+ <rule effect="deny">
+ <condition>
+ <resource-match attr="resource-id">
+ file.write
+ </resource-match>
+ <subject-match attr="name" match="memo" />
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="name" match="phonesearch" />
+ </subject>
+ </target>
+ <rule effect="prompt-oneshot">
+ <condition>
+ <resource-match attr="resource-id">
+ pim.contact
+ </resource-match>
+ <subject-match attr="name" match="phonesearch" />
+ </condition>
+ </rule>
+ </policy>
+
+ </policy-set>
\ No newline at end of file
--- /dev/null
+ <policy-set id="Policy-1" combine="first-matching-target">
+
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="name" match="analogclock" />
+ </subject>
+ </target>
+ <rule effect="prompt-blanket">
+ <condition>
+ <resource-match attr="resource-id">
+ device.simcard
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="name" match="memo" />
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ file.write
+ </resource-match>
+ <subject-match attr="name" match="memo" />
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="name" match="phonesearch" />
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ pim.contact
+ </resource-match>
+ <subject-match attr="name" match="phonesearch" />
+ </condition>
+ </rule>
+ </policy>
+
+ </policy-set>
\ No newline at end of file
--- /dev/null
+<policy-set id="Policy-4" combine="first-matching-target">
+<policy>
+ <target>
+ <subject>
+ <subject-match attr="id">a1</subject-match>
+ </subject>
+ </target>
+
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">d3</resource-match>
+ </condition>
+ </rule>
+ </policy>
+<policy>
+ <target>
+ <subject>
+ <subject-match attr="id">aa2</subject-match>
+ </subject>
+ </target>
+
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">bb2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+
+<policy>
+ <target>
+ <subject>
+ <subject-match attr="id">c3</subject-match>
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">d3</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
\ No newline at end of file
--- /dev/null
+<policy-set id="Policy-4" combine="first-matching-target">
+<policy>
+ <target>
+ <subject>
+ <subject-match attr="id">a1</subject-match>
+ </subject>
+ </target>
+
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">b1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+<policy>
+ <target>
+ <subject>
+ <subject-match attr="id">aa2</subject-match>
+ </subject>
+ </target>
+
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">bb2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+
+<policy>
+ <target>
+ <subject>
+ <subject-match attr="id">c3</subject-match>
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">d3</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
\ No newline at end of file
--- /dev/null
+<policy-set id="Policy-1" combine="first-matching-target">
+ <policy description="WAC">
+
+ <!-- permit access to private filesystem -->
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="device-cap" match="messaging.write"/>
+ </condition>
+ </rule>
+ <!-- permit access to camera preview -->
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="device-cap" match="camera.show"/>
+ </condition>
+
+ </rule>
+ <!-- prompt-blanket access to IMEI -->
+ <rule effect="prompt-blanket">
+ <condition>
+ <resource-match attr="device-cap" match="devicestatus.networkinfo"/>
+ <resource-match attr="param:property" match="imei"/>
+ </condition>
+ </rule>
+ <!-- prompt-session access to messging when roaming -->
+ <rule effect="prompt-session">
+ <condition>
+ <resource-match attr="device-cap" match="messaging.send"/>
+ <environment-match attr="roaming" match="true"/>
+ </condition>
+ </rule>
+ <!-- prompt-session access to network when roaming -->
+ <rule effect="prompt-session">
+ <condition>
+ <condition combine="or">
+ <resource-match attr="device-cap" match="XMLHttpRequest"/>
+ <resource-match attr="device-cap" match="externalNetworkAccess"/>
+ </condition>
+ <environment-match attr="roaming" match="true"/>
+ </condition>
+ </rule>
+ <!-- prompt-blanket access to camera capture -->
+ <rule effect="prompt-blanket">
+ <condition>
+ <resource-match attr="device-cap" match="camera.capture"/>
+ </condition>
+ </rule>
+ <!-- prompt-blanket access to contacts -->
+ <rule effect="prompt-blanket">
+ <condition>
+ <resource-match attr="device-cap" match="pim.contact.*"/>
+ </condition>
+ </rule>
+ <!-- prompt-blanket access to calendar -->
+ <rule effect="prompt-blanket">
+ <condition>
+ <resource-match attr="device-cap" match="pim.calendar.*"/>
+ </condition>
+ </rule>
+ <!-- prompt-blanket access to task -->
+ <rule effect="prompt-blanket">
+ <condition>
+ <resource-match attr="device-cap" match="pim.task.*"/>
+ </condition>
+ </rule>
+ <!-- prompt-blanket access to devicestatus -->
+ <rule effect="prompt-blanket">
+ <condition>
+ <resource-match attr="device-cap" match="devicestatus.*"/>
+ </condition>
+ </rule>
+ <!-- prompt-blanket access to geolocation -->
+ <rule effect="prompt-oneshot">
+ <condition>
+ <resource-match attr="device-cap" match="geolocation"/>
+ </condition>
+ </rule>
+ <!-- prompt-blanket access to networking -->
+ <rule effect="prompt-session">
+ <condition combine="or">
+ <resource-match attr="device-cap" match="XMLHttpRequest"/>
+ <resource-match attr="device-cap" match="externalNetworkAccess"/>
+ </condition>
+ </rule>
+ <!-- prompt-blanket access to filesystem -->
+ <rule effect="prompt-blanket">
+ <condition>
+ <resource-match attr="device-cap" match="filesystem.*"/>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition>
+ <resource-match attr="device-cap" match="messaging.subscribe"/>
+ </condition>
+ </rule>
+ <!-- permit access to all remaining deviceapis -->
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="device-cap" match="*"/>
+ </condition>
+ </rule>
+ <rule effect="permit"/>
+</policy>
+</policy-set>
--- /dev/null
+<policy-set id="Policy-1">
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">
+ subject
+ </subject-match>
+ </subject>
+ <subject>
+ <subject-match attr="id" match="subject2" />
+ </subject>
+ </target>
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="id" match="subject" />
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource
+ </resource-match>
+ <subject-match attr="version" match="3" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="id" match="subject2" />
+ </subject>
+ </target>
+ <rule effect="deny">
+ <condition>
+ <resource-match attr="resource-id">
+ resource
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<policy-set >
+ <target>
+ <subject>
+ <subject-match attr="id">
+ subject3
+ </subject-match>
+ </subject>
+ <subject>
+ <subject-match attr="id" match="subject4" />
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource2
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition>
+ <resource-match attr="resource-id">
+ resource2
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="id">
+ subject4
+ </subject-match>
+ <subject-match attr="version" match="4" />
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<policy-set id="Policy-2" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id" match="subject5" />
+ </subject>
+ <subject>
+ <subject-match attr="id" match="subject6" />
+ </subject>
+ </target>
+ <policy>
+ <target>
+ <subject>
+ <subject-match attr="id">
+ subject5
+ </subject-match>
+ </subject>
+ </target>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource5
+ </resource-match>
+ <subject-match attr="version" match="5" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <resource-match attr="resource-id">
+ resource6
+ </resource-match>
+ <subject-match attr="version" match="6" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-3" combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id" match="subject7" />
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource7
+ </resource-match>
+ <condition combine="and">
+ <condition combine="or">
+ <subject-match attr="version" match="7" />
+ <subject-match attr="version" match="6" />
+ </condition>
+ <resource-match attr="author" match="author2" />
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource7
+ </resource-match>
+ <condition combine="or">
+ <condition combine="or">
+ <subject-match attr="version" match="1" />
+ <subject-match attr="version" match="2" />
+ </condition>
+ <resource-match attr="author" match="author3" />
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">
+ resource7
+ </resource-match>
+ <condition combine="or">
+ <condition combine="or">
+ <subject-match attr="version" match="1" />
+ <subject-match attr="version" match="2" />
+ </condition>
+ <resource-match attr="author" match="author3" />
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+
+<policy-set id="Policy-4" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s8a</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r8</resource-match>
+ <resource-match attr="r8v1" match="1" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r8</resource-match>
+ <resource-match attr="r8v2" match="2" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-5" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s8b</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r8</resource-match>
+ <resource-match attr="r8v2" match="2" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r8</resource-match>
+ <resource-match attr="r8v1" match="1" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-6" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s8c</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r8</resource-match>
+ <resource-match attr="r8v1" match="1" />
+ <resource-match attr="r8v2" match="1" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny" />
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-7" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9a</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9a.scheme" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9a" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-8" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9b</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9b.authority" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9b" match="777" func="equal" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-9" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9c</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9c.scheme" match="http" />
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9c.authority" match="onet.pl" />
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9c.scheme-authority" match="http://onet.pl" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9c" match="*" func="glob" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-10" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9d</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9d.scheme" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9d.authority" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9d" match="*" func="glob" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9d.scheme-authority" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-11" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9e</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9e.host" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9e" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-12" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9f</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9e.host" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9e" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-13" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9g</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9g.path" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9g" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-14" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s9h</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9g.path" match="http://onet.pl:80/test.html" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r9</resource-match>
+ <resource-match attr="r9g" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-15" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s10a</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10a" match="[1234567890]+[ab]+" func="regexp" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10a" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-16" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s10b</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10a" match="[1234567890]+[ab]+" func="regexp" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10a" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set id="Policy-17" combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s10c</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10c" match="[1234567890]+[ab]+" func="regexp" />
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r10</resource-match>
+ <resource-match attr="r10c" match="*" func="glob"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!-- justyna -->
+
+<!--- test 13 (old name: test 100)-->
+
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s13</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 14 (old name: test 101)-->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s14</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 15 (old name: test 102) -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="uri.host" match="//buu.com.pl"/>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 16 (old name: test 103) -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s16</subject-match>
+ <subject-match attr="uri.host" match="v.com.pl"/>
+
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 17 (old name: test 104)-->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">subject4</subject-match>
+ <subject-match attr="version" match="4" />
+ </subject>
+ </target>
+<policy>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">subject5</subject-match>
+ <subject-match attr="version" match="4" />
+ </subject>
+ </target>
+<policy>
+ <rule effect="deny">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 18 (old name: test 105)-->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="uri" match="buu.com.pl"/>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id" match="s18b"/>
+ <subject-match attr="uri" match="buu.s18b.pl"/>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id" match="s18c"/>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="uri" match="buu.s18c.pl"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 19 (old name: test 106)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s19.1</subject-match>
+ <subject-match attr="key-root-trust" match="voperator"/>
+ </subject>
+ </target>
+<policy>
+ <rule effect="deny">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s19.2</subject-match>
+ <subject-match attr="key-root-trust" match="voperator"/>
+ </subject>
+ </target>
+<policy>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 20 (old name: test 107)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s20.1</subject-match>
+ <subject-match attr="signer-id" match="v7zha89%49x£$"/>
+ </subject>
+ </target>
+<policy>
+ <rule effect="deny">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s20.2</subject-match>
+ <subject-match attr="signer-id" match="v7zha89%49x£$"/>
+ </subject>
+ </target>
+<policy>
+ <rule effect="permit">
+ <condition>
+ <resource-match attr="resource-id">
+ resource4
+ </resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!-- justyna -->
+
+
+<!--- test 21 (old name: test 103 U)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s21</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 23 (old name: test 105 U)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s23</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 24 (old name: test 106 U)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s24</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <subject-match attr="version" match="5"/>
+ <resource-match attr="resource-id" match="device:pim"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 25.1 (old name: test 107 U)-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s25.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 25.2 (old name: test 107 a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s25.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 25.3 (old name: test 107 b U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s25.3</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 25.4 (old name: test 107 c U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s25.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 26.1 (old name: test 108 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s26.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 26.2 (old name: test 108 a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s26.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 26.3 (old name: test 108 b U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s26.3</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 26.4 (old name: test 108 c U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s26.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 27.1 (old name: test 109 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s27.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 27.2 (old name: test 109a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s27.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 27.3 (old name: test 109b U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s27.3</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 27.4 (old name: test 109c U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s27.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 28 (old name: test 110 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s28</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 29 (old name: test 111 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s29</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 30.1 (old name: test 112 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s30.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 30.2 (old name: test 112a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s30.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 30.3 (old name: test 112b U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s30.3</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 30.4 (old name: test 112c U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s30.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+</policy-set>
+
+
+
+<!--- test 31.1 (old name: test 113 U -->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s31.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 31.2.1 (old name: test 113a U -->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s31.2.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 31.2.2 (old name: test 113aa U -->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s31.2.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 31.3 (old name: test 113b U -->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s31.3</subject-match>
+ </subject>
+ </target>
+
+
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+</policy-set>
+
+<!--- test 32.1 (old name: test 114 U -->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s32.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 32.2.1 (old name: test 114a U -->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s32.2.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 32.2.2 (old name: test 114aa U -->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s32.2.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 32.3 (old name: test 114b U -->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s32.3</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 33.1 (old name: test 115 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s33.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 33.2 (old name: test 115a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s33.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 33.3 (old name: test 115b U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s33.3</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 34.1 (old name: test 116 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s34.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="permit-overrides">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 34.2 (old name: test 116 a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s34.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="permit-overrides">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+<!--- test 35.1 (old name: test 117 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s35.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="deny-overrides">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 35.2 (old name: test 117 a U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s35.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="deny-overrides">
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set>
+ <target>
+ <subject>
+ <subject-match attr="id">org.tizen.widget.analogclock</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="http://helloheloo/"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 36 (old name: test 102 U -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s36</subject-match>
+ <subject-match attr="version" match="5"/>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+
+
+<!--- test 37 (old name: test 108 -->
+<!-- mbialota modified -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s37</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="prompt-oneshot">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 38 (old name: test 109 -->
+<!-- mbialota modified -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s38</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="prompt-session">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s38.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="prompt-session">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 39 (old name: test 110 -->
+<!-- mbialota modified -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s39</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="prompt-blanket">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s39.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="prompt-blanket">
+ <condition combine="and">
+ <resource-match attr="resource-id">device:pim.contacts.read</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!-- Maria -->
+<!-- testing different methods of policies and rules combining-->
+<!--- test 40 (old name: test 200 -->
+
+<!--- two opposite rules put into different policies in one policy set -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s40</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r40</resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r40</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 41 (old name: test 201 -->
+
+<!--- two different rules put into different policies in one policy set-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s41</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r41</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r41.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 42.1 (old name: test 202 -->
+<!--- two opposite rules put into one policy in one policy set-->
+<!--- this case will have the result of deny because of default rules combining==deny override, which is not the same as policies combining -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s42.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r42.1</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r42.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 42.2 (old name: test 202b -->
+<!--- two opposite rules put into one policy in one policy set-->
+<!--- this case will have the result of deny because of default rules combining==deny override, which is not the same as policies combining -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s42.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r42.2</resource-match>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r42.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 43.1 (old name: test 203 -->
+
+<!--- two opposite rules put into different policies in one policy set-->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s43.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r43.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r43.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<!--- test 43.2 (old name: test 203b -->
+
+<!--- two opposite rules put into different policies in one policy set-->
+<policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s43.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r43.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r43.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 44.1 (old name: test 204 -->
+<!--- two different rules put into different policies in one policy set-->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s44.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r44.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r44.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 44.2 (old name: test 204b -->
+<!--- two different rules put into different policies in one policy set-->
+<policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s44.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r44.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r44.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 45.1 (old name: test 205 -->
+<!--- two opposite rules put into one policy -->
+<!--- testing rules combining methods-->
+<!--- this case should have the result of permit in contradiction to test 202 -->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s45.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r45.1</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r45.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<!--- test 45.2 (old name: test 205b -->
+<!--- two opposite rules put into one policy -->
+<!--- testing rules combining methods-->
+<!--- this case should have the result of deny-->
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s45.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r45.2</resource-match>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r45.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 46.1 (old name: test 206 -->
+<!--- two opposite rules put into one policy -->
+
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s46.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="permit-overrides">
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r46.1</resource-match>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r46.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<!--- test 46.2 (old name: test 206b -->
+<!--- two opposite rules put into one policy -->
+
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s46.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="permit-overrides">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r46.2</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r46.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+<!--- test 47.1 (old name: test 207 -->
+<!--- two opposite rules put into one policy -->
+
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s47.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="deny-overrides">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r47.1</resource-match>
+ </condition>
+ </rule>
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r47.1</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+<!--- test 47.2 (old name: test 207b -->
+<!--- two opposite rules put into one policy -->
+
+<policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s47.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="deny-overrides">
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id">r47.2</resource-match>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id">r47.2</resource-match>
+ </condition>
+ </rule>
+ </policy>
+</policy-set>
+
+
+<!--- test 48 (old name: test 101)-->
+
+<policy-set combine="first-matching-target">
+<target>
+<subject>
+<subject-match attr="id">s48</subject-match>
+<subject-match attr="uri.host" match="www.test.pl"/>
+
+</subject>
+</target>
+<policy>
+<rule effect="permit">
+<condition combine="and">
+<resource-match attr="resource-id" match="device:pim.contacts"/>
+<!--<subject-match attr="uri" match="http://www.test.pl:80"/>-->
+</condition>
+</rule>
+</policy>
+</policy-set>
+
+</policy-set>
--- /dev/null
+<policy-set id="Policy-1">
+
+<policy>
+ <target>
+<!--
+ <subject>
+ <subject-match attr="id" match="analogclock"/>
+ </subject>
+-->
+ </target>
+ <rule effect="permit">
+ <condition>
+ <!--
+ <resource-match attr="resource-id">
+ api.appconfig
+ </resource-match>
+ <resource-match attr="device-cap">
+ api.appconfig
+ </resource-match>
+ -->
+ </condition>
+ </rule>
+</policy>
+
+
+</policy-set>
\ No newline at end of file
--- /dev/null
+<policy-set combine="deny-overrides" >
+ <policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s25.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+
+ <policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s25.3</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <subject-match attr="version" match="9"/>
+ </condition>
+
+
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+
+ <!--- test 25.4 (old name: test 107 c U -->
+ <policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s25.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+
+
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+
+
+
+ <!--- test 26.1 (old name: test 108 U -->
+ <policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s26.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+
+
+ <!--- test 26.2 (old name: test 108 a U -->
+ <policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s26.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+
+
+ <!--- test 26.3 (old name: test 108 b U -->
+ <policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s26.3</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+
+ <!--- test 26.4 (old name: test 108 c U -->
+ <policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s26.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+
+
+
+ <!--- test 27.1 (old name: test 109 U -->
+ <policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s27.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+
+ <!--- test 27.2 (old name: test 109a U -->
+ <policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s27.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+
+ <!--- test 27.3 (old name: test 109b U -->
+ <policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s27.3</subject-match>
+ <subject-match attr="version" match="5"/>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+
+
+
+ <!--- test 27.4 (old name: test 109c U -->
+ <policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s27.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+
+
+
+ <!--- test 28 (old name: test 110 U -->
+ <policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s28</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+
+
+ <!--- test 29 (old name: test 111 U -->
+ <policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s29</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+
+ <!--- test 30.1 (old name: test 112 U -->
+ <policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s30.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+
+
+ <!--- test 30.2 (old name: test 112a U -->
+ <policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s30.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+
+
+ <!--- test 30.3 (old name: test 112b U -->
+ <policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s30.3</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+
+ <!--- test 30.4 (old name: test 112c U -->
+ <policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s30.4</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ </policy-set>
+
+
+
+ <!--- test 31.1 (old name: test 113 U -->
+ <policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s31.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+
+
+
+ <!--- test 31.2.1 (old name: test 113a U -->
+ <policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s31.2.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+
+
+ <!--- test 31.2.2 (old name: test 113aa U -->
+ <policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s31.2.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+
+
+ <!--- test 31.3 (old name: test 113b U -->
+ <policy-set combine="deny-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s31.3</subject-match>
+ </subject>
+ </target>
+
+
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ </policy-set>
+
+ <!--- test 32.1 (old name: test 114 U -->
+ <policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s32.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+
+
+ <!--- test 32.2.1 (old name: test 114a U -->
+ <policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s32.2.1</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+
+ <!--- test 32.2.2 (old name: test 114aa U -->
+ <policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s32.2.2</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+
+ <!--- test 32.3 (old name: test 114b U -->
+ <policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s32.3</subject-match>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="deny">
+ <condition combine="or">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+
+ <policy>
+ <rule effect="deny">
+ <condition combine="and">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+
+
+ <!--- test 33.1 (old name: test 115 U -->
+ <policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s33.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+
+
+ <!--- test 33.2 (old name: test 115a U -->
+ <policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s33.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+
+
+ <!--- test 33.3 (old name: test 115b U -->
+ <policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s33.3</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="or">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+
+
+ <!--- test 34.1 (old name: test 116 U -->
+ <policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s34.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="permit-overrides">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+
+ <!--- test 34.2 (old name: test 116 a U -->
+ <policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s34.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="permit-overrides">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+
+
+
+ <!--- test 35.1 (old name: test 117 U -->
+ <policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s35.1</subject-match>
+ </subject>
+ </target>
+ <policy combine="deny-overrides">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+
+
+ <!--- test 35.2 (old name: test 117 a U -->
+ <policy-set combine="permit-overrides">
+ <target>
+ <subject>
+ <subject-match attr="id">s35.2</subject-match>
+ </subject>
+ </target>
+ <policy combine="deny-overrides">
+ <rule effect="deny">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device"/>
+ <subject-match attr="version" match="5"/>
+
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+
+ <policy-set>
+ <target>
+ <subject>
+ <subject-match attr="id">org.tizen.widget.analogclock</subject-match>
+ </subject>
+ </target>
+ <policy combine="first-applicable">
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="http://helloheloo/"/>
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+
+
+ <!--- test 36 (old name: test 102 U -->
+ <policy-set combine="first-matching-target">
+ <target>
+ <subject>
+ <subject-match attr="id">s36</subject-match>
+ <subject-match attr="version" match="5"/>
+ </subject>
+ </target>
+ <policy>
+ <rule effect="permit">
+ <condition combine="and">
+ <resource-match attr="resource-id" match="device:pim.contacts"/>
+ <subject-match attr="version" match="5"/>
+ </condition>
+ </rule>
+ </policy>
+ </policy-set>
+
+</policy-set>
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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
+#
+
+#
+# Test files
+#
+# Define all DPL tests sources.
+# Runner is responsible for runnint it all and
+# generating proper output files
+#
+
+SET(TARGET_NAME "dpl-tests-core")
+
+# Set DPL tests sources
+SET(DPL_TESTS_SOURCES
+ ${PROJECT_SOURCE_DIR}/tests/core/main.cpp
+ ${PROJECT_SOURCE_DIR}/tests/core/test_address.cpp
+ ${PROJECT_SOURCE_DIR}/tests/core/test_binary_queue.cpp
+ ${PROJECT_SOURCE_DIR}/tests/core/test_foreach.cpp
+ ${PROJECT_SOURCE_DIR}/tests/core/test_fast_delegate.cpp
+ ${PROJECT_SOURCE_DIR}/tests/core/test_log_unhandled_exception.cpp
+ ${PROJECT_SOURCE_DIR}/tests/core/test_once.cpp
+ ${PROJECT_SOURCE_DIR}/tests/core/test_serialization.cpp
+ ${PROJECT_SOURCE_DIR}/tests/core/test_scoped_array.cpp
+ ${PROJECT_SOURCE_DIR}/tests/core/test_scoped_close.cpp
+ ${PROJECT_SOURCE_DIR}/tests/core/test_scoped_fclose.cpp
+ ${PROJECT_SOURCE_DIR}/tests/core/test_scoped_free.cpp
+ ${PROJECT_SOURCE_DIR}/tests/core/test_scoped_ptr.cpp
+ ${PROJECT_SOURCE_DIR}/tests/core/test_semaphore.cpp
+ ${PROJECT_SOURCE_DIR}/tests/core/test_shared_ptr.cpp
+ ${PROJECT_SOURCE_DIR}/tests/core/test_string.cpp
+ ${PROJECT_SOURCE_DIR}/tests/core/test_task.cpp
+ ${PROJECT_SOURCE_DIR}/tests/core/test_thread.cpp
+ ${PROJECT_SOURCE_DIR}/tests/core/test_type_list.cpp
+ ${PROJECT_SOURCE_DIR}/tests/core/test_zip_input.cpp
+)
+
+INCLUDE_DIRECTORIES(
+ ${SYS_EFL_INCLUDE_DIRS}
+ ${DPL_TEST_INCLUDE_DIR}
+)
+
+LINK_DIRECTORIES(${SYS_EFL_LIBRARY_DIRS})
+
+ADD_EXECUTABLE(${TARGET_NAME} ${DPL_TESTS_SOURCES})
+
+TARGET_LINK_LIBRARIES(
+ ${TARGET_NAME}
+ ${SYS_EFL_LIBRARIES}
+ ${TARGET_DPL_EFL}
+ ${TARGET_DPL_TEST_ENGINE_EFL}
+)
+
+SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES
+ BUILD_WITH_INSTALL_RPATH ON
+ INSTALL_RPATH_USE_LINK_PATH ON
+)
+
+INSTALL(TARGETS ${TARGET_NAME}
+ DESTINATION bin
+ PERMISSIONS OWNER_READ
+ OWNER_WRITE
+ OWNER_EXECUTE
+ GROUP_READ
+ GROUP_EXECUTE
+ WORLD_READ
+ WORLD_EXECUTE
+)
+
+INSTALL(FILES
+ ${PROJECT_SOURCE_DIR}/tests/core/data/sample.zip
+ DESTINATION /opt/apps/wrt/wrt-commons/tests/core
+)
\ No newline at end of file
--- /dev/null
+!!!options!!! stop
+Test code
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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);
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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)
+
+RUNNER_TEST(Address_InitialEmpty)
+{
+ DPL::Address address;
+ RUNNER_ASSERT(address.ToString() == ":0");
+}
+
+RUNNER_TEST(Address_InitialAddress)
+{
+ DPL::Address address("www.sample.com");
+ RUNNER_ASSERT(address.ToString() == "www.sample.com:0");
+}
+
+RUNNER_TEST(Address_InitialAddressPort)
+{
+ DPL::Address address("www.somewhere.com", 8080);
+ RUNNER_ASSERT(address.ToString() == "www.somewhere.com:8080");
+}
+
+RUNNER_TEST(Address_Getters)
+{
+ DPL::Address address("www.somewhere.com", 8080);
+ RUNNER_ASSERT(address.GetAddress() == "www.somewhere.com");
+ RUNNER_ASSERT(address.GetPort() == 8080);
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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;
+}
+
+RUNNER_TEST(BinaryQueue_InitialEmpty)
+{
+ DPL::BinaryQueue queue;
+ RUNNER_ASSERT(queue.Empty() == true);
+}
+
+RUNNER_TEST(BinaryQueue_InitialSize)
+{
+ DPL::BinaryQueue queue;
+ RUNNER_ASSERT(queue.Size() == 0);
+}
+
+RUNNER_TEST(BinaryQueue_InitialCopy)
+{
+ DPL::BinaryQueue queue;
+ DPL::BinaryQueue copy = queue;
+
+ RUNNER_ASSERT(copy.Size() == 0);
+}
+
+RUNNER_TEST(BinaryQueue_InitialConsumeZero)
+{
+ DPL::BinaryQueue queue;
+ queue.Consume(0);
+}
+
+RUNNER_TEST(BinaryQueue_InitialFlattenConsumeZero)
+{
+ DPL::BinaryQueue queue;
+ queue.FlattenConsume(NULL, 0);
+}
+
+RUNNER_TEST(BinaryQueue_InitialFlattenZero)
+{
+ DPL::BinaryQueue queue;
+ queue.Flatten(NULL, 0);
+}
+
+RUNNER_TEST(BinaryQueue_InitialConsumeOne)
+{
+ DPL::BinaryQueue queue;
+
+ Try
+ {
+ queue.Consume(1);
+ }
+ Catch (DPL::BinaryQueue::Exception::OutOfData)
+ {
+ return;
+ }
+
+ RUNNER_FAIL;
+}
+
+RUNNER_TEST(BinaryQueue_InitialFlattenConsumeOne)
+{
+ DPL::BinaryQueue queue;
+
+ Try
+ {
+ char data;
+ queue.FlattenConsume(&data, 1);
+ }
+ Catch (DPL::BinaryQueue::Exception::OutOfData)
+ {
+ return;
+ }
+
+ RUNNER_FAIL;
+}
+
+RUNNER_TEST(BinaryQueue_InitialFlattenOne)
+{
+ DPL::BinaryQueue queue;
+
+ Try
+ {
+ char data;
+ queue.Flatten(&data, 1);
+ }
+ Catch (DPL::BinaryQueue::Exception::OutOfData)
+ {
+ return;
+ }
+
+ RUNNER_FAIL;
+}
+
+RUNNER_TEST(BinaryQueue_ZeroCopyFrom)
+{
+ DPL::BinaryQueue queue;
+ DPL::BinaryQueue copy;
+
+ copy.AppendCopyFrom(queue);
+ RUNNER_ASSERT(queue.Empty());
+}
+
+RUNNER_TEST(BinaryQueue_ZeroMoveFrom)
+{
+ DPL::BinaryQueue queue;
+ DPL::BinaryQueue copy;
+
+ copy.AppendMoveFrom(queue);
+ RUNNER_ASSERT(queue.Empty());
+}
+
+RUNNER_TEST(BinaryQueue_ZeroCopyTo)
+{
+ DPL::BinaryQueue queue;
+ DPL::BinaryQueue copy;
+
+ queue.AppendCopyTo(copy);
+ RUNNER_ASSERT(queue.Empty());
+}
+
+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");
+}
+
+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) == "");
+}
+
+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");
+}
+
+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");
+}
+
+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");
+}
+
+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");
+}
+
+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");
+}
+
+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;
+ }
+};
+
+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);
+}
+
+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");
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_fast_delegate.cpp
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of fast delegate tests.
+ */
+#include <dpl/test/test_runner.h>
+#include <dpl/fast_delegate.h>
+#include <dpl/log/log.h>
+
+RUNNER_TEST_GROUP_INIT(DPL)
+
+// Sample copied and adopted from
+// http://www.codeproject.com/KB/cpp/FastDelegate.aspx
+//
+// Demonstrate the syntax for FastDelegates.
+// -Don Clugston, May 2004.
+// It's a really boring example, but it shows the most important cases.
+// Declare some functions of varying complexity...
+void SimpleStaticFunction(int num, const char *str);
+void SimpleStaticFunction(int num, const char *str)
+{
+ LogDebug("In SimpleStaticFunction. Num=" << num << ", str =" << str);
+}
+
+void SimpleVoidFunction();
+void SimpleVoidFunction()
+{
+ LogDebug("In SimpleVoidFunction with no parameters.");
+}
+
+class CBaseClass
+{
+protected:
+ const char *m_name;
+
+public:
+ CBaseClass(const char *name)
+ : m_name(name)
+ {
+ }
+
+ virtual ~CBaseClass()
+ {
+ }
+
+ void SimpleMemberFunction(int num, const char *str)
+ {
+ LogDebug("In SimpleMemberFunction in " << m_name << ". Num="
+ << num << ", str = " << str);
+ }
+
+ int SimpleMemberFunctionReturnsInt(int num, const char *str)
+ {
+ LogDebug("In SimpleMemberFunctionReturnsInt in " << m_name << ". Num="
+ << num << ", str = " << str);
+ return -1;
+ }
+
+ void ConstMemberFunction(int num, const char *str) const
+ {
+ LogDebug("In ConstMemberFunction in " << m_name << ". Num="
+ << num << ", str = " << str);
+ }
+
+ virtual void SimpleVirtualFunction(int num, const char *str)
+ {
+ LogDebug("In SimpleVirtualFunction in " << m_name << ". Num="
+ << num << ", str = " << str);
+ }
+
+ static void StaticMemberFunction(int num, const char *str)
+ {
+ LogDebug("In StaticMemberFunction Num="
+ << num << ", str = " << str);
+ }
+};
+
+class COtherClass
+{
+ double rubbish; // to ensure this class has non-zero size.
+
+public:
+ virtual ~COtherClass()
+ {
+ }
+
+ virtual void UnusedVirtualFunction(void)
+ {
+ }
+ virtual void TrickyVirtualFunction(int num, const char *str) = 0;
+};
+
+class VeryBigClass
+{
+ int letsMakeThingsComplicated[400];
+};
+
+// This declaration ensures that we get a convoluted class heirarchy.
+class CDerivedClass
+ : public VeryBigClass,
+ virtual public COtherClass,
+ virtual public CBaseClass
+{
+ double m_somemember[8];
+
+public:
+ CDerivedClass()
+ : CBaseClass("Base of Derived")
+ {
+ m_somemember[0] = 1.2345;
+ }
+
+ void SimpleDerivedFunction(int num, const char *str)
+ {
+ LogDebug("In SimpleDerivedFunction Num="
+ << num << ", str = " << str);
+ }
+
+ virtual void AnotherUnusedVirtualFunction(int num, const char *str)
+ {
+ LogDebug("In AnotherUnusedVirtualFunction in " << m_name << ". Num="
+ << num << ", str = " << str);
+ }
+
+ virtual void TrickyVirtualFunction(int num, const char *str)
+ {
+ LogDebug("In TrickyVirtualFunction in " << m_name << ". Num="
+ << num << ", str = " << str);
+ }
+};
+
+RUNNER_TEST(FastDelegate_Test)
+{
+ // Delegates with up to 8 parameters are supported.
+ // Here's the case for a void function.
+ // We declare a delegate and attach it to SimpleVoidFunction()
+ DPL::FastDelegate0<> noparameterdelegate(&SimpleVoidFunction);
+
+ // invoke the delegate - this calls SimpleVoidFunction()
+ noparameterdelegate();
+
+ LogDebug("-- Examples using two-parameter delegates (int, char *) --");
+
+ // By default, the return value is void.
+ typedef DPL::FastDelegate2<int, const char *> MyDelegate;
+
+ // If you want to have a non-void return value, put it at the end.
+ typedef DPL::FastDelegate2<int, const char *, int> IntMyDelegate;
+
+
+ MyDelegate funclist[12]; // delegates are initialized to empty
+ CBaseClass a("Base A");
+ CBaseClass b("Base B");
+ CDerivedClass d;
+ CDerivedClass c;
+
+ IntMyDelegate newdeleg;
+ newdeleg = DPL::MakeDelegate(&a,
+ &CBaseClass::SimpleMemberFunctionReturnsInt);
+
+ // Binding a simple member function
+ funclist[0].bind(&a, &CBaseClass::SimpleMemberFunction);
+
+ // You can also bind static (free) functions
+ funclist[1].bind(&SimpleStaticFunction);
+
+ // and static member functions
+ funclist[2].bind(&CBaseClass::StaticMemberFunction);
+
+ // and const member functions (these only need a const class pointer).
+ funclist[3].bind((const CBaseClass *) &a,
+ &CBaseClass::ConstMemberFunction);
+
+ funclist[4].bind(&a, &CBaseClass::ConstMemberFunction);
+
+ // and virtual member functions
+ funclist[5].bind(&b, &CBaseClass::SimpleVirtualFunction);
+
+ // You can also use the = operator. For static functions, a fastdelegate
+ // looks identical to a simple function pointer.
+ funclist[6] = &CBaseClass::StaticMemberFunction;
+
+ // The weird rule about the class of derived member function pointers
+ // is avoided. For MSVC, you can use &CDerivedClass::SimpleVirtualFunction
+ // here, but DMC will complain. Note that as well as .bind(), you can also
+ // use the MakeDelegate() global function.
+ funclist[7] = DPL::MakeDelegate(&d, &CBaseClass::SimpleVirtualFunction);
+
+ // The worst case is an abstract virtual function of a virtually-derived
+ // class with at least one non-virtual base class. This is a VERY obscure
+ // situation, which you're unlikely to encounter in the real world.
+ // FastDelegate versions prior to 1.3 had problems with this case on VC6.
+ // Now, it works without problems on all compilers.
+ funclist[8].bind(&c, &CDerivedClass::TrickyVirtualFunction);
+
+ // BUT... in such cases you should be using the base class as an
+ // interface, anyway.
+ funclist[9].bind(&c, &COtherClass::TrickyVirtualFunction);
+
+ // Calling a function that was first declared in the derived class is
+ // straightforward
+ funclist[10] = DPL::MakeDelegate(&c, &CDerivedClass::SimpleDerivedFunction);
+
+ // You can also bind directly using the constructor
+ MyDelegate dg(&b, &CBaseClass::SimpleVirtualFunction);
+
+ const char *msg = "Looking for equal delegate";
+
+ for (int i = 0; i < 12; i++)
+ {
+ LogDebug(i << ":");
+
+ // The == and != operators are provided
+ // Note that they work even for inline functions.
+ if (funclist[i] == dg)
+ {
+ msg = "Found equal delegate";
+ }
+
+ // operator ! can be used to test for an empty delegate
+ // You can also use the .empty() member function.
+ if (!funclist[i])
+ {
+ LogDebug("Delegate is empty");
+ }
+ else
+ {
+ // Invocation generates optimal assembly code.
+ funclist[i](i, msg);
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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;
+}
+
+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);
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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";}
+};
+
+RUNNER_TEST(Log_Unknown_Exception)
+{
+ UNHANDLED_EXCEPTION_HANDLER_BEGIN
+ {
+// throw MyException();
+ }
+ UNHANDLED_EXCEPTION_HANDLER_END
+ RUNNER_ASSERT(true);
+}
+
+RUNNER_TEST(Log_DPL_Exception)
+{
+ UNHANDLED_EXCEPTION_HANDLER_BEGIN
+ {
+// Throw(MyDPLException::MyException);
+ }
+ UNHANDLED_EXCEPTION_HANDLER_END
+ RUNNER_ASSERT(true);
+}
+
+RUNNER_TEST(Log_STD_Exception)
+{
+ UNHANDLED_EXCEPTION_HANDLER_BEGIN
+ {
+// throw MySTDException();
+ }
+ UNHANDLED_EXCEPTION_HANDLER_END
+ RUNNER_ASSERT(true);
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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/shared_ptr.h>
+#include <dpl/atomic.h>
+
+RUNNER_TEST_GROUP_INIT(DPL)
+
+namespace // anonymous
+{
+gint g_counter;
+
+void Delegate()
+{
+ ++g_counter;
+}
+} // namespace anonymous
+
+RUNNER_TEST(Once_DoubleCall)
+{
+ g_counter = 0;
+
+ DPL::Once once;
+
+ once.Call(&Delegate);
+ once.Call(&Delegate);
+
+ RUNNER_ASSERT_MSG(g_counter == 1, "Counter value is: " << g_counter);
+}
+
+class MyThread
+ : public DPL::Thread
+{
+protected:
+ virtual int ThreadEntry()
+ {
+ DPL::WaitForSingleHandle(m_event->GetHandle());
+ m_once->Call(DPL::Once::Delegate(this, &MyThread::Call));
+ 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;
+};
+
+RUNNER_TEST(Once_MultiThreadCall)
+{
+ const size_t NUM_THREADS = 20;
+ typedef DPL::SharedPtr<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);
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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)
+
+RUNNER_TEST(ScopedArray_Zero)
+{
+ DPL::ScopedArray<char> array;
+
+ RUNNER_ASSERT(!array);
+ RUNNER_ASSERT(!!!array);
+}
+
+RUNNER_TEST(ScopedArray_NonZero)
+{
+ DPL::ScopedArray<char> array(new char[7]);
+
+ RUNNER_ASSERT(array);
+ RUNNER_ASSERT(!!array);
+}
+
+RUNNER_TEST(ScopedArray_Reset)
+{
+ DPL::ScopedArray<char> array(new char[7]);
+ array.Reset();
+
+ RUNNER_ASSERT(!array);
+
+ array.Reset(new char);
+ RUNNER_ASSERT(array);
+}
+
+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);
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
+
+RUNNER_TEST(ScopedFClose_Zero)
+{
+ DPL::ScopedFClose file;
+
+ RUNNER_ASSERT(!file);
+ RUNNER_ASSERT(!!!file);
+}
+
+RUNNER_TEST(ScopedFClose_NonZero)
+{
+ DPL::ScopedFClose file(MakeTmp());
+
+ RUNNER_ASSERT(file);
+ RUNNER_ASSERT(!!file);
+}
+
+RUNNER_TEST(ScopedFClose_Reset)
+{
+ DPL::ScopedFClose file(MakeTmp());
+ file.Reset();
+
+ RUNNER_ASSERT(!file);
+
+ file.Reset(MakeTmp());
+ RUNNER_ASSERT(file);
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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)
+
+RUNNER_TEST(ScopedFree_Zero)
+{
+ DPL::ScopedFree<void> free;
+
+ RUNNER_ASSERT(!free);
+ RUNNER_ASSERT(!!!free);
+}
+
+RUNNER_TEST(ScopedFree_NonZero)
+{
+ DPL::ScopedFree<void> free(malloc(7));
+
+ RUNNER_ASSERT(free);
+ RUNNER_ASSERT(!!free);
+}
+
+RUNNER_TEST(ScopedFree_Reset)
+{
+ DPL::ScopedFree<void> free(malloc(7));
+ free.Reset();
+
+ RUNNER_ASSERT(!free);
+
+ free.Reset(malloc(8));
+ RUNNER_ASSERT(free);
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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)
+
+RUNNER_TEST(ScopedPtr_Zero)
+{
+ DPL::ScopedPtr<char> ptr;
+
+ RUNNER_ASSERT(!ptr);
+ RUNNER_ASSERT(!!!ptr);
+}
+
+RUNNER_TEST(ScopedPtr_NonZero)
+{
+ DPL::ScopedPtr<char> ptr(new char(7));
+
+ RUNNER_ASSERT(ptr);
+ RUNNER_ASSERT(!!ptr);
+}
+
+RUNNER_TEST(ScopedPtr_Reset)
+{
+ DPL::ScopedPtr<char> ptr(new char(7));
+ ptr.Reset();
+
+ RUNNER_ASSERT(!ptr);
+
+ ptr.Reset(new char);
+ RUNNER_ASSERT(ptr);
+}
+
+RUNNER_TEST(ScopedPtr_Operators)
+{
+ DPL::ScopedPtr<char> ptr(new char(7));
+
+ RUNNER_ASSERT(*ptr == *ptr.Get());
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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;
+ }
+};
+
+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);
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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)
+ {
+ 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;
+};
+
+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);
+}
+
+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;
+}
+
+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);
+}
+
+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;
+}
+
+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));
+}
+
+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);
+}
+
+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]));
+ }
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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)
+
+RUNNER_TEST(SharedPtr_Zero)
+{
+ DPL::SharedPtr<char> ptr;
+
+ RUNNER_ASSERT(!ptr);
+ RUNNER_ASSERT(!!!ptr);
+ RUNNER_ASSERT(ptr == DPL::SharedPtr<char>());
+}
+
+RUNNER_TEST(SharedPtr_NonZero)
+{
+ DPL::SharedPtr<char> ptr(new char(7));
+
+ RUNNER_ASSERT(ptr);
+ RUNNER_ASSERT(!!ptr);
+ RUNNER_ASSERT(ptr != DPL::SharedPtr<char>());
+}
+
+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);
+}
+
+RUNNER_TEST(SharedPtr_Reset)
+{
+ DPL::SharedPtr<char> ptr(new char(7));
+ ptr.Reset();
+
+ RUNNER_ASSERT(!ptr);
+
+ ptr.Reset(new char);
+ RUNNER_ASSERT(ptr);
+}
+
+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);
+}
+
+RUNNER_TEST(SharedPtr_Operators)
+{
+ DPL::SharedPtr<char> ptr(new char(7));
+
+ RUNNER_ASSERT(*ptr == *ptr.Get());
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <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, nbytesdecoded + 1, 0);
+
+ 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=";
+
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+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");
+}
+
+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);
+}
+
+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);
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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/test_runner.h>
+#include <dpl/task.h>
+#include <dpl/log/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()
+ {
+ LogInfo("Step one");
+ }
+
+ void StepTwo()
+ {
+ LogInfo("Step two");
+ }
+
+ void StepThree()
+ {
+ LogInfo("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());
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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)
+ {
+ LogInfo("Foo: ctor: " << id);
+ }
+
+ ~Foo()
+ {
+ LogInfo("Foo: dtor: " << id);
+ g_wasFooDeleted = true;
+ }
+
+ void Bar()
+ {
+ LogInfo("Foo: bar");
+ }
+};
+
+typedef DPL::ThreadLocalVariable<Foo> TlsFoo;
+TlsFoo g_foo;
+
+class FooThread
+ : public DPL::Thread
+{
+protected:
+ virtual int ThreadEntry()
+ {
+ LogInfo("In thread");
+
+ RUNNER_ASSERT(!g_foo);
+ RUNNER_ASSERT(g_foo.IsNull());
+
+ g_foo = Foo();
+ g_foo->Bar();
+
+ return 0;
+ }
+};
+
+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());
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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)
+
+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);
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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/apps/wrt/wrt-commons/tests/core/no_such_file";
+const char* PATH_ARCHIVE = "/opt/apps/wrt/wrt-commons/tests/core/sample.zip";
+const char* ARCHIVED_FILE = "sample.txt";
+}
+
+RUNNER_TEST_GROUP_INIT(DPL)
+
+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);
+}
+
+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(version);
+ FIELD(versionNeeded);
+ FIELD(flag);
+ FIELD(compressionMethod);
+ FIELD(dosDate);
+ FIELD(crc);
+ FIELD(compressedSize);
+ FIELD(uncompressedSize);
+ FIELD(diskNumberStart);
+ FIELD(internalFileAttributes);
+ FIELD(externalFileAttributes);
+#undef FIELD
+ }
+}
+
+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");
+}
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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 "dpl-tests-db")
+
+# Set DPL tests sources
+SET(DPL_TESTS_SOURCES
+ ${PROJECT_SOURCE_DIR}/tests/db/main.cpp
+ ${PROJECT_SOURCE_DIR}/tests/db/test_orm.cpp
+ ${PROJECT_SOURCE_DIR}/tests/db/test_sql_connection.cpp
+)
+
+ADD_SUBDIRECTORY(orm)
+
+INCLUDE_DIRECTORIES(
+ ${SYS_EFL_INCLUDE_DIRS}
+ ${DPL_TEST_INCLUDE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/orm
+)
+
+LINK_DIRECTORIES(${SYS_EFL_LIBRARY_DIRS})
+
+ADD_EXECUTABLE(${TARGET_NAME} ${DPL_TESTS_SOURCES})
+
+TARGET_LINK_LIBRARIES(
+ ${TARGET_NAME}
+ ${TARGET_DPL_EFL}
+ ${TARGET_DPL_DB_EFL}
+ ${TARGET_DPL_TEST_ENGINE_EFL}
+)
+
+SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES
+ BUILD_WITH_INSTALL_RPATH ON
+ INSTALL_RPATH_USE_LINK_PATH ON
+)
+
+INSTALL(TARGETS ${TARGET_NAME}
+ DESTINATION bin
+ PERMISSIONS OWNER_READ
+ OWNER_WRITE
+ OWNER_EXECUTE
+ GROUP_READ
+ GROUP_EXECUTE
+ WORLD_READ
+ WORLD_EXECUTE
+)
+
+INSTALL(FILES
+ ${PROJECT_SOURCE_DIR}/tests/db/orm/dpl_orm_test.db
+ DESTINATION /opt/apps/wrt/wrt-commons/tests/db
+)
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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);
+}
--- /dev/null
+
+ADD_CUSTOM_COMMAND( OUTPUT dpl_orm_test_db.sql
+ COMMAND rm -f ${CMAKE_CURRENT_SOURCE_DIR}/dpl_orm_test.db
+ COMMAND gcc -Wall -I${DPL_DB_INCLUDE_DIR} -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 )
--- /dev/null
+
+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");
+)
--- /dev/null
+
+
+
+
+CREATE TABLE TestTableInsert (
+ ColumnOptInt INT ,
+ ColumnOptText TEXT ,
+ ColumnInt INT DEFAULT 99 not null,
+ ColumnInt2 INT not null,
+ ColumnText TEXT not null,
+CHECK(1) );
+
+CREATE TABLE TestTableDelete (
+ ColumnOptInt INT ,
+ ColumnOptText TEXT ,
+ ColumnInt INT DEFAULT 99 not null,
+ ColumnInt2 INT not null,
+ ColumnText TEXT not null,
+CHECK(1) );
+
+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 (
+ ColumnOptInt INT ,
+ ColumnOptText TEXT ,
+ ColumnInt INT DEFAULT 99 not null,
+ ColumnInt2 INT not null,
+ ColumnText TEXT not null,
+CHECK(1) );
+
+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");
+
+
--- /dev/null
+DATABASE_START(dpl_orm_test)
+
+#include "dpl_orm_test_db"
+
+DATABASE_END()
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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"
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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>
+
+namespace {
+const char* PATH_DB = "/opt/apps/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();
+ }
+ }
+
+ ~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)
+
+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);
+ }
+}
+
+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);
+ }
+}
+
+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));
+ }
+}
+
+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)));
+ }
+}
+
+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();
+ }
+}
+
+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.size() == 0, "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);
+ }
+}
+
+RUNNER_TEST(ORM_MultipleBindInsert)
+{
+ for ( int i = 0 ; i < TEST_REPETITION ; i++ )
+ {
+ ORM_Insert();
+ }
+}
+
+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("ColumnInt2 ASC");
+ 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.");
+ }
+
+}
+
+RUNNER_TEST(ORM_MultipleBindDelete)
+{
+ for ( int i = 0 ; i < TEST_REPETITION ; i++ )
+ {
+ ORM_Delete();
+ }
+}
+
+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);
+
+ }
+
+}
+
+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);
+ }
+}
+
+RUNNER_TEST(ORM_MultipleBindUpdate)
+{
+ for ( int i = 0 ; i < TEST_REPETITION ; i++ )
+ {
+ ORM_Update();
+ }
+}
+
+RUNNER_TEST(ORM_transactions)
+{
+ SmartAttach interface;
+ DPL::DB::ORM::dpl_orm_test::ScopedTransaction transaction(interface.get());
+}
+
+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.");
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <dpl/shared_ptr.h>
+#include <dpl/log/log.h>
+#include <sstream>
+#include <string>
+#include <cstdlib>
+#include <ctime>
+
+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,
+ 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 DPL::SharedPtr<DPL::Thread> ThreadPtr;
+
+void MassiveReadWriteTest(AbstractSynchronizationObjectGenerator *generator)
+{
+ std::ostringstream dbFileNameStream;
+ dbFileNameStream << "/tmp/dpl_tests_db_";
+ dbFileNameStream << rand() << ".db";
+
+ std::string dbFileName = dbFileNameStream.str();
+
+ LogDebug("Temporary database used: " << dbFileName);
+
+ DPL::DB::SqlConnection connection(dbFileName);
+ connection.ExecCommand("BEGIN TRANSACTION;");
+ connection.ExecCommand("CREATE TABLE test(value TEXT);");
+ connection.ExecCommand("COMMIT;");
+
+ 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, dbFileName, generator));
+
+ stressGenerators[i]->Run();
+ }
+
+ for (size_t i = 0; i < STRESS_GENERATOR_COUNT; ++i)
+ stressGenerators[i]->Quit();
+
+ unlink(dbFileName.c_str());
+}
+
+RUNNER_TEST(SqlConnection_MassiveReadWrite_NaiveSynchronization)
+{
+ srand(time(NULL));
+
+ NaiveSynchronizationObjectGenerator m_generator;
+ MassiveReadWriteTest(&m_generator);
+}
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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
+#
+
+INCLUDE(FindPkgConfig)
+
+SET(TARGET_DBUS_TESTS "dpl-tests-dbus")
+SET(TARGET_DBUS_TEST_SERVICE "dpl-dbus-test-service")
+
+PKG_CHECK_MODULES(DBUS_PKG
+ ecore
+ appcore-efl
+ gio-2.0
+ gobject-2.0
+ REQUIRED
+)
+
+SET(DBUS_TESTS_SRCS
+ ${PROJECT_SOURCE_DIR}/tests/dbus/main.cpp
+ ${PROJECT_SOURCE_DIR}/tests/dbus/test_cases.cpp
+ ${PROJECT_SOURCE_DIR}/tests/dbus/dbus_test.cpp
+ ${PROJECT_SOURCE_DIR}/tests/dbus/loop_control.cpp
+)
+
+SET(DBUS_TEST_SERVICE_SRCS
+ ${PROJECT_SOURCE_DIR}/tests/dbus/test_service.cpp
+ ${PROJECT_SOURCE_DIR}/tests/dbus/loop_control.cpp
+)
+
+INCLUDE_DIRECTORIES(
+ ${DBUS_PKG_INCLUDE_DIRS}
+ ${DPL_TEST_INCLUDE_DIR}
+)
+
+LINK_DIRECTORIES(${DBUS_PKG_LIBRARY_DIRS})
+
+ADD_EXECUTABLE(${TARGET_DBUS_TESTS}
+ ${DBUS_TESTS_SRCS}
+)
+
+TARGET_LINK_LIBRARIES(${TARGET_DBUS_TESTS}
+ ${DBUS_PKG_LIBRARIES}
+ ${TARGET_DPL_EFL}
+ ${TARGET_DPL_DBUS_EFL}
+ ${TARGET_DPL_TEST_ENGINE_EFL}
+)
+
+SET_TARGET_PROPERTIES(${TARGET_DBUS_TESTS} PROPERTIES
+ BUILD_WITH_INSTALL_RPATH ON
+ INSTALL_RPATH_USE_LINK_PATH ON
+)
+
+ADD_EXECUTABLE(${TARGET_DBUS_TEST_SERVICE}
+ ${DBUS_TEST_SERVICE_SRCS}
+)
+
+TARGET_LINK_LIBRARIES(${TARGET_DBUS_TEST_SERVICE}
+ ${DBUS_PKG_LIBRARIES}
+ ${TARGET_DPL_EFL}
+ ${TARGET_DPL_DBUS_EFL}
+)
+
+SET_TARGET_PROPERTIES(${TARGET_DBUS_TEST_SERVICE} PROPERTIES
+ BUILD_WITH_INSTALL_RPATH ON
+ INSTALL_RPATH_USE_LINK_PATH ON
+)
+
+INSTALL(TARGETS ${TARGET_DBUS_TESTS} ${TARGET_DBUS_TEST_SERVICE}
+ DESTINATION bin
+ PERMISSIONS OWNER_READ
+ OWNER_WRITE
+ OWNER_EXECUTE
+ GROUP_READ
+ GROUP_EXECUTE
+ WORLD_READ
+ WORLD_EXECUTE
+)
+
+INSTALL(FILES
+ ${PROJECT_SOURCE_DIR}/tests/dbus/data/org.tizen.DBusTestService.service
+ DESTINATION /usr/share/dbus-1/services
+)
--- /dev/null
+[D-BUS Service]
+Name=org.tizen.DBusTestService
+Exec=/usr/bin/dpl-dbus-test-service
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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);
+
+ 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
+{
+ Assert(NULL != m_test && "Test not set.");
+
+ return *m_test;
+}
+
+void DBusTestManager::setCurrentTest(DBusTest& test)
+{
+ m_test = &test;
+}
+
+void DBusTestManager::clear()
+{
+ m_test = NULL;
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "loop_control.h"
+#include <dpl/log/log.h>
+
+#include <dpl/framework_efl.h>
+
+#include <glib.h>
+#include <glib-object.h>
+
+
+namespace LoopControl
+{
+void init_loop(int argc, char *argv[])
+{
+ (void)argc;
+ (void)argv;
+ g_type_init();
+ g_thread_init(NULL);
+
+ LogInfo("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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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);
+
+ LogInfo("Running tests...");
+ int status = DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv);
+
+ return status;
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "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(AcquireSessionBus)
+{
+ try
+ {
+ DPL::DBus::Connection::sessionBus();
+ }
+ catch (const DPL::DBus::Exception& ex)
+ {
+ RUNNER_ASSERT_MSG(false, ex.DumpToString());
+ }
+}
+
+RUNNER_TEST(AcquireSystemBus)
+{
+ try
+ {
+ DPL::DBus::Connection::systemBus();
+ }
+ catch (const DPL::DBus::Exception& ex)
+ {
+ RUNNER_ASSERT_MSG(false, ex.DumpToString());
+ }
+}
+
+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());
+ }
+}
+
+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();
+ }
+};
+
+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);
+ }
+ 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());
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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;
+}
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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 "dpl-tests-event")
+
+# Set DPL tests sources
+SET(DPL_TESTS_SOURCES
+ ${PROJECT_SOURCE_DIR}/tests/event/main.cpp
+ ${PROJECT_SOURCE_DIR}/tests/event/test_controller.cpp
+ ${PROJECT_SOURCE_DIR}/tests/event/test_event_support.cpp
+ ${PROJECT_SOURCE_DIR}/tests/event/test_ic_delegate.cpp
+ ${PROJECT_SOURCE_DIR}/tests/event/test_property.cpp
+)
+
+INCLUDE_DIRECTORIES(
+ ${SYS_EFL_INCLUDE_DIRS}
+ ${DPL_TEST_INCLUDE_DIR}
+)
+
+LINK_DIRECTORIES(${SYS_EFL_LIBRARY_DIRS})
+
+ADD_EXECUTABLE(${TARGET_NAME} ${DPL_TESTS_SOURCES})
+
+TARGET_LINK_LIBRARIES(
+ ${TARGET_NAME}
+ ${TARGET_DPL_EFL}
+ ${TARGET_DPL_EVENT_EFL}
+ ${TARGET_DPL_TEST_ENGINE_EFL}
+)
+
+SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES
+ BUILD_WITH_INSTALL_RPATH ON
+ INSTALL_RPATH_USE_LINK_PATH ON
+)
+
+INSTALL(TARGETS ${TARGET_NAME}
+ DESTINATION bin
+ PERMISSIONS OWNER_READ
+ OWNER_WRITE
+ OWNER_EXECUTE
+ GROUP_READ
+ GROUP_EXECUTE
+ WORLD_READ
+ WORLD_EXECUTE
+)
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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);
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <dpl/scoped_ptr.h>
+#include <dpl/shared_ptr.h>
+#include <list>
+#include <vector>
+RUNNER_TEST_GROUP_INIT(DPL)
+
+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; }
+};
+
+RUNNER_TEST(Controller_InitSimple)
+{
+ IntController controller;
+ controller.Touch();
+ RUNNER_ASSERT(controller.Value() == -1);
+}
+
+RUNNER_TEST(Controller_InitStrange)
+{
+ StrangeController controller;
+ controller.Touch();
+}
+
+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);
+}
+
+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();
+ }
+};
+
+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);
+}
+
+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 DPL::SharedPtr<TestController> ControllerPtr;
+typedef DPL::SharedPtr<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 DPL::ScopedPtr<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() % static_cast<int>(testContextPtr->controllers.size());
+ testContextPtr->controllers.at(id)->DPL::Event::ControllerEventHandler<RandomEvent>::PostEvent(RandomEvent());
+ }
+ }
+};
+
+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();
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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/fast_delegate.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(); }
+};
+
+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)
+{
+ LogInfo("Got delegate call");
+ g_delegateTest = k;
+}
+
+class DelegateTestSupport
+ : public DPL::Event::EventSupport<int>
+{
+public:
+ void Test()
+ {
+ EmitEvent(7);
+ }
+};
+
+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);
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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/fast_delegate.h>
+#include <dpl/event/inter_context_delegate.h>
+#include <dpl/thread.h>
+#include <dpl/shared_ptr.h>
+#include <dpl/waitable_event.h>
+#include <dpl/assert.h>
+#include <dpl/mutex.h>
+#include <dpl/type_list.h>
+
+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;
+};
+
+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();
+}
+
+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 DPL::SharedPtr<ICTestController> ICTestControllerPtr;
+typedef DPL::SharedPtr<TestContextFree> TestContextFreePtr;
+typedef DPL::SharedPtr<TestRunnerInThread> TestRunnerInThreadPtr;
+typedef DPL::SharedPtr<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;
+};
+
+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){
+ LogInfo("[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;
+};
+
+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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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, "Foo caption"),
+ Testproperty0(this, "", &ReadSomething),
+ Testproperty1(this),
+ Testproperty2(this),
+ Testproperty3(this),
+ Testproperty4(this, "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;
+}
+
+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);
+}
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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 "dpl-tests-loc")
+
+SET(MAIN_DIR ${PROJECT_SOURCE_DIR}/tests/localization)
+
+SET(LOC_TESTS_SOURCES
+ ${MAIN_DIR}/test_localization.cpp
+ ${MAIN_DIR}/test_suite01.cpp
+ ${MAIN_DIR}/mockup_src/widget_dao.cpp
+ ${PROJECT_SOURCE_DIR}/modules/localization/src/localization_utils.cpp
+ ${PROJECT_SOURCE_DIR}/modules/localization/src/w3c_file_localization.cpp
+)
+
+INCLUDE_DIRECTORIES(
+ ${SYS_EFL_INCLUDE_DIRS}
+ ${DPL_TEST_INCLUDE_DIR}
+ ${MAIN_DIR}/mockup_include
+ ${PROJECT_SOURCE_DIR}/modules/localization/include
+)
+
+LINK_DIRECTORIES(${SYS_EFL_LIBRARY_DIRS})
+
+ADD_EXECUTABLE(${TARGET_LOC} ${LOC_TESTS_SOURCES})
+
+TARGET_LINK_LIBRARIES(
+ ${TARGET_LOC}
+ ${SYS_EFL_LIBRARIES}
+ ${TARGET_DPL_EFL}
+ ${TARGET_DPL_TEST_ENGINE_EFL}
+)
+
+SET_TARGET_PROPERTIES(${TARGET_LOC} PROPERTIES
+ RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin/
+ BUILD_WITH_INSTALL_RPATH ON
+ INSTALL_RPATH_USE_LINK_PATH ON
+)
+
+INSTALL(TARGETS ${TARGET_LOC}
+ DESTINATION bin
+ PERMISSIONS OWNER_READ
+ OWNER_WRITE
+ OWNER_EXECUTE
+ GROUP_READ
+ GROUP_EXECUTE
+ WORLD_READ
+ WORLD_EXECUTE
+ )
+
+ADD_SUBDIRECTORY(files)
--- /dev/null
+INSTALL(FILES
+ ${PROJECT_SOURCE_DIR}/tests/localization/files/one
+ DESTINATION
+ /opt/apps/widget/tests/localization/widget1/locales/pl-en
+ )
+
+INSTALL(FILES
+ ${PROJECT_SOURCE_DIR}/tests/localization/files/one
+ ${PROJECT_SOURCE_DIR}/tests/localization/files/two
+ DESTINATION
+ /opt/apps/widget/tests/localization/widget2/locales/pl-en
+ )
+
+INSTALL(FILES
+ ${PROJECT_SOURCE_DIR}/tests/localization/files/two
+ DESTINATION
+ /opt/apps/widget/tests/localization/widget2/locales/en-en
+ )
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_SRC_CONFIGURATION_COMMON_DAO_TYPES_H_
+#define WRT_SRC_CONFIGURATION_COMMON_DAO_TYPES_H_
+
+#include <set>
+#include <string>
+#include <map>
+#include <vector>
+#include <list>
+#include <dpl/optional_typedefs.h>
+#include <dpl/shared_ptr.h>
+
+namespace WrtDB {
+namespace Powder {
+
+typedef std::set<DPL::String> StringSet;
+//! Widget description
+struct Description
+{
+ //!Content level
+ typedef enum
+ {
+ Level0 = 0,
+ Level1,
+ Level2,
+ Level3,
+ Level4,
+ Level5,
+ LevelUnknown
+ } LevelEnum;
+ struct LevelEntry
+ {
+ LevelEnum level; //!< content level
+
+ typedef StringSet Context;
+
+ //! POWDER context
+ //! xa This material appears in an artistic context
+ //! xb This material appears in an educational context
+ //! xc This material appears in a medical context
+ //! xd This material appears in a sports context
+ //! xe This material appears in a violent context
+ Context context;
+ explicit LevelEntry(LevelEnum level = LevelUnknown);
+ //! Function checks if context is valid
+ //! \param[in] level POWDER content level
+ //! \param[in] context POWDER context
+ bool isContextValid(LevelEnum level,
+ const DPL::OptionalString& context) const;
+ };
+
+ struct CategoryEntry
+ {
+ //! Levels entries for POWDER description
+ typedef std::vector <LevelEntry> LevelsContainer;
+ LevelsContainer levels;
+ //! Function checks if context is valid
+ //! \param[out] reason set if context invalid
+ //! \param[in] level POWDER content level
+ //! \param[in] context POWDER context
+ bool isCategoryValid(LevelEntry& reason,
+ LevelEnum level,
+ const DPL::OptionalString& context) const;
+ };
+
+ //! POWDER Category -> Category entry map for Widget
+ //!
+ //! nu Nudity
+ //! se Sex
+ //! vi Violence
+ //! la Potentially offensive language
+ //! dr Drug use
+ //! ga Gambling
+ //! ha Hate or harmful activities
+ //! ug Use of user-generated content
+ typedef std::map<DPL::String, CategoryEntry> CategoryEntries;
+
+ CategoryEntries categories;
+
+ //! Age rating for widget
+ //! If Null not set
+ DPL::OptionalInt ageRating;
+};
+} // namespace Powder
+
+namespace ChildProtection {
+
+//! Blacklist with forbidden URLs
+//! It should be stored in WidgetDAO
+typedef std::vector<DPL::String> BlackList;
+
+//! Widget Child protection record
+//! Record should be stored in WingetDAO
+struct Record
+{
+ //! Child protection enabled
+ bool enabled;
+ explicit Record(bool enabled) :
+ enabled(enabled)
+ {
+ }
+};
+
+//! Powder processing
+struct PowderRules
+{
+ //! Rule set by parent about forbidden category
+ //! Powder category
+ //! nu Nudity
+ //! se Sex
+ //! vi Violence
+ //! la Potentially offensive language
+ //! dr Drug use
+ //! ga Gambling
+ //! ha Hate or harmful activities
+ //! ug Use of user-generated content
+ //! Powder context
+ //! xa This material appears in an artistic conteaxt
+ //! xb This material appears in an educational context
+ //! xc This material appears in a medical context
+ //! xd This material appears in a sports context
+ //! xe This material appears in a violent context
+ struct CategoryRule
+ {
+ DPL::String category;
+ Powder::Description::LevelEnum level;
+ DPL::OptionalString context;
+ explicit CategoryRule(const DPL::String& category = DPL::String(),
+ Powder::Description::LevelEnum level =
+ Powder::Description::LevelUnknown,
+ const DPL::OptionalString& context = DPL::OptionalString());
+ };
+
+ struct PowderResult
+ {
+ //! Reasoning outcome: part of POWDER description used to invalidate
+ Powder::Description::LevelEntry invalidDescription;
+ //! Reasoning outcome: rule set by parent not full filed by description
+ CategoryRule invalidRule;
+
+ //! Reasoning outcome: type of invalidity
+ enum InvalidReason
+ {
+ InvalidRule, //!< One of rules was not fulfilled
+ InvalidAge, //!< Age is invalid
+ AgeRatingNotSet, //!< Age rating for widget is not set
+ Valid //!< Description valid
+ };
+ InvalidReason reason;
+ explicit PowderResult(InvalidReason reason = Valid,
+ const Powder::Description::LevelEntry& invalidDescription =
+ Powder::Description::LevelEntry(),
+ const CategoryRule& invalidRule = CategoryRule());
+ };
+
+ typedef std::pair<bool, PowderResult> ResultPair;
+
+ //! Function checks if rule is fulfilled by description
+ //! \param[in] rule checked rule
+ //! \param[in] description
+ //! \retval true rule is valid
+ //! \retval false rule is invalid
+ ResultPair isRuleValidForDescription(const CategoryRule& rule,
+ const Powder::Description& description) const;
+ //! Function checks if age limit is fulfilled by description
+ //! \param[in] description
+ //! \retval true age is valid
+ //! \retval false age is invalid
+ ResultPair isAgeValidForDescription(
+ const Powder::Description& description) const;
+
+ //! It is the maximum age rating valid for child
+ //! Uniform age is stored in WidgetDAO
+ DPL::OptionalInt ageLimit;
+
+ //! Set to true if age rating is required
+ //! If ageLimit is not set value is ignored
+ bool isAgeRatingRequired;
+
+ //! Set of rules configured by parent
+ //! Rules are stored in WidgetDAO and are uniform for all widgets
+ typedef std::vector<CategoryRule> RulesContainer;
+ RulesContainer rules;
+
+ //! Function check if Widget description is valid for ChildProtection
+ //! configuration
+ //! \param description widget description
+ //! \retval true widget is valid
+ //! \retval false widget is invalid
+ ResultPair isDescriptionValid(const Powder::Description& description)
+ const;
+
+ PowderRules() :
+ isAgeRatingRequired(false)
+ {
+ }
+};
+} // namespace ChildProtection
+
+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;
+ std::string m_featuresInstallURI;
+ std::string m_featuresKeyCN;
+ std::string m_featuresRootCN;
+ std::string m_featuresRootFingerprint;
+
+ FeatureContainer m_featureContainer;
+};
+
+class PluginObjectsDAO
+{
+ public:
+ typedef std::set<std::string> Objects;
+ typedef DPL::SharedPtr<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;
+
+/**
+ * @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;
+
+typedef std::list<DPL::String> WindowModeList;
+
+/**
+ * @brief Widget configuration parameter key
+ */
+typedef DPL::String WidgetParamKey;
+
+/**
+ * @brief Widget configuration parameter value
+ */
+typedef DPL::String WidgetParamValue;
+
+/**
+ * @brief A map of widget configuration parameters.
+ *
+ * Widget configuration parameters are read from database and are stored
+ * along with feature that they describe.
+ */
+typedef std::multimap<WidgetParamKey, WidgetParamValue> WidgetParamMap;
+
+/**
+ * @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 required; /// Whether feature is required
+ DbPluginHandle pluginId; /// Plugin id that implement this feature
+ WidgetParamMap params; /// Widget's params
+
+ DbWidgetFeature() :
+ required(false),
+ 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.required == featureB.required &&
+ 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;
+
+/**
+ * @brief Widget specific type
+ *
+ * Widget type describes belowed in WAC, TIZEN WebApp
+ */
+enum AppType
+{
+ APP_TYPE_UNKNOWN = 0, // unknown
+ APP_TYPE_WAC10, // WAC 1.0
+ APP_TYPE_WAC20, // WAC 2.0
+ APP_TYPE_TIZENWEBAPP, // slp webapp
+};
+
+class WidgetType
+{
+ public:
+ WidgetType()
+ :appType(APP_TYPE_UNKNOWN)
+ {
+ }
+ WidgetType(const AppType type)
+ :appType(type)
+ {
+ }
+ 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_WAC10)
+ X(APP_TYPE_WAC20)
+ X(APP_TYPE_TIZENWEBAPP)
+#undef X
+ default:
+ return "UNKNOWN";
+ }
+ }
+
+ AppType appType;
+};
+
+} // namespace WrtDB
+
+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 Application Service
+ *
+ * Application sercvice describes details of behaviour
+ * when widget receives aul bundle data.
+ */
+struct WidgetApplicationService
+{
+ public:
+ DPL::String src; /* start uri */
+ DPL::String operation; /* service name */
+ DPL::String scheme; /* scheme type*/
+ DPL::String mime; /* mime type */
+
+ bool operator== (const WidgetApplicationService& other) const
+ {
+ return src == other.src &&
+ operation == other.operation &&
+ scheme == other.scheme &&
+ mime == other.mime;
+ }
+};
+
+typedef std::list<WidgetApplicationService> WidgetApplicationServiceList;
+#endif /* WRT_SRC_CONFIGURATION_COMMON_DAO_TYPES_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <map>
+#include <set>
+#include <string>
+
+#include <dpl/string.h>
+#include <dpl/exception.h>
+#include <dpl/optional_typedefs.h>
+
+#include <dpl/wrt-dao-ro/common_dao_types.h>
+
+typedef DPL::OptionalString WidgetGUID;
+
+namespace ConfigParserData {
+
+struct Icon
+{
+ Icon(const DPL::String& src) : src(src)
+ {
+ }
+ DPL::String src;
+ DPL::OptionalInt width;
+ DPL::OptionalInt height;
+ 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;
+};
+} // namespace ConfigParserData
+namespace WrtDB {
+
+typedef std::list<DPL::String> StringList;
+
+struct WidgetLocalizedInfo
+{
+ DPL::OptionalString name;
+ DPL::OptionalString shortName;
+ DPL::OptionalString description;
+ DPL::OptionalString license;
+ DPL::OptionalString licenseHref;
+};
+
+typedef std::list<DPL::String> LanguageTagList;
+
+class WidgetDAO
+{
+ 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.
+ */
+ WidgetDAO(DbWidgetHandle widgetHandle)
+ : m_widgetHandle(widgetHandle)
+ {}
+
+ /**
+ * Destructor
+ */
+ virtual ~WidgetDAO(){}
+
+ /**
+ * 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 { return m_widgetHandle; }
+ DbWidgetHandle getHandle(const WidgetGUID GUID) const;
+ static DbWidgetHandle getHandle(const DPL::String pkgName);
+
+ /**
+ * 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.
+ */
+ DPL::String getPath() const;
+ void setPath(const DPL::String &path) 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;
+ void setLocalizedStartFileList(const LocalizedStartFileList &list) 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;
+ void setStartFileList(const WidgetStartFileList &list) const;
+
+ WidgetLocalizedInfo getLocalizedInfo(const DPL::String& languageTag) const;
+ protected:
+ static std::map<DbWidgetHandle,WidgetStartFileList> s_startFileMap;
+ static std::map<DbWidgetHandle,LocalizedStartFileList> s_localizedStartFileMap;
+ static std::map<DbWidgetHandle,DPL::String> s_pathMap;
+};
+
+} // namespace WrtDB
+
+#endif // _WRT_SRC_CONFIGURATION_WIDGET_DAO_READ_ONLY_H_
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <dpl/wrt-dao-rw/widget_dao.h>
+
+#include <sstream>
+#include <dpl/foreach.h>
+#include <dpl/log/log.h>
+#include <dpl/sstream.h>
+
+namespace WrtDB {
+
+std::map<DbWidgetHandle,WidgetDAO::WidgetStartFileList> WidgetDAO::s_startFileMap;
+std::map<DbWidgetHandle,WidgetDAO::LocalizedStartFileList> WidgetDAO::s_localizedStartFileMap;
+std::map<DbWidgetHandle,DPL::String> WidgetDAO::s_pathMap;
+
+DbWidgetHandle WidgetDAO::getHandle(const WidgetGUID /* GUID */) const
+{
+ LogError("Not impleneted!");
+ return 0;
+}
+
+DbWidgetHandle WidgetDAO::getHandle(const DPL::String /* pkgName */)
+{
+ LogError("Not implemented!");
+ return 0;
+}
+
+DPL::String WidgetDAO::getPath() const
+{
+ return s_pathMap[m_widgetHandle];
+}
+
+void WidgetDAO::setPath(const DPL::String &path) const
+{
+ s_pathMap[m_widgetHandle] = path;
+}
+
+WidgetLocalizedInfo
+ WidgetDAO::getLocalizedInfo(const DPL::String& /* languageTag */)
+ const
+{
+ LogError("Not implemented!");
+ return WidgetLocalizedInfo();
+}
+
+DPL::OptionalString WidgetDAO::getDefaultlocale() const
+{
+ LogError("Not implemented!");
+ return DPL::OptionalString();
+}
+
+WidgetDAO::WidgetLocalizedIconList WidgetDAO::getLocalizedIconList() const
+{
+ LogError("Not implemented!");
+ return WidgetLocalizedIconList();
+}
+
+WidgetDAO::WidgetIconList WidgetDAO::getIconList() const
+{
+ LogError("Not implemented!");
+ return WidgetIconList();
+}
+
+WidgetDAO::LocalizedStartFileList WidgetDAO::getLocalizedStartFileList() const
+{
+ return s_localizedStartFileMap[m_widgetHandle];
+}
+
+void WidgetDAO::setLocalizedStartFileList(const LocalizedStartFileList &list) const {
+ s_localizedStartFileMap[m_widgetHandle] = list;
+}
+
+WidgetDAO::WidgetStartFileList WidgetDAO::getStartFileList() const
+{
+ return s_startFileMap[m_widgetHandle];
+}
+
+void WidgetDAO::setStartFileList(const WidgetStartFileList &list) const
+{
+ s_startFileMap[m_widgetHandle] = list;
+}
+
+} // namespace WrtDB
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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);
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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/log/log.h>
+#include <dpl/test/test_runner.h>
+
+#include <dpl/wrt-dao-rw/widget_dao.h>
+#include <dpl/localization/w3c_file_localization.h>
+
+namespace {
+
+WrtDB::LanguageTagList generateLanguageTags(){
+ WrtDB::LanguageTagList tags;
+ tags.push_back(L"pl-pl");
+ tags.push_back(L"en-en");
+ tags.push_back(L"pl-en");
+ return tags;
+}
+
+static const WrtDB::LanguageTagList languageTags = generateLanguageTags();
+static const DPL::String widget1Path = L"/opt/apps/widget/tests/localization/widget1/";
+static const DPL::String widget2Path = L"/opt/apps/widget/tests/localization/widget2/";
+
+} // anonymous namespace
+
+RUNNER_TEST(test01_getFilePathInWidgetPackageFromUrl){
+ const int widgetHandle = 1;
+ WrtDB::WidgetDAO dao(widgetHandle);
+ dao.setPath(widget1Path);
+
+ auto result = W3CFileLocalization::getFilePathInWidgetPackageFromUrl(
+ widgetHandle,
+ languageTags,
+ L"widget://one");
+
+ RUNNER_ASSERT(*result == L"/opt/apps/widget/tests/localization/widget1/locales/pl-en/one");
+}
+
+RUNNER_TEST(test02_getFilePathInWidgetPackageFromUrl){
+ const int widgetHandle = 2;
+ WrtDB::WidgetDAO dao(widgetHandle);
+ dao.setPath(widget2Path);
+
+ auto result = W3CFileLocalization::getFilePathInWidgetPackageFromUrl(
+ widgetHandle,
+ languageTags,
+ L"widget://one");
+
+ RUNNER_ASSERT(*result == L"/opt/apps/widget/tests/localization/widget2/locales/pl-en/one");
+}
+
+RUNNER_TEST(test03_getFilePathInWidgetPackageFromUrl){
+ const int widgetHandle = 2;
+ WrtDB::WidgetDAO dao(widgetHandle);
+ dao.setPath(widget2Path);
+
+ auto result = W3CFileLocalization::getFilePathInWidgetPackageFromUrl(
+ widgetHandle,
+ languageTags,
+ L"widget://two");
+
+ RUNNER_ASSERT(*result == L"/opt/apps/widget/tests/localization/widget2/locales/en-en/two");
+}
+
+RUNNER_TEST(test04_getFilePathInWidgetPackage){
+ const int widgetHandle = 1;
+ WrtDB::WidgetDAO dao(widgetHandle);
+ dao.setPath(widget1Path);
+
+ auto result = W3CFileLocalization::getFilePathInWidgetPackage(
+ widgetHandle,
+ languageTags,
+ L"one");
+
+ RUNNER_ASSERT(*result == L"locales/pl-en/one");
+}
+
+RUNNER_TEST(test05_getFilePathInWidgetPackage){
+ const int widgetHandle = 2;
+ WrtDB::WidgetDAO dao(widgetHandle);
+ dao.setPath(widget2Path);
+
+ auto result = W3CFileLocalization::getFilePathInWidgetPackage(
+ widgetHandle,
+ languageTags,
+ L"two");
+
+ RUNNER_ASSERT(*result == L"locales/en-en/two");
+}
+
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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)
+# @author Pawel Sikorski (p.sikorski@samsung.com)
+# @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+# @version 1.0
+# @brief
+#
+INCLUDE(FindPkgConfig)
+SET(TARGET_VCORE_TEST "dpl-tests-vcore")
+
+PKG_CHECK_MODULES(VCORE_TEST_DEP
+ libsoup-2.4
+ REQUIRED
+ )
+
+SET(VCORE_TESTS_SOURCES
+ ${PROJECT_SOURCE_DIR}/tests/vcore/vcore_tests.cpp
+ ${PROJECT_SOURCE_DIR}/tests/vcore/TestCases.cpp
+ ${PROJECT_SOURCE_DIR}/tests/vcore/TestEnv.cpp
+ ${PROJECT_SOURCE_DIR}/tests/vcore/TestCRL.cpp
+ )
+
+INCLUDE_DIRECTORIES(
+ ${SYS_EFL_INCLUDE_DIRS}
+ ${DPL_TEST_INCLUDE_DIR}
+ ${PROJECT_SOURCE_DIR}/modules/vcore/src
+ ${PROJECT_SOURCE_DIR}/tests/vcore
+ ${PROJECT_SOURCE_DIR}/modules/widget_dao/include # global_config.h
+ ${VCORE_TEST_DEP_INCLUDE_DIRS}
+ )
+
+ADD_EXECUTABLE(${TARGET_VCORE_TEST} ${VCORE_TESTS_SOURCES})
+
+TARGET_LINK_LIBRARIES(${TARGET_VCORE_TEST}
+ ${SYS_EFL_LIBRARIES}
+ ${TARGET_DPL_EFL}
+ ${TARGET_DPL_TEST_ENGINE_EFL}
+ ${TARGET_VCORE_LIB}
+ ${TARGET_WRT_DAO_RO_LIB} # global_config.h_
+ ${VCORE_TEST_DEP_LIBRARIES}
+ )
+
+INSTALL(TARGETS ${TARGET_VCORE_TEST}
+ DESTINATION bin
+ PERMISSIONS OWNER_READ
+ OWNER_WRITE
+ OWNER_EXECUTE
+ GROUP_READ
+ GROUP_EXECUTE
+ WORLD_READ
+ WORLD_EXECUTE
+ )
+
+INSTALL(FILES ${PROJECT_SOURCE_DIR}/tests/vcore/certificate-generator/dpl-tests-vcore-ocsp-server.sh
+ DESTINATION bin
+ PERMISSIONS OWNER_READ
+ OWNER_WRITE
+ OWNER_EXECUTE
+ GROUP_READ
+ GROUP_EXECUTE
+ WORLD_READ
+ WORLD_EXECUTE
+ )
+
+ADD_CUSTOM_COMMAND(TARGET ${TARGET_VCORE_TEST} POST_BUILD
+ COMMAND ${PROJECT_SOURCE_DIR}/tests/vcore/certificate-generator/create_certs.sh
+ WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/tests/vcore/certificate-generator/
+ COMMENT "Generate certificate chains"
+ )
+
+INSTALL(FILES
+ ${PROJECT_SOURCE_DIR}/tests/vcore/test-cases/widget/author-signature.xml
+ ${PROJECT_SOURCE_DIR}/tests/vcore/test-cases/widget/signature1.xml
+ ${PROJECT_SOURCE_DIR}/tests/vcore/test-cases/widget/signature22.xml
+ ${PROJECT_SOURCE_DIR}/tests/vcore/test-cases/widget/config.xml
+ ${PROJECT_SOURCE_DIR}/tests/vcore/test-cases/widget/index.html
+ DESTINATION
+ /opt/apps/widget/tests/vcore_widget_uncompressed
+ )
+
+INSTALL(FILES
+ ${PROJECT_SOURCE_DIR}/tests/vcore/test-cases/keys/ocsp_level0deprecated.crt
+ ${PROJECT_SOURCE_DIR}/tests/vcore/test-cases/keys/ocsp_level1.crt
+ ${PROJECT_SOURCE_DIR}/tests/vcore/test-cases/keys/ocsp_level2.crt
+ ${PROJECT_SOURCE_DIR}/tests/vcore/test-cases/keys/ocsp_rootca.crt
+ ${PROJECT_SOURCE_DIR}/tests/vcore/test-cases/keys/operator.root.cert.pem
+ ${PROJECT_SOURCE_DIR}/tests/vcore/test-cases/keys/root_cacert.pem
+ ${PROJECT_SOURCE_DIR}/tests/vcore/test-cases/keys/CAbundle.crt
+ DESTINATION
+ /opt/apps/widget/tests/vcore_keys
+ )
+
+INSTALL(FILES
+ ${PROJECT_SOURCE_DIR}/tests/vcore/certificate-generator/demoCA/cacert.pem
+ ${PROJECT_SOURCE_DIR}/tests/vcore/certificate-generator/1second_level.pem
+ ${PROJECT_SOURCE_DIR}/tests/vcore/certificate-generator/1third_level.pem
+ ${PROJECT_SOURCE_DIR}/tests/vcore/certificate-generator/2second_level.pem
+ ${PROJECT_SOURCE_DIR}/tests/vcore/certificate-generator/2third_level.pem
+ ${PROJECT_SOURCE_DIR}/tests/vcore/certificate-generator/3second_level.pem
+ ${PROJECT_SOURCE_DIR}/tests/vcore/certificate-generator/3third_level.pem
+ ${PROJECT_SOURCE_DIR}/tests/vcore/certificate-generator/cacrl1.pem
+ ${PROJECT_SOURCE_DIR}/tests/vcore/certificate-generator/cacrl2.pem
+ ${PROJECT_SOURCE_DIR}/tests/vcore/certificate-generator/respcert.pem
+ ${PROJECT_SOURCE_DIR}/tests/vcore/certificate-generator/respcert.key
+ ${PROJECT_SOURCE_DIR}/tests/vcore/certificate-generator/openssl.cnf
+ DESTINATION
+ /opt/apps/widget/tests/vcore_certs/
+)
+
+INSTALL(DIRECTORY
+ ${PROJECT_SOURCE_DIR}/tests/vcore/certificate-generator/demoCA
+ DESTINATION
+ /opt/apps/widget/tests/vcore_certs/
+)
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <algorithm>
+#include <cstring>
+#include <openssl/x509v3.h>
+#include <dpl/file_input_mapping.h>
+#include <dpl/log/log.h>
+#include "TestCRL.h"
+
+using namespace ValidationCore;
+using namespace std;
+
+
+namespace {
+const char *CRL_LOOKUP_DIR = "/opt/etc/ssl/certs/";
+const char *beginCertificate = "-----BEGIN CERTIFICATE-----";
+const char *endCertificate = "-----END CERTIFICATE-----";
+const char *beginTrustedCertificate = "-----BEGIN TRUSTED CERTIFICATE-----";
+const char *endTrustedCertificate = "-----END TRUSTED CERTIFICATE-----";
+
+
+bool whiteCharacter(char a){
+ return a == '\n';
+}
+
+}
+
+TestCRL::TestCRL()
+{
+ //Add additional lookup dir
+ int rv = X509_LOOKUP_add_dir(m_lookup, CRL_LOOKUP_DIR, X509_FILETYPE_PEM);
+ if (!rv) {
+ LogError("Failed to add lookup dir for PEM files.");
+ ThrowMsg(CRLException::StorageError,
+ "Failed to add lookup dir for PEM files.");
+ }
+ LogInfo("CRL storage initialization complete.");
+}
+
+std::string TestCRL::getFileContent(const std::string &filename)
+{
+ //Only PEM formatted files allowed
+ LogInfo("Read file: " << filename);
+ DPL::FileInputMapping file(filename);
+ string content(reinterpret_cast<const char*>(file.GetAddress()),
+ file.GetSize());
+
+ size_t posBegin = content.find(beginCertificate);
+ size_t posEnd = content.find(endCertificate);
+ if (posBegin != string::npos &&
+ posEnd != string::npos) {
+ posBegin += strlen(beginCertificate);
+ } else {
+ posBegin = content.find(beginTrustedCertificate);
+ posEnd = content.find(endTrustedCertificate);
+ if (posBegin != string::npos &&
+ posEnd != string::npos) {
+ posBegin += strlen(beginTrustedCertificate);
+ } else {
+ LogError("Failed to parse PEM file");
+ return string();
+ }
+ }
+ //Remove whitespaces
+ string cert(content, posBegin, posEnd - posBegin);
+ cert.erase(std::remove_if(cert.begin(), cert.end(), whiteCharacter),
+ cert.end());
+
+ return cert;
+}
+
+void TestCRL::addCRLToStore(const string &filename, const string &uri)
+{
+ LogInfo("Read file: " << filename);
+ //Only PEM formatted files allowed
+ DPL::FileInputMapping file(filename);
+ char *buffer = new char[file.GetSize()];
+ memcpy(buffer, file.GetAddress(), file.GetSize());
+ CRLDataPtr crl(new CRLData(buffer, file.GetSize(), uri));
+ updateCRL(crl);
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef _TEST_CRL_H
+#define _TEST_CRL_H
+
+#include <string>
+#include <vcore/CRL.h>
+
+class TestCRL : public ValidationCore::CRL
+{
+ public:
+ TestCRL();
+
+ void addCRLToStore(const std::string &filename, const std::string &uri);
+
+ //convinient function
+ std::string getFileContent(const std::string &filename);
+};
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <string>
+
+#include <dpl/test/test_runner.h>
+#include <dpl/event/event_delivery.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <vcore/ReferenceValidator.h>
+#include <vcore/SignatureFinder.h>
+#include <vcore/SignatureReader.h>
+#include <vcore/SignatureValidator.h>
+#include <vcore/OCSP.h>
+#include <vcore/CachedOCSP.h>
+#include "TestEnv.h"
+#include <vcore/SSLContainers.h>
+#include <vcore/Base64.h>
+#include <vcore/CertificateLoader.h>
+#include <vcore/CRL.h>
+#include <vcore/CachedCRL.h>
+#include <vcore/RevocationCheckerBase.h>
+#include "TestCRL.h"
+#include <vcore/CertificateCacheDAO.h>
+
+namespace {
+
+const std::string widget_path =
+ "/opt/apps/widget/tests/vcore_widget_uncompressed/";
+const std::string keys_path = "/opt/apps/widget/tests/vcore_keys/";
+const std::string widget_store_path = "/opt/apps/widget/tests/vcore_widgets/";
+const std::string cert_store_path = "/opt/apps/widget/tests/vcore_certs/";
+const std::string crl_URI = "http://localhost/my.crl";
+
+const std::string anka_ec_key_type = "urn:oid:1.2.840.10045.3.1.7";
+const std::string anka_ec_public_key =
+ "BGi9RmTUjpqCpQjx6SSiKdfmtjQBFNSN7ghm6TuaH9r4x73WddeLxLioH3VEmFLC+QLiR"\
+ "kPxDxL/6YmQdgfGrqk=";
+
+const std::string rsa_modulus =
+ "ocwjKEFaPxLNcPTz2PtT2Gyu5jzkWaPo4thjZo3rXuNbD4TzjY02UGnTxvflNeORLpSS1"\
+ "PeYr/1E/Nhr7qQAzj9g0DwW7p8zQEdOUi3v76VykeB0pFJH+0Fxp6LVBX9Z+EvZk+dbOy"\
+ "GJ4Njm9B6M09axXlV11Anj9B/HYUDfDX8=";
+const std::string rsa_exponent = "AQAB";
+
+const std::string magda_dsa_p =
+ "2BYIQj0ePUVxzrdBT41eCblraa9Dqag7QXFMCRM2PtyS22JPDKuV77tBc/jg0V3htHWdR"\
+ "q9n6/kQDwrP7FIPoLATLIiC3oAYWj46Mr6d9k/tt/JZU6PvULmB2k1wrrmvKUi+U+I5Ro"\
+ "qe8ui8lqR9pp9u2WCh2QmFfCohKNjN5qs=";
+const std::string magda_dsa_q = "4p4JcDqz+S7CbWyd8txApZw0sik=";
+const std::string magda_dsa_g =
+ "AQrLND1ZGFvzwBpPPXplmPh1ijPx1O2gQEvPvyjR88guWcGqQc0m7dTb6PEvbI/oZ0o91"\
+ "k7VEkfthURnNR1WtOLT8dmAuKQfwTQLPwCwUM/QiuWSlCyKLTE4Ev8aOG7ZqWudsKm/td"\
+ "n9pUNGtcod1wo1ZtP7PfEJ6rYZGQDOlz8=";
+
+const std::string googleCA =
+"MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkG"
+"A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz"
+"cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2"
+"MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV"
+"BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt"
+"YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN"
+"ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE"
+"BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is"
+"I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G"
+"CSqGSIb3DQEBAgUAA4GBALtMEivPLCYATxQT3ab7/AoRhIzzKBxnki98tsX63/Do"
+"lbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59AhWM1pF+NEHJwZRDmJXNyc"
+"AA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2OmufTqj/ZA1k";
+
+const std::string google2nd =
+"MIIDIzCCAoygAwIBAgIEMAAAAjANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJV"
+"UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDMgUHVi"
+"bGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNTEzMDAw"
+"MDAwWhcNMTQwNTEyMjM1OTU5WjBMMQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhh"
+"d3RlIENvbnN1bHRpbmcgKFB0eSkgTHRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBD"
+"QTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1NNn0I0Vf67NMf59HZGhPwtx"
+"PKzMyGT7Y/wySweUvW+Aui/hBJPAM/wJMyPpC3QrccQDxtLN4i/1CWPN/0ilAL/g"
+"5/OIty0y3pg25gqtAHvEZEo7hHUD8nCSfQ5i9SGraTaEMXWQ+L/HbIgbBpV8yeWo"
+"3nWhLHpo39XKHIdYYBkCAwEAAaOB/jCB+zASBgNVHRMBAf8ECDAGAQH/AgEAMAsG"
+"A1UdDwQEAwIBBjARBglghkgBhvhCAQEEBAMCAQYwKAYDVR0RBCEwH6QdMBsxGTAX"
+"BgNVBAMTEFByaXZhdGVMYWJlbDMtMTUwMQYDVR0fBCowKDAmoCSgIoYgaHR0cDov"
+"L2NybC52ZXJpc2lnbi5jb20vcGNhMy5jcmwwMgYIKwYBBQUHAQEEJjAkMCIGCCsG"
+"AQUFBzABhhZodHRwOi8vb2NzcC50aGF3dGUuY29tMDQGA1UdJQQtMCsGCCsGAQUF"
+"BwMBBggrBgEFBQcDAgYJYIZIAYb4QgQBBgpghkgBhvhFAQgBMA0GCSqGSIb3DQEB"
+"BQUAA4GBAFWsY+reod3SkF+fC852vhNRj5PZBSvIG3dLrWlQoe7e3P3bB+noOZTc"
+"q3J5Lwa/q4FwxKjt6lM07e8eU9kGx1Yr0Vz00YqOtCuxN5BICEIlxT6Ky3/rbwTR"
+"bcV0oveifHtgPHfNDs5IAn8BL7abN+AqKjbc1YXWrOU/VG+WHgWv";
+
+const std::string google3rd =
+"MIIDITCCAoqgAwIBAgIQL9+89q6RUm0PmqPfQDQ+mjANBgkqhkiG9w0BAQUFADBM"
+"MQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkg"
+"THRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBDQTAeFw0wOTEyMTgwMDAwMDBaFw0x"
+"MTEyMTgyMzU5NTlaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh"
+"MRYwFAYDVQQHFA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKFApHb29nbGUgSW5jMRcw"
+"FQYDVQQDFA53d3cuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC"
+"gYEA6PmGD5D6htffvXImttdEAoN4c9kCKO+IRTn7EOh8rqk41XXGOOsKFQebg+jN"
+"gtXj9xVoRaELGYW84u+E593y17iYwqG7tcFR39SDAqc9BkJb4SLD3muFXxzW2k6L"
+"05vuuWciKh0R73mkszeK9P4Y/bz5RiNQl/Os/CRGK1w7t0UCAwEAAaOB5zCB5DAM"
+"BgNVHRMBAf8EAjAAMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwudGhhd3Rl"
+"LmNvbS9UaGF3dGVTR0NDQS5jcmwwKAYDVR0lBCEwHwYIKwYBBQUHAwEGCCsGAQUF"
+"BwMCBglghkgBhvhCBAEwcgYIKwYBBQUHAQEEZjBkMCIGCCsGAQUFBzABhhZodHRw"
+"Oi8vb2NzcC50aGF3dGUuY29tMD4GCCsGAQUFBzAChjJodHRwOi8vd3d3LnRoYXd0"
+"ZS5jb20vcmVwb3NpdG9yeS9UaGF3dGVfU0dDX0NBLmNydDANBgkqhkiG9w0BAQUF"
+"AAOBgQCfQ89bxFApsb/isJr/aiEdLRLDLE5a+RLizrmCUi3nHX4adpaQedEkUjh5"
+"u2ONgJd8IyAPkU0Wueru9G2Jysa9zCRo1kNbzipYvzwY4OA8Ys+WAi0oR1A04Se6"
+"z5nRUP8pJcA2NhUzUnC+MY+f6H/nEQyNv4SgQhqAibAxWEEHXw==";
+
+const std::string certVerisign =
+"MIIG+DCCBeCgAwIBAgIQU9K++SSnJF6DygHkbKokdzANBgkqhkiG9w0BAQUFADCB"
+"vjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL"
+"ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2Ug"
+"YXQgaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykwNjE4MDYGA1UEAxMv"
+"VmVyaVNpZ24gQ2xhc3MgMyBFeHRlbmRlZCBWYWxpZGF0aW9uIFNTTCBTR0MgQ0Ew"
+"HhcNMTAwNTI2MDAwMDAwWhcNMTIwNTI1MjM1OTU5WjCCASkxEzARBgsrBgEEAYI3"
+"PAIBAxMCVVMxGTAXBgsrBgEEAYI3PAIBAhMIRGVsYXdhcmUxGzAZBgNVBA8TElYx"
+"LjAsIENsYXVzZSA1LihiKTEQMA4GA1UEBRMHMjQ5Nzg4NjELMAkGA1UEBhMCVVMx"
+"DjAMBgNVBBEUBTk0MDQzMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHFA1N"
+"b3VudGFpbiBWaWV3MSIwIAYDVQQJFBk0ODcgRWFzdCBNaWRkbGVmaWVsZCBSb2Fk"
+"MRcwFQYDVQQKFA5WZXJpU2lnbiwgSW5jLjEmMCQGA1UECxQdIFByb2R1Y3Rpb24g"
+"U2VjdXJpdHkgU2VydmljZXMxGTAXBgNVBAMUEHd3dy52ZXJpc2lnbi5jb20wggEi"
+"MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCj+PvvK+fZOXwno0yT/OTy2Zm9"
+"ehnZjTtO/X2IWBEa3jG30C52uHFQI4NmXiQVNvJHkBaAj0ilVjvGdxXmkyyFsugt"
+"IWOTZ8pSKdX1tmGFIon6Ko9+lBFkVkudA1ogAUbtTB8IcdeOlpK78T4SjdVMhY18"
+"150YzSw6hRKlw52wBaDxtGZElvOth41K7TUcaDnQVzz5SBPW5MUhi7AWrdoSk17O"
+"BozOzmB/jkYDVDnwLcbR89SLHEOle/idSYSDQUmab3y0JS8RyQV1+DB70mnFALnD"
+"fLiL47nMQQCGxXgp5voQ2YmSXhevKmEJ9vvtC6C7yv2W6yomfS/weUEce9pvAgMB"
+"AAGjggKCMIICfjCBiwYDVR0RBIGDMIGAghB3d3cudmVyaXNpZ24uY29tggx2ZXJp"
+"c2lnbi5jb22CEHd3dy52ZXJpc2lnbi5uZXSCDHZlcmlzaWduLm5ldIIRd3d3LnZl"
+"cmlzaWduLm1vYmmCDXZlcmlzaWduLm1vYmmCD3d3dy52ZXJpc2lnbi5ldYILdmVy"
+"aXNpZ24uZXUwCQYDVR0TBAIwADAdBgNVHQ4EFgQU8oBwK/WBXCZDWi0dbuDgPyTK"
+"iJIwCwYDVR0PBAQDAgWgMD4GA1UdHwQ3MDUwM6AxoC+GLWh0dHA6Ly9FVkludGwt"
+"Y3JsLnZlcmlzaWduLmNvbS9FVkludGwyMDA2LmNybDBEBgNVHSAEPTA7MDkGC2CG"
+"SAGG+EUBBxcGMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LnZlcmlzaWduLmNv"
+"bS9ycGEwKAYDVR0lBCEwHwYIKwYBBQUHAwEGCCsGAQUFBwMCBglghkgBhvhCBAEw"
+"HwYDVR0jBBgwFoAUTkPIHXbvN1N6T/JYb5TzOOLVvd8wdgYIKwYBBQUHAQEEajBo"
+"MCsGCCsGAQUFBzABhh9odHRwOi8vRVZJbnRsLW9jc3AudmVyaXNpZ24uY29tMDkG"
+"CCsGAQUFBzAChi1odHRwOi8vRVZJbnRsLWFpYS52ZXJpc2lnbi5jb20vRVZJbnRs"
+"MjAwNi5jZXIwbgYIKwYBBQUHAQwEYjBgoV6gXDBaMFgwVhYJaW1hZ2UvZ2lmMCEw"
+"HzAHBgUrDgMCGgQUS2u5KJYGDLvQUjibKaxLB4shBRgwJhYkaHR0cDovL2xvZ28u"
+"dmVyaXNpZ24uY29tL3ZzbG9nbzEuZ2lmMA0GCSqGSIb3DQEBBQUAA4IBAQB9VZxB"
+"wDMRGyhFWYkY5rwUVGuDJiGeas2xRJC0G4+riQ7IN7pz2a2BhktmZ5HbxXL4ZEY4"
+"yMN68DEVErhtKiuL02ng27alhlngadKQzSL8pLdmQ+3jEwm9nva5C/7pbeqy+qGF"
+"is4IWNYOc4HKNkABxXm5v0ouys8HPNkTLFLep0gLqRXW3gYN2XbKUWMs7z7hJpkY"
+"GxP8YQSxi513O2dWVCXB8S6erIz9E/bcfdXoCPyQdn42y3IEoJvPvBS3S55fD4+Q"
+"Q43GPhumSg9a6S3hnyw8DX5OiUGmqgQrtSeDRsNmWqtWizEQbe+fotZpEn/7zYTa"
+"tk1ni/k5jDH/QeuG";
+
+const std::string crlExampleCertificate =
+"MIIFlDCCBHygAwIBAgIBADANBgkqhkiG9w0BAQUFADBDMRIwEAYKCZImiZPyLGQB"
+"GRYCZXMxGDAWBgoJkiaJk/IsZAEZFghpcmlzZ3JpZDETMBEGA1UEAxMKSVJJU0dy"
+"aWRDQTAeFw0wNTA2MjgwNTAyMjhaFw0xNTA2MjYwNTAyMjhaMEMxEjAQBgoJkiaJ"
+"k/IsZAEZFgJlczEYMBYGCgmSJomT8ixkARkWCGlyaXNncmlkMRMwEQYDVQQDEwpJ"
+"UklTR3JpZENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1CQiWlff"
+"ajoMSTuismKqLQ+Mt33Tq4bBpCZvCBXhqan1R0ksILPtK1L7C8QWqPk6AZZpuNmY"
+"cNVtJGc8ksgDWvX0EB3GKwZTZ8RrSRlSEe9Otq+Ur7S9uxM1JMmCr6zZTMFANzBS"
+"4btnduV78C09IhFYG4OW8IPhNrbfPaeOR+PRPAa/qdSONAwTrM1sZkIvGpAkBWM6"
+"Pn7TK9BAK6GLvwgii780fWj3Cwgmp8EDCTievBbWj+z8/apMEy9R0vyB2dWNNCnk"
+"6q8VvrjgMsJt33O3BqOoBuZ8R/SS9OFWLFSU3s7cfrRaUSJk/Mx8OGFizRkcXSzX"
+"0Nidcg7hX5i78wIDAQABo4ICkTCCAo0wDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E"
+"FgQUnUJkLlupXvH/bMg8NtPxtkOYrRowawYDVR0jBGQwYoAUnUJkLlupXvH/bMg8"
+"NtPxtkOYrRqhR6RFMEMxEjAQBgoJkiaJk/IsZAEZFgJlczEYMBYGCgmSJomT8ixk"
+"ARkWCGlyaXNncmlkMRMwEQYDVQQDEwpJUklTR3JpZENBggEAMA4GA1UdDwEB/wQE"
+"AwIBxjARBglghkgBhvhCAQEEBAMCAAcwOwYJYIZIAYb4QgENBC4WLElSSVNHcmlk"
+"IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IENlcnRpZmljYXRlMIGZBgNVHR8EgZEw"
+"gY4wLqAsoCqGKGh0dHA6Ly93d3cuaXJpc2dyaWQuZXMvcGtpL2NybC9jYWNybC5w"
+"ZW0wXKBaoFiGVmxkYXA6Ly9sZGFwLmlyaXNncmlkLmVzOjEzODAvY249SVJJU0dy"
+"aWRDQSxkYz1pcmlzZ3JpZCxkYz1lcz9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0"
+"MDcGCWCGSAGG+EIBAwQqFihodHRwOi8vd3d3LmlyaXNncmlkLmVzL3BraS9jcmwv"
+"Y2FjcmwucGVtME4GCWCGSAGG+EIBCARBFj9odHRwOi8vd3d3LmlyaXNncmlkLmVz"
+"L3BraS9wb2xpY3kvMS4zLjYuMS40LjEuNzU0Ny4yLjIuNC4xLjEuMS8waQYDVR0g"
+"BGIwYDBeBg0rBgEEAbp7AgIEAQEBME0wSwYIKwYBBQUHAgEWP2h0dHA6Ly93d3cu"
+"aXJpc2dyaWQuZXMvcGtpL3BvbGljeS8xLjMuNi4xLjQuMS43NTQ3LjIuMi40LjEu"
+"MS4xLzANBgkqhkiG9w0BAQUFAAOCAQEAaqRfyLER+P2QOZLLdz66m7FGsgtFsAEx"
+"wiNrIChFWfyHVZG7Ph1fn/GDD5LMsrU23lx3NBN5/feHuut1XNYKNs8vtV07D70r"
+"DKjUlPbmWV0B+/GDxe1FDGop/tKQfyHSUaBuauXChFU/2INu5lhBerNl7QxNJ1ws"
+"cWGiT7R+L/2EjgzWgH1V/0zmIOMep6kY7MUs8rlyF0O5MNFs232cA1trl9kvhAGU"
+"9p58Enf5DWMrh17SPH586yIJeiWZtPez9G54ftY+XIqfn0X0zso0dnoXNJQYS043"
+"/5vSnoHdRx/EmN8yjeEavZtC48moN0iJ38eB44uKgCD77rZW5s1XqA==";
+
+//class TestCleanup
+//{
+// public:
+// explicit TestCleanup(bool bCheckForFakeVerification = false)
+// {
+// if (bCheckForFakeVerification) {
+// bool bUnsetEnvVar = true;
+//
+// m_strEnvVar = "CHECK_ONLY_DOMAIN_INSTEAD_OF_VALIDATION";
+// if (getenv(m_strEnvVar.c_str()) != NULL) {
+// bUnsetEnvVar = false;
+// } else {
+// setenv(m_strEnvVar.c_str(), "1", 0);
+// }
+// }
+// }
+//
+// ~TestCleanup()
+// {
+// if (!m_strRootCAPath.empty()) {
+// removeCertGivenByFilename(m_strRootCAPath.c_str());
+// }
+//
+// if (!m_strEnvVar.empty()) {
+// unsetenv(m_strEnvVar.c_str());
+// }
+// }
+//
+// void setRootCAPath(const std::string& strRootCAPath)
+// {
+// m_strRootCAPath = strRootCAPath;
+// }
+//
+// private:
+// std::string m_strRootCAPath;
+// std::string m_strEnvVar;
+//};
+//
+//class PolicyChanger : public DPL::Event::EventListener<AceUpdateResponseEvent>
+//{
+// public:
+// PolicyChanger()
+// {
+// DPL::Event::EventDeliverySystem::AddListener<AceUpdateResponseEvent>(this);
+// }
+//
+// ~PolicyChanger()
+// {
+// DPL::Event::EventDeliverySystem::RemoveListener<AceUpdateResponseEvent>(this);
+// }
+//
+// void OnEventReceived(const AceUpdateResponseEvent& event)
+// {
+// if (0 != event.GetArg0()) {
+// LogError("Policy change failed");
+// }
+// Assert(0 == event.GetArg0() && "Policy change failed");
+// LoopControl::finish_wait_for_wrt_init();
+// }
+//
+// void updatePolicy(const std::string& path)
+// {
+// AceUpdateRequestEvent event(path);
+// DPL::Event::EventDeliverySystem::Publish(event);
+// LoopControl::wait_for_wrt_init();
+// }
+//};
+
+} // namespace anonymous
+
+using namespace ValidationCore;
+
+//////////////////////////////////////////////////
+//////// VALIDATION CORE TEST SUITE ////////////
+//////////////////////////////////////////////////
+
+RUNNER_TEST(test01_signature_finder)
+{
+ SignatureFileInfoSet signatureSet;
+ SignatureFinder signatureFinder(widget_path);
+ RUNNER_ASSERT_MSG(
+ SignatureFinder::NO_ERROR == signatureFinder.find(signatureSet),
+ "SignatureFinder failed");
+ RUNNER_ASSERT_MSG(signatureSet.size() == 3,
+ "Some signature has not been found");
+
+ SignatureFileInfo first = *(signatureSet.begin());
+ RUNNER_ASSERT_MSG(
+ std::string("author-signature.xml") == first.getFileName(),
+ "Author Signature");
+ RUNNER_ASSERT_MSG(-1 == first.getFileNumber(), "Wrong signature number.");
+ first = *(signatureSet.rbegin());
+ RUNNER_ASSERT_MSG(std::string("signature22.xml") == first.getFileName(),
+ "Wrong signature fileName.");
+ RUNNER_ASSERT_MSG(22 == first.getFileNumber(), "Wrong signature number.");
+}
+
+RUNNER_TEST(test02_signature_reader)
+{
+ SignatureFileInfoSet signatureSet;
+ SignatureFinder signatureFinder(widget_path);
+ RUNNER_ASSERT_MSG(
+ SignatureFinder::NO_ERROR == signatureFinder.find(signatureSet),
+ "SignatureFinder failed");
+
+ SignatureFileInfoSet::reverse_iterator iter = signatureSet.rbegin();
+
+ for (; iter != signatureSet.rend(); ++iter) {
+ SignatureData data(widget_path + iter->getFileName(),
+ iter->getFileNumber());
+ SignatureReader xml;
+ xml.initialize(data, WrtDB::GlobalConfig::GetSignatureXmlSchema());
+ xml.read(data);
+ }
+}
+
+RUNNER_TEST(test03_signature_validator)
+{
+ SignatureFileInfoSet signatureSet;
+ SignatureFinder signatureFinder(widget_path);
+ RUNNER_ASSERT_MSG(
+ SignatureFinder::NO_ERROR == signatureFinder.find(signatureSet),
+ "SignatureFinder failed");
+
+ SignatureFileInfoSet::reverse_iterator iter = signatureSet.rbegin();
+
+ for (; iter != signatureSet.rend(); ++iter) {
+ SignatureData data(widget_path + iter->getFileName(),
+ iter->getFileNumber());
+ SignatureReader xml;
+ xml.initialize(data, WrtDB::GlobalConfig::GetSignatureXmlSchema());
+ xml.read(data);
+
+ SignatureValidator validator(
+ false,
+ false,
+ false);
+
+ if (data.isAuthorSignature()) {
+ RUNNER_ASSERT_MSG(
+ SignatureValidator::SIGNATURE_DISREGARD ==
+ validator.check(data, widget_path),
+ "Validation failed");
+ } else {
+ RUNNER_ASSERT_MSG(
+ SignatureValidator::SIGNATURE_VERIFIED ==
+ validator.check(data, widget_path),
+ "Validation failed");
+ }
+ }
+}
+
+RUNNER_TEST(test05_signature_reference)
+{
+ SignatureFileInfoSet signatureSet;
+ SignatureFinder signatureFinder(widget_path);
+ RUNNER_ASSERT_MSG(
+ SignatureFinder::NO_ERROR == signatureFinder.find(signatureSet),
+ "SignatureFinder failed");
+
+ SignatureFileInfoSet::reverse_iterator iter = signatureSet.rbegin();
+
+ for (; iter != signatureSet.rend(); ++iter) {
+ SignatureData data(widget_path + iter->getFileName(),
+ iter->getFileNumber());
+ SignatureReader xml;
+ xml.initialize(data, WrtDB::GlobalConfig::GetSignatureXmlSchema());
+ xml.read(data);
+
+ SignatureValidator sval(
+ false,
+ false,
+ false);
+ sval.check(data, widget_path);
+
+ ReferenceValidator val(widget_path);
+ RUNNER_ASSERT(
+ ReferenceValidator::NO_ERROR == val.checkReferences(data));
+ }
+}
+
+RUNNER_TEST(test07t01_base64)
+{
+ std::string strraw = "1234567890qwertyuiop[]asdfghjkl;'zxcvbnm,.";
+ std::string strenc =
+ "MTIzNDU2Nzg5MHF3ZXJ0eXVpb3BbXWFzZGZnaGprbDsnenhjdmJubSwu";
+
+ Base64Encoder encoder;
+ encoder.reset();
+ encoder.append(strraw);
+ encoder.finalize();
+ RUNNER_ASSERT_MSG(strenc == encoder.get(), "Error in Base64Encoder.");
+
+ Base64Decoder decoder;
+ decoder.reset();
+ decoder.append(strenc);
+ RUNNER_ASSERT(decoder.finalize());
+ RUNNER_ASSERT_MSG(strraw == decoder.get(), "Error in Base64Decoder.");
+}
+
+RUNNER_TEST(test07t02_base64)
+{
+ const size_t MAX = 40;
+ char buffer[MAX];
+ for (size_t i = 0; i<MAX; ++i) {
+ buffer[i] = static_cast<char>(i);
+ }
+
+ std::string raw(&buffer[0], &buffer[MAX]);
+
+ RUNNER_ASSERT(MAX == raw.size());
+
+ Base64Encoder encoder;
+ encoder.reset();
+ encoder.append(raw);
+ encoder.finalize();
+ std::string enc = encoder.get();
+
+ Base64Decoder decoder;
+ decoder.reset();
+ decoder.append(enc);
+ RUNNER_ASSERT(decoder.finalize());
+ RUNNER_ASSERT_MSG(raw == decoder.get(), "Error in Base64 conversion.");
+}
+
+RUNNER_TEST(test07t03_base64)
+{
+ std::string invalid = "1234)";
+
+ Base64Decoder decoder;
+ decoder.reset();
+ decoder.append(invalid);
+ RUNNER_ASSERT(false == decoder.finalize());
+}
+
+RUNNER_TEST(test07t04_base64)
+{
+ std::string invalid = "12234";
+
+ Base64Decoder decoder;
+ decoder.reset();
+
+ bool exception = false;
+ Try {
+ std::string temp = decoder.get();
+ } Catch(Base64Decoder::Exception::NotFinalized) {
+ exception = true;
+ }
+
+ RUNNER_ASSERT_MSG(exception, "Base64Decoder does not throw error.");
+}
+
+RUNNER_TEST(test08t01_Certificate)
+{
+ Certificate cert(certVerisign, Certificate::FORM_BASE64);
+
+ DPL::OptionalString result;
+
+ result = cert.getCommonName(Certificate::FIELD_SUBJECT);
+ RUNNER_ASSERT_MSG(!result.IsNull(), "No common name");
+ RUNNER_ASSERT_MSG(*result == DPL::FromUTF8String("www.verisign.com"),
+ "CommonName mismatch");
+
+ result = cert.getCommonName(Certificate::FIELD_ISSUER);
+ RUNNER_ASSERT_MSG(!result.IsNull(), "No common name");
+ RUNNER_ASSERT_MSG(result == DPL::FromUTF8String(
+ "VeriSign Class 3 Extended Validation SSL SGC CA"),
+ "CommonName mismatch");
+
+ result = cert.getCountryName();
+ RUNNER_ASSERT_MSG(!result.IsNull(), "No country");
+ RUNNER_ASSERT_MSG(*result == DPL::FromUTF8String("US"),
+ "Country mismatch");
+}
+
+RUNNER_TEST(test08t02_Certificate)
+{
+ Certificate cert(certVerisign, Certificate::FORM_BASE64);
+
+ Certificate::Fingerprint fin =
+ cert.getFingerprint(Certificate::FINGERPRINT_SHA1);
+
+ unsigned char buff[20] = {
+ 0xb9, 0x72, 0x1e, 0xd5, 0x49,
+ 0xed, 0xbf, 0x31, 0x84, 0xd8,
+ 0x27, 0x0c, 0xfe, 0x03, 0x11,
+ 0x19, 0xdf, 0xc2, 0x2b, 0x0a};
+ RUNNER_ASSERT_MSG(fin.size() == 20, "Wrong size of fingerprint");
+
+ for (size_t i = 0; i<20; ++i) {
+ RUNNER_ASSERT_MSG(fin[i] == buff[i], "Fingerprint mismatch");
+ }
+}
+
+RUNNER_TEST(test08t03_Certificate)
+{
+ Certificate cert(certVerisign, Certificate::FORM_BASE64);
+
+ Certificate::AltNameSet nameSet = cert.getAlternativeNameDNS();
+
+ RUNNER_ASSERT(nameSet.size() == 8);
+
+ DPL::String str = DPL::FromUTF8String("verisign.com");
+ RUNNER_ASSERT(nameSet.find(str) != nameSet.end());
+
+ str = DPL::FromUTF8String("fake.com");
+ RUNNER_ASSERT(nameSet.find(str) == nameSet.end());
+
+}
+
+RUNNER_TEST(test09t01_CertificateCollection)
+{
+ CertificateList list;
+ list.push_back(CertificatePtr(
+ new Certificate(google2nd, Certificate::FORM_BASE64)));
+ list.push_back(CertificatePtr(
+ new Certificate(googleCA, Certificate::FORM_BASE64)));
+ list.push_back(CertificatePtr(
+ new Certificate(google3rd, Certificate::FORM_BASE64)));
+
+ CertificateCollection collection;
+ collection.load(list);
+
+ bool exception = false;
+
+ Try {
+ RUNNER_ASSERT(collection.isChain());
+ } Catch (CertificateCollection::Exception::WrongUsage) {
+ exception = true;
+ }
+
+ RUNNER_ASSERT_MSG(exception, "Exception expected!");
+
+ RUNNER_ASSERT_MSG(collection.sort(), "Sort failed");
+
+ RUNNER_ASSERT(collection.isChain());
+
+ std::string encoded = collection.toBase64String();
+
+ collection.clear();
+
+ RUNNER_ASSERT_MSG(collection.size() == 0, "Function clear failed.");
+
+ collection.load(encoded);
+
+ RUNNER_ASSERT_MSG(collection.sort(), "Sort failed");
+
+ list = collection.getChain();
+
+ RUNNER_ASSERT(
+ DPL::ToUTF8String(*(list.front().Get()->getCommonName())) ==
+ "www.google.com");
+ RUNNER_ASSERT(
+ DPL::ToUTF8String(*(list.back().Get()->getOrganizationName())) ==
+ "VeriSign, Inc.");
+}
+
+RUNNER_TEST(test51t01_ocsp_validation_negative)
+{
+ CertificateCacheDAO::clearCertificateCache();
+
+ CertificateList lOCSPCertificates;
+ CertificatePtr certificatePtr;
+ CertificatePtr pCert0;
+ CertificatePtr pCert1;
+ CertificatePtr pCert2;
+ CertificatePtr pRootCert;
+ std::string caRootPath(keys_path + "ocsp_rootca.crt"),
+ certLevel0Path(keys_path + "ocsp_level0deprecated.crt"),
+ certLevel1Path(keys_path + "ocsp_level1.crt"),
+ certLevel2Path(keys_path + "ocsp_level2.crt");
+
+ pRootCert = RevocationCheckerBase::loadPEMFile(caRootPath.c_str());
+ if (!pRootCert) {
+ RUNNER_ASSERT_MSG(false, "Couldn't load ocsp_rootca.crt");
+ }
+ lOCSPCertificates.push_back(pRootCert);
+
+ pCert0 = RevocationCheckerBase::loadPEMFile(certLevel0Path.c_str());
+ if (!pCert0) {
+ RUNNER_ASSERT_MSG(false, "Couldn't load ocsp_level0.crt");
+ }
+ lOCSPCertificates.push_back(CertificatePtr(pCert0));
+
+ pCert1 = RevocationCheckerBase::loadPEMFile(certLevel1Path.c_str());
+ if (!pCert1) {
+ RUNNER_ASSERT_MSG(false, "Couldn't load ocsp_level1.crt");
+ }
+ lOCSPCertificates.push_back(CertificatePtr(pCert1));
+
+ pCert2 = RevocationCheckerBase::loadPEMFile(certLevel2Path.c_str());
+ if (!pCert2) {
+ RUNNER_ASSERT_MSG(false, "Couldn't load ocsp_level2.crt");
+ }
+ lOCSPCertificates.push_back(CertificatePtr(pCert2));
+
+ OCSP ocsp;
+ ocsp.setDigestAlgorithmForCertId(ValidationCore::OCSP::SHA1);
+ ocsp.setDigestAlgorithmForRequest(ValidationCore::OCSP::SHA1);
+
+ CertificateCollection collection;
+ collection.load(lOCSPCertificates);
+ RUNNER_ASSERT(collection.sort());
+ CertificateList sorted = collection.getChain();
+
+ ocsp.setTrustedStore(sorted);
+ VerificationStatusSet status = ocsp.validateCertificateList(sorted);
+
+ RUNNER_ASSERT_MSG(!status.contains(VERIFICATION_STATUS_CONNECTION_FAILED),
+ "Caught OCSP connection error from store exception");
+ RUNNER_ASSERT_MSG(status.contains(VERIFICATION_STATUS_GOOD),
+ "Caught OCSP verification error exception");
+ RUNNER_ASSERT_MSG(status.contains(VERIFICATION_STATUS_VERIFICATION_ERROR),
+ "Caught OCSP verification error exception");
+
+ CertificateCacheDAO::clearCertificateCache();
+}
+
+RUNNER_TEST(test51t02_ocsp_validation_positive)
+{
+ CertificateCacheDAO::clearCertificateCache();
+
+ CertificateList lOCSPCertificates;
+ CertificatePtr certificatePtr;
+ CertificatePtr pCert0;
+ CertificatePtr pCert1;
+ CertificatePtr pCert2;
+ CertificatePtr pRootCert;
+ std::string caRootPath(keys_path + "ocsp_rootca.crt"),
+ certLevel1Path(keys_path + "ocsp_level1.crt"),
+ certLevel2Path(keys_path + "ocsp_level2.crt");
+
+ pRootCert = RevocationCheckerBase::loadPEMFile(caRootPath.c_str());
+ if (!pRootCert) {
+ RUNNER_ASSERT_MSG(false, "Couldn't load ocsp_rootca.crt");
+ }
+ lOCSPCertificates.push_back(pRootCert);
+
+ pCert1 = RevocationCheckerBase::loadPEMFile(certLevel1Path.c_str());
+ if (!pCert1) {
+ RUNNER_ASSERT_MSG(false, "Couldn't load ocsp_level1.crt");
+ }
+ lOCSPCertificates.push_back(CertificatePtr(pCert1));
+
+ pCert2 = RevocationCheckerBase::loadPEMFile(certLevel2Path.c_str());
+ if (!pCert2) {
+ RUNNER_ASSERT_MSG(false, "Couldn't load ocsp_level2.crt");
+ }
+ lOCSPCertificates.push_back(CertificatePtr(pCert2));
+
+ OCSP ocsp;
+ ocsp.setDigestAlgorithmForCertId(ValidationCore::OCSP::SHA1);
+ ocsp.setDigestAlgorithmForRequest(ValidationCore::OCSP::SHA1);
+
+ CertificateCollection collection;
+ collection.load(lOCSPCertificates);
+ RUNNER_ASSERT(collection.sort());
+ CertificateList sorted = collection.getChain();
+
+ ocsp.setTrustedStore(sorted);
+ VerificationStatusSet status = ocsp.validateCertificateList(sorted);
+
+ RUNNER_ASSERT_MSG(!status.contains(VERIFICATION_STATUS_CONNECTION_FAILED),
+ "Caught OCSP connection error from store exception");
+ RUNNER_ASSERT_MSG(status.contains(VERIFICATION_STATUS_GOOD),
+ "Caught OCSP verification error exception");
+ RUNNER_ASSERT_MSG(!status.contains(VERIFICATION_STATUS_VERIFICATION_ERROR),
+ "Caught OCSP verification error exception");
+
+ CertificateCacheDAO::clearCertificateCache();
+}
+
+RUNNER_TEST(test51t04_ocsp_request)
+{
+ CertificateList lTrustedCerts;
+
+ lTrustedCerts.push_back(CertificatePtr(
+ new Certificate(google3rd, Certificate::FORM_BASE64)));
+ lTrustedCerts.push_back(CertificatePtr(
+ new Certificate(google2nd, Certificate::FORM_BASE64)));
+ lTrustedCerts.push_back(CertificatePtr(
+ new Certificate(googleCA, Certificate::FORM_BASE64)));
+
+ CertificateCollection chain;
+ chain.load(lTrustedCerts);
+ chain.sort();
+
+ OCSP ocsp;
+ ocsp.setDigestAlgorithmForCertId(OCSP::SHA1);
+ ocsp.setDigestAlgorithmForRequest(OCSP::SHA1);
+ ocsp.setTrustedStore(lTrustedCerts);
+ VerificationStatus result = ocsp.checkEndEntity(chain);
+
+ RUNNER_ASSERT(VERIFICATION_STATUS_GOOD == result);
+}
+
+RUNNER_TEST(test51t05_cached_ocsp_validation_negative)
+{
+ CertificateCacheDAO::clearCertificateCache();
+
+ CertificateList lOCSPCertificates;
+ CertificatePtr certificatePtr;
+ CertificatePtr pCert0;
+ CertificatePtr pCert1;
+ CertificatePtr pCert2;
+ CertificatePtr pRootCert;
+ std::string caRootPath(keys_path + "ocsp_rootca.crt"),
+ certLevel0Path(keys_path + "ocsp_level0deprecated.crt"),
+ certLevel1Path(keys_path + "ocsp_level1.crt"),
+ certLevel2Path(keys_path + "ocsp_level2.crt");
+
+ pRootCert = RevocationCheckerBase::loadPEMFile(caRootPath.c_str());
+ RUNNER_ASSERT_MSG(pRootCert, "Couldn't load ocsp_rootca.crt");
+ lOCSPCertificates.push_back(pRootCert);
+
+ pCert0 = RevocationCheckerBase::loadPEMFile(certLevel0Path.c_str());
+ RUNNER_ASSERT_MSG(pCert0, "Couldn't load ocsp_level0.crt");
+ lOCSPCertificates.push_back(CertificatePtr(pCert0));
+
+ pCert1 = RevocationCheckerBase::loadPEMFile(certLevel1Path.c_str());
+ RUNNER_ASSERT_MSG(pCert1, "Couldn't load ocsp_level1.crt");
+ lOCSPCertificates.push_back(CertificatePtr(pCert1));
+
+ pCert2 = RevocationCheckerBase::loadPEMFile(certLevel2Path.c_str());
+ RUNNER_ASSERT_MSG(pCert2, "Couldn't load ocsp_level2.crt");
+ lOCSPCertificates.push_back(CertificatePtr(pCert2));
+
+ CachedOCSP ocsp;
+
+ CertificateCollection collection;
+ collection.load(lOCSPCertificates);
+ RUNNER_ASSERT(collection.sort());
+
+ VerificationStatus status = ocsp.check(collection);
+
+ RUNNER_ASSERT_MSG(status != VERIFICATION_STATUS_GOOD,
+ "Caught OCSP verification error exception");
+
+ OCSPCachedStatusList respList;
+ CertificateCacheDAO::getOCSPStatusList(&respList);
+ unsigned len = respList.size();
+
+ status = ocsp.check(collection);
+
+ RUNNER_ASSERT_MSG(status != VERIFICATION_STATUS_GOOD,
+ "Caught OCSP verification error exception");
+
+ respList.clear();
+ CertificateCacheDAO::getOCSPStatusList(&respList);
+ RUNNER_ASSERT_MSG(respList.size() == len && len > 0,
+ "Caught OCSP cache error exception");
+
+ CertificateCacheDAO::clearCertificateCache();
+}
+
+RUNNER_TEST(test51t06_cached_ocsp_validation_positive)
+{
+ CertificateCacheDAO::clearCertificateCache();
+
+ CertificateList lOCSPCertificates;
+ CertificatePtr certificatePtr;
+ CertificatePtr pCert0;
+ CertificatePtr pCert1;
+ CertificatePtr pCert2;
+ CertificatePtr pRootCert;
+ std::string caRootPath(keys_path + "ocsp_rootca.crt"),
+ certLevel1Path(keys_path + "ocsp_level1.crt"),
+ certLevel2Path(keys_path + "ocsp_level2.crt");
+
+ pRootCert = RevocationCheckerBase::loadPEMFile(caRootPath.c_str());
+ RUNNER_ASSERT_MSG(pRootCert, "Couldn't load ocsp_rootca.crt");
+ lOCSPCertificates.push_back(pRootCert);
+
+ pCert1 = RevocationCheckerBase::loadPEMFile(certLevel1Path.c_str());
+ RUNNER_ASSERT_MSG(pCert1, "Couldn't load ocsp_level1.crt");
+ lOCSPCertificates.push_back(CertificatePtr(pCert1));
+
+ pCert2 = RevocationCheckerBase::loadPEMFile(certLevel2Path.c_str());
+ RUNNER_ASSERT_MSG(pCert2, "Couldn't load ocsp_level2.crt");
+ lOCSPCertificates.push_back(CertificatePtr(pCert2));
+
+ CachedOCSP ocsp;
+
+ CertificateCollection collection;
+ collection.load(lOCSPCertificates);
+ RUNNER_ASSERT(collection.sort());
+
+ VerificationStatus status = ocsp.check(collection);
+
+ RUNNER_ASSERT_MSG(status == VERIFICATION_STATUS_GOOD,
+ "Caught OCSP verification error exception");
+
+ OCSPCachedStatusList respList;
+ CertificateCacheDAO::getOCSPStatusList(&respList);
+ unsigned len = respList.size();
+
+ status = ocsp.check(collection);
+
+ RUNNER_ASSERT_MSG(status == VERIFICATION_STATUS_GOOD,
+ "Caught OCSP verification error exception");
+
+ respList.clear();
+ CertificateCacheDAO::getOCSPStatusList(&respList);
+ RUNNER_ASSERT_MSG(respList.size() == len && len > 0,
+ "Caught OCSP cache error exception");
+
+ CertificateCacheDAO::clearCertificateCache();
+}
+
+RUNNER_TEST(test61_crl_test_revocation_no_crl)
+{
+ //Clear CRL cache so there is no CRL for those certificates URI.
+ CertificateCacheDAO::clearCertificateCache();
+ //Prepare certificate chain
+ TestCRL crl;
+ std::string cacertStr(crl.getFileContent(cert_store_path + "cacert.pem"));
+ std::string certAStr(
+ crl.getFileContent(cert_store_path + "1second_level.pem"));
+ std::string certBStr(
+ crl.getFileContent(cert_store_path + "1third_level.pem"));
+
+ CertificateLoader loader;
+ CertificateList certList;
+ CertificateCollection collection;
+ RUNNER_ASSERT(loader.loadCertificateFromRawData(cacertStr) ==
+ CertificateLoader::NO_ERROR);
+ RUNNER_ASSERT(!!loader.getCertificatePtr());
+ certList.push_back(loader.getCertificatePtr());
+ RUNNER_ASSERT(loader.loadCertificateFromRawData(certAStr) ==
+ CertificateLoader::NO_ERROR);
+ RUNNER_ASSERT(!!loader.getCertificatePtr());
+ certList.push_back(loader.getCertificatePtr());
+ RUNNER_ASSERT(loader.loadCertificateFromRawData(certBStr) ==
+ CertificateLoader::NO_ERROR);
+ RUNNER_ASSERT(!!loader.getCertificatePtr());
+ certList.push_back(loader.getCertificatePtr());
+
+ collection.load(certList);
+
+ CRL::RevocationStatus status = crl.checkCertificateChain(collection);
+ RUNNER_ASSERT_MSG(status.isCRLValid == false,
+ "Some certificate have no CRL extension!");
+
+ CertificateCacheDAO::clearCertificateCache();
+}
+
+RUNNER_TEST(test62_crl_test_revocation_set1)
+{
+ CertificateCacheDAO::clearCertificateCache();
+
+ //Prepare certificate chain
+ TestCRL crl;
+ std::string cacertStr(crl.getFileContent(cert_store_path + "cacert.pem"));
+ std::string certAStr(
+ crl.getFileContent(cert_store_path + "1second_level.pem"));
+ std::string certBStr(
+ crl.getFileContent(cert_store_path + "1third_level.pem"));
+ crl.addCRLToStore(cert_store_path + "cacrl1.pem", crl_URI);
+
+ CertificateLoader loader;
+ CertificateList certList;
+ CertificateCollection collection;
+ RUNNER_ASSERT(loader.loadCertificateFromRawData(cacertStr) ==
+ CertificateLoader::NO_ERROR);
+ RUNNER_ASSERT(!!loader.getCertificatePtr());
+ certList.push_back(loader.getCertificatePtr());
+ RUNNER_ASSERT(loader.loadCertificateFromRawData(certAStr) ==
+ CertificateLoader::NO_ERROR);
+ RUNNER_ASSERT(!!loader.getCertificatePtr());
+ certList.push_back(loader.getCertificatePtr());
+ RUNNER_ASSERT(loader.loadCertificateFromRawData(certBStr) ==
+ CertificateLoader::NO_ERROR);
+ RUNNER_ASSERT(!!loader.getCertificatePtr());
+ certList.push_back(loader.getCertificatePtr());
+
+ collection.load(certList);
+
+ CRL::RevocationStatus status = crl.checkCertificateChain(collection);
+ RUNNER_ASSERT(status.isCRLValid);
+ RUNNER_ASSERT(status.isRevoked);
+
+ CertificateCacheDAO::clearCertificateCache();
+}
+
+RUNNER_TEST(test63_crl_test_revocation_set1)
+{
+ CertificateCacheDAO::clearCertificateCache();
+
+ //Prepare certificate chain
+ TestCRL crl;
+ std::string cacertStr(crl.getFileContent(cert_store_path + "cacert.pem"));
+ std::string certAStr(
+ crl.getFileContent(cert_store_path + "1second_level.pem"));
+ std::string certBStr(
+ crl.getFileContent(cert_store_path + "1third_level.pem"));
+ crl.addCRLToStore(cert_store_path + "cacrl1.pem", crl_URI);
+
+ CertificateLoader loader;
+ CertificateList certList;
+ CertificateCollection collection;
+ RUNNER_ASSERT(loader.loadCertificateFromRawData(cacertStr) ==
+ CertificateLoader::NO_ERROR);
+ RUNNER_ASSERT(!!loader.getCertificatePtr());
+ certList.push_back(loader.getCertificatePtr());
+ RUNNER_ASSERT(loader.loadCertificateFromRawData(certAStr) ==
+ CertificateLoader::NO_ERROR);
+ RUNNER_ASSERT(!!loader.getCertificatePtr());
+ certList.push_back(loader.getCertificatePtr());
+ RUNNER_ASSERT(loader.loadCertificateFromRawData(certBStr) ==
+ CertificateLoader::NO_ERROR);
+ RUNNER_ASSERT(!!loader.getCertificatePtr());
+ certList.push_back(loader.getCertificatePtr());
+
+ collection.load(certList);
+
+ CRL::RevocationStatus status = crl.checkCertificateChain(collection);
+ RUNNER_ASSERT(status.isCRLValid);
+ RUNNER_ASSERT(status.isRevoked);
+
+ CertificateCacheDAO::clearCertificateCache();
+}
+
+RUNNER_TEST(test64_crl_test_revocation_set2)
+{
+ CertificateCacheDAO::clearCertificateCache();
+
+ //Prepare certificate chain
+ TestCRL crl;
+ std::string cacertStr(crl.getFileContent(cert_store_path + "cacert.pem"));
+ std::string certAStr(
+ crl.getFileContent(cert_store_path + "2second_level.pem"));
+ std::string certBStr(
+ crl.getFileContent(cert_store_path + "2third_level.pem"));
+ crl.addCRLToStore(cert_store_path + "cacrl1.pem", crl_URI);
+
+ CertificateLoader loader;
+ CertificateList certList;
+ CertificateCollection collection;
+ RUNNER_ASSERT(loader.loadCertificateFromRawData(cacertStr) ==
+ CertificateLoader::NO_ERROR);
+ RUNNER_ASSERT(!!loader.getCertificatePtr());
+ certList.push_back(loader.getCertificatePtr());
+ RUNNER_ASSERT(loader.loadCertificateFromRawData(certAStr) ==
+ CertificateLoader::NO_ERROR);
+ RUNNER_ASSERT(!!loader.getCertificatePtr());
+ certList.push_back(loader.getCertificatePtr());
+ RUNNER_ASSERT(loader.loadCertificateFromRawData(certBStr) ==
+ CertificateLoader::NO_ERROR);
+ RUNNER_ASSERT(!!loader.getCertificatePtr());
+ certList.push_back(loader.getCertificatePtr());
+
+ collection.load(certList);
+
+ CRL::RevocationStatus status = crl.checkCertificateChain(collection);
+ RUNNER_ASSERT(status.isCRLValid);
+ RUNNER_ASSERT(!status.isRevoked);
+
+ CertificateCacheDAO::clearCertificateCache();
+}
+
+RUNNER_TEST(test65_crl_test_revocation_set2)
+{
+ CertificateCacheDAO::clearCertificateCache();
+
+ //Prepare certificate chain
+ TestCRL crl;
+ std::string cacertStr(crl.getFileContent(cert_store_path + "cacert.pem"));
+ std::string certAStr(
+ crl.getFileContent(cert_store_path + "2second_level.pem"));
+ std::string certBStr(
+ crl.getFileContent(cert_store_path + "2third_level.pem"));
+ crl.addCRLToStore(cert_store_path + "cacrl2.pem", crl_URI);
+
+ CertificateLoader loader;
+ CertificateList certList;
+ CertificateCollection collection;
+ RUNNER_ASSERT(loader.loadCertificateFromRawData(cacertStr) ==
+ CertificateLoader::NO_ERROR);
+ RUNNER_ASSERT(!!loader.getCertificatePtr());
+ certList.push_back(loader.getCertificatePtr());
+ RUNNER_ASSERT(loader.loadCertificateFromRawData(certAStr) ==
+ CertificateLoader::NO_ERROR);
+ RUNNER_ASSERT(!!loader.getCertificatePtr());
+ certList.push_back(loader.getCertificatePtr());
+ RUNNER_ASSERT(loader.loadCertificateFromRawData(certBStr) ==
+ CertificateLoader::NO_ERROR);
+ RUNNER_ASSERT(!!loader.getCertificatePtr());
+ certList.push_back(loader.getCertificatePtr());
+
+ collection.load(certList);
+
+ CRL::RevocationStatus status = crl.checkCertificateChain(collection);
+ RUNNER_ASSERT(status.isCRLValid);
+ RUNNER_ASSERT(status.isRevoked);
+
+ CertificateCacheDAO::clearCertificateCache();
+}
+
+RUNNER_TEST(test66_crl_update_expired_lists)
+{
+ CertificateCacheDAO::clearCertificateCache();
+
+ CertificateLoader loader;
+ loader.loadCertificateFromRawData(google2nd);
+ RUNNER_ASSERT(!!loader.getCertificatePtr());
+ TestCRL crl;
+ RUNNER_ASSERT_MSG(
+ crl.updateList(loader.getCertificatePtr(), CRL::UPDATE_ON_EXPIRED),
+ "CRL update on expired succeeded");
+
+ CertificateCacheDAO::clearCertificateCache();
+}
+
+RUNNER_TEST(test67_crl_update_lists_on_demand)
+{
+ CertificateCacheDAO::clearCertificateCache();
+
+ CertificateLoader loader;
+ loader.loadCertificateFromRawData(google2nd);
+ RUNNER_ASSERT(!!loader.getCertificatePtr());
+ TestCRL crl;
+ RUNNER_ASSERT_MSG(
+ crl.updateList(loader.getCertificatePtr(), CRL::UPDATE_ON_DEMAND),
+ "CRL update on demand succeeded");
+
+ CertificateCacheDAO::clearCertificateCache();
+}
+
+RUNNER_TEST(test68_cached_crl_test_positive)
+{
+ CertificateCacheDAO::clearCertificateCache();
+
+ TestCRL crl;
+
+ std::string cacertStr(crl.getFileContent(cert_store_path + "cacert.pem"));
+ std::string certAStr(
+ crl.getFileContent(cert_store_path + "2second_level.pem"));
+ std::string certBStr(
+ crl.getFileContent(cert_store_path + "2third_level.pem"));
+ crl.addCRLToStore(cert_store_path + "cacrl1.pem", crl_URI);
+
+ CertificateLoader loader;
+ CertificateList certList;
+ CertificateCollection collection;
+ RUNNER_ASSERT(loader.loadCertificateFromRawData(cacertStr) ==
+ CertificateLoader::NO_ERROR);
+ RUNNER_ASSERT(!!loader.getCertificatePtr());
+ certList.push_back(loader.getCertificatePtr());
+ RUNNER_ASSERT(loader.loadCertificateFromRawData(certAStr) ==
+ CertificateLoader::NO_ERROR);
+ RUNNER_ASSERT(!!loader.getCertificatePtr());
+ certList.push_back(loader.getCertificatePtr());
+ RUNNER_ASSERT(loader.loadCertificateFromRawData(certBStr) ==
+ CertificateLoader::NO_ERROR);
+ RUNNER_ASSERT(!!loader.getCertificatePtr());
+ certList.push_back(loader.getCertificatePtr());
+
+ collection.load(certList);
+
+ CRL::RevocationStatus status = crl.checkCertificateChain(collection);
+
+ CachedCRL cached;
+ VerificationStatus cached_status = cached.check(collection);
+ CRLCachedDataList list;
+ CertificateCacheDAO::getCRLResponseList(&list);
+ unsigned len = list.size();
+
+ RUNNER_ASSERT(status.isCRLValid);
+ RUNNER_ASSERT(!status.isRevoked &&
+ cached_status == VERIFICATION_STATUS_GOOD);
+
+ cached_status = cached.check(collection);
+ list.clear();
+ CertificateCacheDAO::getCRLResponseList(&list);
+
+ RUNNER_ASSERT(len == list.size());
+ RUNNER_ASSERT(!status.isRevoked &&
+ cached_status == VERIFICATION_STATUS_GOOD);
+
+ CertificateCacheDAO::clearCertificateCache();
+}
+
+RUNNER_TEST(test69_cached_crl_test_negative)
+{
+ CertificateCacheDAO::clearCertificateCache();
+
+ //Prepare certificate chain
+ TestCRL crl;
+ std::string cacertStr(crl.getFileContent(cert_store_path + "cacert.pem"));
+ std::string certAStr(
+ crl.getFileContent(cert_store_path + "2second_level.pem"));
+ std::string certBStr(
+ crl.getFileContent(cert_store_path + "2third_level.pem"));
+ crl.addCRLToStore(cert_store_path + "cacrl2.pem", crl_URI);
+
+ CertificateLoader loader;
+ CertificateList certList;
+ CertificateCollection collection;
+ RUNNER_ASSERT(loader.loadCertificateFromRawData(cacertStr) ==
+ CertificateLoader::NO_ERROR);
+ RUNNER_ASSERT(!!loader.getCertificatePtr());
+ certList.push_back(loader.getCertificatePtr());
+ RUNNER_ASSERT(loader.loadCertificateFromRawData(certAStr) ==
+ CertificateLoader::NO_ERROR);
+ RUNNER_ASSERT(!!loader.getCertificatePtr());
+ certList.push_back(loader.getCertificatePtr());
+ RUNNER_ASSERT(loader.loadCertificateFromRawData(certBStr) ==
+ CertificateLoader::NO_ERROR);
+ RUNNER_ASSERT(!!loader.getCertificatePtr());
+ certList.push_back(loader.getCertificatePtr());
+
+ collection.load(certList);
+
+ CRL::RevocationStatus status = crl.checkCertificateChain(collection);
+ CachedCRL cached;
+ VerificationStatus cached_status = cached.check(collection);
+ CRLCachedDataList list;
+ CertificateCacheDAO::getCRLResponseList(&list);
+ unsigned len = list.size();
+
+ RUNNER_ASSERT(status.isCRLValid);
+ RUNNER_ASSERT(status.isRevoked &&
+ cached_status == VERIFICATION_STATUS_REVOKED);
+
+ cached_status = cached.check(collection);
+ list.clear();
+ CertificateCacheDAO::getCRLResponseList(&list);
+
+ RUNNER_ASSERT(len == list.size());
+ RUNNER_ASSERT(status.isRevoked &&
+ cached_status == VERIFICATION_STATUS_REVOKED);
+
+ CertificateCacheDAO::clearCertificateCache();
+}
+
+RUNNER_TEST(test70_ocsp_local_validation_positive)
+{
+ CertificateCacheDAO::clearCertificateCache();
+
+ CertificateList lOCSPCertificates;
+ CertificatePtr certificatePtr;
+ CertificatePtr pCert0;
+ CertificatePtr pRootCert;
+ std::string caRootPath(cert_store_path + "cacert.pem"),
+ certLevel0Path(cert_store_path + "1second_level.pem");
+
+ pRootCert = RevocationCheckerBase::loadPEMFile(caRootPath.c_str());
+ if (!pRootCert) {
+ RUNNER_ASSERT_MSG(false, "Couldn't load cacert.pem");
+ }
+ lOCSPCertificates.push_back(pRootCert);
+
+ pCert0 = RevocationCheckerBase::loadPEMFile(certLevel0Path.c_str());
+ if (!pCert0) {
+ RUNNER_ASSERT_MSG(false, "Couldn't load 1second_level.pem");
+ }
+ lOCSPCertificates.push_back(CertificatePtr(pCert0));
+
+ OCSP ocsp;
+ ocsp.setDigestAlgorithmForCertId(ValidationCore::OCSP::SHA1);
+ ocsp.setDigestAlgorithmForRequest(ValidationCore::OCSP::SHA1);
+
+ CertificateCollection collection;
+ collection.load(lOCSPCertificates);
+ RUNNER_ASSERT(collection.sort());
+ CertificateList sorted = collection.getChain();
+
+ ocsp.setTrustedStore(sorted);
+ VerificationStatusSet status = ocsp.validateCertificateList(sorted);
+
+ RUNNER_ASSERT_MSG(!status.contains(VERIFICATION_STATUS_CONNECTION_FAILED),
+ "Caught OCSP connection error - check if "
+ "dpl-tests-vcore-ocsp-server.sh is running!");
+ RUNNER_ASSERT_MSG(status.contains(VERIFICATION_STATUS_GOOD),
+ "Caught OCSP verification error exception");
+ RUNNER_ASSERT_MSG(!status.contains(VERIFICATION_STATUS_VERIFICATION_ERROR),
+ "Caught OCSP verification error exception");
+
+ CertificateCacheDAO::clearCertificateCache();
+}
+
+RUNNER_TEST(test71_ocsp_local_validation_positive)
+{
+ CertificateCacheDAO::clearCertificateCache();
+
+ CertificateList lOCSPCertificates;
+ CertificatePtr certificatePtr;
+ CertificatePtr pCert0;
+ CertificatePtr pRootCert;
+ std::string caRootPath(cert_store_path + "cacert.pem"),
+ certLevel0Path(cert_store_path + "3second_level.pem");
+
+ pRootCert = RevocationCheckerBase::loadPEMFile(caRootPath.c_str());
+ if (!pRootCert) {
+ RUNNER_ASSERT_MSG(false, "Couldn't load cacert.pem");
+ }
+ lOCSPCertificates.push_back(pRootCert);
+
+ pCert0 = RevocationCheckerBase::loadPEMFile(certLevel0Path.c_str());
+ if (!pCert0) {
+ RUNNER_ASSERT_MSG(false, "Couldn't load 3second_level.pem");
+ }
+ lOCSPCertificates.push_back(CertificatePtr(pCert0));
+
+ OCSP ocsp;
+ ocsp.setDigestAlgorithmForCertId(ValidationCore::OCSP::SHA1);
+ ocsp.setDigestAlgorithmForRequest(ValidationCore::OCSP::SHA1);
+
+ CertificateCollection collection;
+ collection.load(lOCSPCertificates);
+ RUNNER_ASSERT(collection.sort());
+ CertificateList sorted = collection.getChain();
+
+ ocsp.setTrustedStore(sorted);
+ VerificationStatusSet status = ocsp.validateCertificateList(sorted);
+
+ RUNNER_ASSERT_MSG(!status.contains(VERIFICATION_STATUS_CONNECTION_FAILED),
+ "Caught OCSP connection error - check if "
+ "dpl-tests-vcore-ocsp-server.sh is running!");
+ RUNNER_ASSERT_MSG(status.contains(VERIFICATION_STATUS_GOOD),
+ "Caught OCSP verification error exception");
+ RUNNER_ASSERT_MSG(!status.contains(VERIFICATION_STATUS_VERIFICATION_ERROR),
+ "Caught OCSP verification error exception");
+
+ CertificateCacheDAO::clearCertificateCache();
+}
+
+RUNNER_TEST(test72_ocsp_local_validation_revoked)
+{
+ CertificateCacheDAO::clearCertificateCache();
+
+ CertificateList lOCSPCertificates;
+ CertificatePtr certificatePtr;
+ CertificatePtr pCert0;
+ CertificatePtr pRootCert;
+ std::string caRootPath(cert_store_path + "cacert.pem"),
+ certLevel0Path(cert_store_path + "2second_level.pem");
+
+ pRootCert = RevocationCheckerBase::loadPEMFile(caRootPath.c_str());
+ if (!pRootCert) {
+ RUNNER_ASSERT_MSG(false, "Couldn't load cacert.pem");
+ }
+ lOCSPCertificates.push_back(pRootCert);
+
+ pCert0 = RevocationCheckerBase::loadPEMFile(certLevel0Path.c_str());
+ if (!pCert0) {
+ RUNNER_ASSERT_MSG(false, "Couldn't load 2second_level.pem");
+ }
+ lOCSPCertificates.push_back(CertificatePtr(pCert0));
+
+ OCSP ocsp;
+ ocsp.setDigestAlgorithmForCertId(ValidationCore::OCSP::SHA1);
+ ocsp.setDigestAlgorithmForRequest(ValidationCore::OCSP::SHA1);
+
+ CertificateCollection collection;
+ collection.load(lOCSPCertificates);
+ RUNNER_ASSERT(collection.sort());
+ CertificateList sorted = collection.getChain();
+
+ ocsp.setTrustedStore(sorted);
+ VerificationStatusSet status = ocsp.validateCertificateList(sorted);
+
+ RUNNER_ASSERT_MSG(!status.contains(VERIFICATION_STATUS_CONNECTION_FAILED),
+ "Caught OCSP connection error - check if "
+ "dpl-tests-vcore-ocsp-server.sh is running!");
+ RUNNER_ASSERT_MSG(!status.contains(VERIFICATION_STATUS_GOOD),
+ "Caught OCSP verification error exception");
+ RUNNER_ASSERT_MSG(status.contains(VERIFICATION_STATUS_REVOKED),
+ "Caught OCSP verification error exception");
+ RUNNER_ASSERT_MSG(!status.contains(VERIFICATION_STATUS_UNKNOWN),
+ "Caught OCSP verification error exception");
+ RUNNER_ASSERT_MSG(!status.contains(VERIFICATION_STATUS_VERIFICATION_ERROR),
+ "Caught OCSP verification error exception");
+
+ CertificateCacheDAO::clearCertificateCache();
+}
+
+RUNNER_TEST(test73_ocsp_local_validation_error_unknown_cert)
+{
+ CertificateCacheDAO::clearCertificateCache();
+
+ CertificateList lOCSPCertificates;
+ CertificatePtr certificatePtr;
+ CertificatePtr pCert0;
+ CertificatePtr pCert1;
+ CertificatePtr pRootCert;
+ std::string caRootPath(cert_store_path + "cacert.pem"),
+ certLevel0Path(cert_store_path + "1second_level.pem"),
+ certLevel1Path(cert_store_path + "1third_level.pem");
+
+ pRootCert = RevocationCheckerBase::loadPEMFile(caRootPath.c_str());
+ if (!pRootCert) {
+ RUNNER_ASSERT_MSG(false, "Couldn't load cacerr.pem");
+ }
+ lOCSPCertificates.push_back(pRootCert);
+
+ pCert0 = RevocationCheckerBase::loadPEMFile(certLevel0Path.c_str());
+ if (!pCert0) {
+ RUNNER_ASSERT_MSG(false, "Couldn't load 1second_level.pem");
+ }
+ lOCSPCertificates.push_back(CertificatePtr(pCert0));
+
+ pCert1 = RevocationCheckerBase::loadPEMFile(certLevel1Path.c_str());
+ if (!pCert1) {
+ RUNNER_ASSERT_MSG(false, "Couldn't load 1third_level.pem");
+ }
+ lOCSPCertificates.push_back(CertificatePtr(pCert1));
+
+ OCSP ocsp;
+ ocsp.setDigestAlgorithmForCertId(ValidationCore::OCSP::SHA1);
+ ocsp.setDigestAlgorithmForRequest(ValidationCore::OCSP::SHA1);
+
+ CertificateCollection collection;
+ collection.load(lOCSPCertificates);
+ RUNNER_ASSERT(collection.sort());
+ CertificateList sorted = collection.getChain();
+
+ ocsp.setTrustedStore(sorted);
+ VerificationStatusSet status = ocsp.validateCertificateList(sorted);
+
+ RUNNER_ASSERT_MSG(!status.contains(VERIFICATION_STATUS_CONNECTION_FAILED),
+ "Caught OCSP connection error - check if "
+ "dpl-tests-vcore-ocsp-server.sh is running!");
+ RUNNER_ASSERT_MSG(status.contains(VERIFICATION_STATUS_GOOD),
+ "Caught OCSP verification error exception");
+ RUNNER_ASSERT_MSG(!status.contains(VERIFICATION_STATUS_REVOKED),
+ "Caught OCSP verification error exception");
+ RUNNER_ASSERT_MSG(status.contains(VERIFICATION_STATUS_VERIFICATION_ERROR),
+ "Caught OCSP verification error exception");
+ RUNNER_ASSERT_MSG(!status.contains(VERIFICATION_STATUS_UNKNOWN),
+ "Caught OCSP verification error exception");
+
+ CertificateCacheDAO::clearCertificateCache();
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <string>
+#include <cstring>
+#include <dpl/log/log.h>
+
+#include <cert-service.h>
+
+#include "TestEnv.h"
+
+const char *storePath = "code-signing_wac";
+
+int addCertToStore(const char* name){
+ int result = cert_svc_add_certificate_to_store(name, storePath);
+
+ if (CERT_SVC_ERR_NO_ERROR != result) {
+ LogError("Error adding certificate: " << name << " To: " << storePath);
+ }
+ return result;
+}
+
+//long int removeCertFromStore(const char* subjectName, const char* issuerName)
+//{
+// long int result = OPERATION_SUCCESS;
+// /* Retrieve all the certificates from store */
+// certmgr_cert_id certId;
+// certmgr_mem_buff certRetrieved;
+// certmgr_ctx context;
+// char storeId[CERTMGR_MAX_PLUGIN_ID_SIZE];
+// char type[CERTMGR_MAX_CERT_TYPE_SIZE];
+// unsigned char certBuff[CERTMGR_MAX_BUFFER_SIZE * 2];
+//
+// certmgr_cert_descriptor descriptor;
+// certId.storeId = storeId;
+// certId.type = type;
+//
+// CERTMGR_INIT_CONTEXT((&context), (sizeof(certmgr_ctx)))
+// std::string storeName("Operator");
+// strncpy(context.storeId, storeName.c_str(), storeName.size());
+//
+// certRetrieved.data = certBuff;
+// certRetrieved.size = CERTMGR_MAX_BUFFER_SIZE * 2;
+//
+// certRetrieved.firstFree = 0;
+//
+// for(certRetrieved.firstFree = 0;
+// OPERATION_SUCCESS ==
+// (result = certmgr_retrieve_certificate_from_store( &context, &certRetrieved, &certId));
+// certRetrieved.firstFree = 0)
+// {
+// if(OPERATION_SUCCESS ==
+// certmgr_extract_certificate_data(&certRetrieved, &descriptor)){
+// LogDebug("The subject of this certificate is " << descriptor.mandatory.subject);
+// LogDebug("The issuer of this certificate is " << descriptor.mandatory.issuer);
+// }
+//
+// if(strcmp(descriptor.mandatory.subject, subjectName) == 0 &&
+// strcmp(descriptor.mandatory.issuer,issuerName) == 0 &&
+// OPERATION_SUCCESS == certmgr_remove_certificate_from_store(&certId))
+// {
+// LogDebug("***Certificate has been REMOVED***");
+// return OPERATION_SUCCESS;
+// }
+// }
+//
+// if(ERR_NO_MORE_CERTIFICATES == result){
+// LogDebug("***THIS CERT IS NOT IN STORE***");
+// return OPERATION_SUCCESS;
+// }
+//
+// return result;
+//}
+
+int removeCertGivenByFilename(const char* name){
+ int result = cert_svc_delete_certificate_from_store(name, storePath);
+
+ if (CERT_SVC_ERR_NO_ERROR != result) {
+ LogError("Error removing certificate: " << name << " From: " << storePath);
+ }
+
+ return result;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 _TESTENV_H_
+#define _TESTENV_H_
+
+int addCertToStore(const char *name);
+long int removeCertFromStore(const char *subjectName, const char *issuerName);
+int removeCertGivenByFilename(const char *name);
+
+#endif
--- /dev/null
+#!/bin/bash
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+#Prerequisite to run script is to
+#create root certificate and directory structure (demoCA) with command:
+#/usr/lib/ssl/misc/CA.sh -newca
+#for automated tests default structure is created in demoCA.init
+
+#make sure current dir has no files from previous generation
+rm -r 1* 2* 3* ca* respcert* demoCA
+cp -R demoCA.init demoCA
+echo "01" > ./demoCA/crlnumber
+
+for index in 1 2 3
+do
+ #create certificate A
+ openssl genrsa -out ${index}second_level.key 1024 -passin pass:1234 -config ./openssl.cnf
+ openssl req -new -key ${index}second_level.key -out ${index}second_level.csr -passin pass:1234 -config ./openssl.cnf <<CONTENT
+PL
+Masovian
+Warsaw
+priv
+priv
+second_level${index}
+
+
+
+CONTENT
+
+ openssl ca -in ${index}second_level.csr -out ${index}second_level.pem -passin pass:1234 -config ./openssl.cnf -extensions v3_ca <<CONTENT
+y
+y
+CONTENT
+
+ #create certificate B
+ openssl req -new -keyout ${index}third_level.key -out ${index}third_level.request -passin pass:1234 -passout pass:1234 -days 365 -config ./openssl.cnf <<CONTENT
+PL
+Masovian
+Warsaw
+priv
+priv
+third_level${index}
+
+
+
+CONTENT
+
+ openssl ca -config ./openssl.cnf -extensions v3_ca -policy policy_anything -keyfile ${index}second_level.key -cert ${index}second_level.pem -out ${index}third_level.pem -infiles ${index}third_level.request <<CONTENT
+y
+y
+CONTENT
+
+done
+
+#generate OCSP response signing certificate
+openssl genrsa -out respcert.key 1024 -passin pass:1234 -config ./openssl.cnf
+openssl req -new -key respcert.key -out respcert.csr -passin pass:1234 -config ./openssl.cnf <<CONTENT
+PL
+Masovian
+Warsaw
+priv
+priv
+responce_cert
+
+
+
+CONTENT
+
+openssl ca -in respcert.csr -out respcert.pem -passin pass:1234 -config ./openssl.cnf -extensions ocsp_cert <<CONTENT
+y
+y
+CONTENT
+
+#generate CRL
+openssl ca -passin pass:1234 -gencrl -keyfile ./demoCA/private/cakey.pem -cert ./demoCA/cacert.pem -out cacrl1.pem -crldays 30 -config ./openssl.cnf
+openssl ca -passin pass:1234 -revoke 1third_level.pem -keyfile ./demoCA/private/cakey.pem -cert ./demoCA/cacert.pem -config ./openssl.cnf
+openssl ca -passin pass:1234 -gencrl -keyfile ./demoCA/private/cakey.pem -cert ./demoCA/cacert.pem -out cacrl1.pem -crldays 30 -config ./openssl.cnf
+
+openssl ca -passin pass:1234 -gencrl -keyfile ./demoCA/private/cakey.pem -cert ./demoCA/cacert.pem -out cacrl2.pem -crldays 30 -config ./openssl.cnf
+openssl ca -passin pass:1234 -revoke 2second_level.pem -keyfile ./demoCA/private/cakey.pem -cert ./demoCA/cacert.pem -config ./openssl.cnf
+openssl ca -passin pass:1234 -gencrl -keyfile ./demoCA/private/cakey.pem -cert ./demoCA/cacert.pem -out cacrl2.pem -crldays 30 -config ./openssl.cnf
--- /dev/null
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 0 (0x0)
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=PL, ST=Masovian, O=priv, OU=priv, CN=priv
+ Validity
+ Not Before: Jul 29 14:32:12 2011 GMT
+ Not After : Jul 28 14:32:12 2014 GMT
+ Subject: C=PL, ST=Masovian, O=priv, OU=priv, CN=priv
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public Key: (1024 bit)
+ Modulus (1024 bit):
+ 00:ab:68:cc:1a:41:78:50:0c:f4:43:3f:9e:8d:7b:
+ 90:3d:eb:d6:8b:ce:d9:c1:b5:f4:d3:2e:75:f3:e1:
+ b3:29:97:1b:38:c6:20:73:8d:a6:cd:61:3f:e1:1c:
+ 78:0f:fd:25:e2:a0:95:6d:a9:33:30:fe:24:76:3d:
+ e4:9d:23:b2:39:3c:98:a5:b2:20:2f:7d:c8:7d:d5:
+ 00:7c:11:2c:6e:58:a2:18:03:02:48:4a:81:c7:eb:
+ 7b:e9:e3:8d:b0:eb:3d:ee:21:19:7c:04:c2:ad:4f:
+ 45:b3:1a:13:d1:76:35:c4:38:7e:0c:6c:7c:e7:83:
+ 41:f0:78:1b:b4:16:d5:93:d9
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ F6:6E:9E:36:6D:49:02:FC:91:1A:5A:9D:D3:FA:B4:9F:07:EE:A9:B3
+ X509v3 Authority Key Identifier:
+ keyid:F6:6E:9E:36:6D:49:02:FC:91:1A:5A:9D:D3:FA:B4:9F:07:EE:A9:B3
+ DirName:/C=PL/ST=Masovian/O=priv/OU=priv/CN=priv
+ serial:00
+
+ X509v3 Basic Constraints:
+ CA:TRUE
+ Signature Algorithm: sha1WithRSAEncryption
+ 96:3c:f7:22:3d:32:c0:67:fc:3a:0a:3c:b7:62:38:7d:a6:d5:
+ 2d:86:c2:ce:6a:84:66:d4:56:b3:93:4e:4c:37:d1:49:b6:67:
+ 91:76:57:96:96:cc:5a:71:da:69:b7:52:9d:8f:17:f7:66:fa:
+ 6c:f1:98:28:44:af:60:df:ad:2a:8b:f5:f3:8c:27:c4:68:a5:
+ 2a:35:c1:6c:84:37:20:ee:c2:9c:58:98:a1:ff:ba:fd:38:36:
+ 45:c3:d7:38:5d:47:ad:c8:0d:26:2b:a9:9d:2e:39:73:b2:aa:
+ da:e5:19:b8:57:28:62:dd:94:2a:c9:50:5b:33:59:b0:56:cf:
+ eb:2f
+-----BEGIN CERTIFICATE-----
+MIICuDCCAiGgAwIBAgIBADANBgkqhkiG9w0BAQUFADBNMQswCQYDVQQGEwJQTDER
+MA8GA1UECBMITWFzb3ZpYW4xDTALBgNVBAoTBHByaXYxDTALBgNVBAsTBHByaXYx
+DTALBgNVBAMTBHByaXYwHhcNMTEwNzI5MTQzMjEyWhcNMTQwNzI4MTQzMjEyWjBN
+MQswCQYDVQQGEwJQTDERMA8GA1UECBMITWFzb3ZpYW4xDTALBgNVBAoTBHByaXYx
+DTALBgNVBAsTBHByaXYxDTALBgNVBAMTBHByaXYwgZ8wDQYJKoZIhvcNAQEBBQAD
+gY0AMIGJAoGBAKtozBpBeFAM9EM/no17kD3r1ovO2cG19NMudfPhsymXGzjGIHON
+ps1hP+EceA/9JeKglW2pMzD+JHY95J0jsjk8mKWyIC99yH3VAHwRLG5YohgDAkhK
+gcfre+njjbDrPe4hGXwEwq1PRbMaE9F2NcQ4fgxsfOeDQfB4G7QW1ZPZAgMBAAGj
+gacwgaQwHQYDVR0OBBYEFPZunjZtSQL8kRpandP6tJ8H7qmzMHUGA1UdIwRuMGyA
+FPZunjZtSQL8kRpandP6tJ8H7qmzoVGkTzBNMQswCQYDVQQGEwJQTDERMA8GA1UE
+CBMITWFzb3ZpYW4xDTALBgNVBAoTBHByaXYxDTALBgNVBAsTBHByaXYxDTALBgNV
+BAMTBHByaXaCAQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQCWPPci
+PTLAZ/w6Cjy3Yjh9ptUthsLOaoRm1Fazk05MN9FJtmeRdleWlsxacdppt1Kdjxf3
+Zvps8ZgoRK9g360qi/XzjCfEaKUqNcFshDcg7sKcWJih/7r9ODZFw9c4XUetyA0m
+K6mdLjlzsqra5Rm4Vyhi3ZQqyVBbM1mwVs/rLw==
+-----END CERTIFICATE-----
--- /dev/null
+-----BEGIN CERTIFICATE REQUEST-----
+MIIBnjCCAQcCAQAwXjELMAkGA1UEBhMCUEwxETAPBgNVBAgTCE1hc292aWFuMQ8w
+DQYDVQQHEwZXYXJzYXcxDTALBgNVBAoTBHByaXYxDTALBgNVBAsTBHByaXYxDTAL
+BgNVBAMTBHByaXYwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKtozBpBeFAM
+9EM/no17kD3r1ovO2cG19NMudfPhsymXGzjGIHONps1hP+EceA/9JeKglW2pMzD+
+JHY95J0jsjk8mKWyIC99yH3VAHwRLG5YohgDAkhKgcfre+njjbDrPe4hGXwEwq1P
+RbMaE9F2NcQ4fgxsfOeDQfB4G7QW1ZPZAgMBAAGgADANBgkqhkiG9w0BAQUFAAOB
+gQBfWbLoBMhFCjsTklaKNKIoF4WRNmGXPBQt+BWZhlVjnxh1ncL3QX2M4r/ys3ax
+bKGm24i5XvUvZ1uR8SxOHGbuTzjRALBOgfb9X5mma/8ZytammJmgjdYkVvvRNFXL
+O+WaOykOlw1zUEUVK0VAmdQ5STPQDypyYwGF5JYL24F84A==
+-----END CERTIFICATE REQUEST-----
--- /dev/null
+V 140728143212Z 00 unknown /C=PL/ST=Masovian/O=priv/OU=priv/CN=priv
--- /dev/null
+unique_subject = yes
--- /dev/null
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 0 (0x0)
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=PL, ST=Masovian, O=priv, OU=priv, CN=priv
+ Validity
+ Not Before: Jul 29 14:32:12 2011 GMT
+ Not After : Jul 28 14:32:12 2014 GMT
+ Subject: C=PL, ST=Masovian, O=priv, OU=priv, CN=priv
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public Key: (1024 bit)
+ Modulus (1024 bit):
+ 00:ab:68:cc:1a:41:78:50:0c:f4:43:3f:9e:8d:7b:
+ 90:3d:eb:d6:8b:ce:d9:c1:b5:f4:d3:2e:75:f3:e1:
+ b3:29:97:1b:38:c6:20:73:8d:a6:cd:61:3f:e1:1c:
+ 78:0f:fd:25:e2:a0:95:6d:a9:33:30:fe:24:76:3d:
+ e4:9d:23:b2:39:3c:98:a5:b2:20:2f:7d:c8:7d:d5:
+ 00:7c:11:2c:6e:58:a2:18:03:02:48:4a:81:c7:eb:
+ 7b:e9:e3:8d:b0:eb:3d:ee:21:19:7c:04:c2:ad:4f:
+ 45:b3:1a:13:d1:76:35:c4:38:7e:0c:6c:7c:e7:83:
+ 41:f0:78:1b:b4:16:d5:93:d9
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ F6:6E:9E:36:6D:49:02:FC:91:1A:5A:9D:D3:FA:B4:9F:07:EE:A9:B3
+ X509v3 Authority Key Identifier:
+ keyid:F6:6E:9E:36:6D:49:02:FC:91:1A:5A:9D:D3:FA:B4:9F:07:EE:A9:B3
+ DirName:/C=PL/ST=Masovian/O=priv/OU=priv/CN=priv
+ serial:00
+
+ X509v3 Basic Constraints:
+ CA:TRUE
+ Signature Algorithm: sha1WithRSAEncryption
+ 96:3c:f7:22:3d:32:c0:67:fc:3a:0a:3c:b7:62:38:7d:a6:d5:
+ 2d:86:c2:ce:6a:84:66:d4:56:b3:93:4e:4c:37:d1:49:b6:67:
+ 91:76:57:96:96:cc:5a:71:da:69:b7:52:9d:8f:17:f7:66:fa:
+ 6c:f1:98:28:44:af:60:df:ad:2a:8b:f5:f3:8c:27:c4:68:a5:
+ 2a:35:c1:6c:84:37:20:ee:c2:9c:58:98:a1:ff:ba:fd:38:36:
+ 45:c3:d7:38:5d:47:ad:c8:0d:26:2b:a9:9d:2e:39:73:b2:aa:
+ da:e5:19:b8:57:28:62:dd:94:2a:c9:50:5b:33:59:b0:56:cf:
+ eb:2f
+-----BEGIN CERTIFICATE-----
+MIICuDCCAiGgAwIBAgIBADANBgkqhkiG9w0BAQUFADBNMQswCQYDVQQGEwJQTDER
+MA8GA1UECBMITWFzb3ZpYW4xDTALBgNVBAoTBHByaXYxDTALBgNVBAsTBHByaXYx
+DTALBgNVBAMTBHByaXYwHhcNMTEwNzI5MTQzMjEyWhcNMTQwNzI4MTQzMjEyWjBN
+MQswCQYDVQQGEwJQTDERMA8GA1UECBMITWFzb3ZpYW4xDTALBgNVBAoTBHByaXYx
+DTALBgNVBAsTBHByaXYxDTALBgNVBAMTBHByaXYwgZ8wDQYJKoZIhvcNAQEBBQAD
+gY0AMIGJAoGBAKtozBpBeFAM9EM/no17kD3r1ovO2cG19NMudfPhsymXGzjGIHON
+ps1hP+EceA/9JeKglW2pMzD+JHY95J0jsjk8mKWyIC99yH3VAHwRLG5YohgDAkhK
+gcfre+njjbDrPe4hGXwEwq1PRbMaE9F2NcQ4fgxsfOeDQfB4G7QW1ZPZAgMBAAGj
+gacwgaQwHQYDVR0OBBYEFPZunjZtSQL8kRpandP6tJ8H7qmzMHUGA1UdIwRuMGyA
+FPZunjZtSQL8kRpandP6tJ8H7qmzoVGkTzBNMQswCQYDVQQGEwJQTDERMA8GA1UE
+CBMITWFzb3ZpYW4xDTALBgNVBAoTBHByaXYxDTALBgNVBAsTBHByaXYxDTALBgNV
+BAMTBHByaXaCAQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQCWPPci
+PTLAZ/w6Cjy3Yjh9ptUthsLOaoRm1Fazk05MN9FJtmeRdleWlsxacdppt1Kdjxf3
+Zvps8ZgoRK9g360qi/XzjCfEaKUqNcFshDcg7sKcWJih/7r9ODZFw9c4XUetyA0m
+K6mdLjlzsqra5Rm4Vyhi3ZQqyVBbM1mwVs/rLw==
+-----END CERTIFICATE-----
--- /dev/null
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: DES-EDE3-CBC,E653123E49750191
+
+OgQe9fnwRSQjEqAuqts2/up+mCfMyiZLwi/ZfhZjBxsRD0n34J5NrLptcWMDNvPT
+TueYJ24eUhE61RE6u9VpcdYd0d/7sbR6i8jiBYa8R15frtTUaD1XCbhz3Sn6REbL
+qDrKW7hHuSKKRfb/6bHVGNGMCR6eCSw9isYcqFDlmRpGiYC5m2nxr/W1JFq4K/te
+KgvZ0kwE9DPeCdLVyHbZ7AcK0aDzUeZOFxxyHvQRLIbprx2DoFi+erPVvPfehJp1
+n2CVa2CXwkY4vIoCKn3KbtRqR+vHbc9UmlSvd2AINPEgCYAr11AGvDl9O6fdLXRJ
+PXq6TMv3se//4qPcyKEiXRhR64a0dxIutyPvESLrnz4BZGsQN695ym3s96x1IEtK
+yb7AGws3kr/zMVFilFFtHZgsMse9kzsMmoQZ31VfyIM1CpmieCVyN2gYV+iQN04f
+1HaT498quauFvxezDe9UC4d9yaFKAM8lqeuMwoisTCu18LR5jA4ODzEJDENnny4O
+ejLVKkdPViJOW5UwGpjl2MQYtmRyN6/FHjFIx9FEIClaxLiYMFXNxIGSWdq85JUb
+/VpkmCiJqjy2eIW137ThbmN2GblLg6l9Hkz1wTBqhqhBK/uznwE7Mh0VL3QNTnys
+4Ib2WoApWS3b9a6UAeybZvZ1vvK/9hryG19iwZsqpmuJoTTSlwZQbBYpVHRiSmrw
+S26rP4kBnId4ftf3oIGCwUgFXhj1cQ7V/PC4EAOzo0opAMQkI6TR1DP8gv1ESmIN
+mdrHvKbzmrRe5enDjrk3G2HVhd2+fPwC0Go8mORvxRtRfDDYeySEPQ==
+-----END RSA PRIVATE KEY-----
--- /dev/null
+#!/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.
+#
+
+pkill -9 openssl # if previously it was launched and openssl didn't close sockets
+
+OPENSSL_CONF=/opt/apps/widget/tests/vcore_certs/openssl.cnf openssl ocsp -index /opt/apps/widget/tests/vcore_certs/demoCA/index.txt -port 8881 -rsigner /opt/apps/widget/tests/vcore_certs/respcert.pem -rkey /opt/apps/widget/tests/vcore_certs/respcert.key -CA /opt/apps/widget/tests/vcore_certs/demoCA/cacert.pem
--- /dev/null
+#
+# OpenSSL example configuration file.
+# This is mostly being used for generation of certificate requests.
+#
+
+# This definition stops the following lines choking if HOME isn't
+# defined.
+HOME = .
+RANDFILE = $ENV::HOME/.rnd
+
+# Extra OBJECT IDENTIFIER info:
+#oid_file = $ENV::HOME/.oid
+oid_section = new_oids
+
+# To use this configuration file with the "-extfile" option of the
+# "openssl x509" utility, name here the section containing the
+# X.509v3 extensions to use:
+# extensions =
+# (Alternatively, use a configuration file that has only
+# X.509v3 extensions in its main [= default] section.)
+
+[ new_oids ]
+
+# We can add new OIDs in here for use by 'ca' and 'req'.
+# Add a simple OID like this:
+# testoid1=1.2.3.4
+# Or use config file substitution like this:
+# testoid2=${testoid1}.5.6
+
+####################################################################
+[ ca ]
+default_ca = CA_default # The default ca section
+
+####################################################################
+[ CA_default ]
+
+dir = ./demoCA # Where everything is kept
+certs = $dir/certs # Where the issued certs are kept
+crl_dir = $dir/crl # Where the issued crl are kept
+database = $dir/index.txt # database index file.
+#unique_subject = no # Set to 'no' to allow creation of
+ # several ctificates with same subject.
+new_certs_dir = $dir/newcerts # default place for new certs.
+
+certificate = $dir/cacert.pem # The CA certificate
+serial = $dir/serial # The current serial number
+crlnumber = $dir/crlnumber # the current crl number
+ # must be commented out to leave a V1 CRL
+crl = $dir/crl.pem # The current CRL
+private_key = $dir/private/cakey.pem# The private key
+RANDFILE = $dir/private/.rand # private random number file
+
+x509_extensions = usr_cert # The extentions to add to the cert
+
+# Comment out the following two lines for the "traditional"
+# (and highly broken) format.
+name_opt = ca_default # Subject Name options
+cert_opt = ca_default # Certificate field options
+
+# Extension copying option: use with caution.
+# copy_extensions = copy
+
+# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
+# so this is commented out by default to leave a V1 CRL.
+# crlnumber must also be commented out to leave a V1 CRL.
+
+#crl_extensions = crl_ext
+
+default_days = 365 # how long to certify for
+default_crl_days= 30 # how long before next CRL
+default_md = sha1 # which md to use.
+preserve = no # keep passed DN ordering
+
+# A few difference way of specifying how similar the request should look
+# For type CA, the listed attributes must be the same, and the optional
+# and supplied fields are just that :-)
+policy = policy_match
+
+# For the CA policy
+[ policy_match ]
+countryName = match
+stateOrProvinceName = match
+organizationName = match
+organizationalUnitName = optional
+commonName = supplied
+emailAddress = optional
+
+# For the 'anything' policy
+# At this point in time, you must list all acceptable 'object'
+# types.
+[ policy_anything ]
+countryName = optional
+stateOrProvinceName = optional
+localityName = optional
+organizationName = optional
+organizationalUnitName = optional
+commonName = supplied
+emailAddress = optional
+
+####################################################################
+[ req ]
+default_bits = 1024
+default_keyfile = privkey.pem
+distinguished_name = req_distinguished_name
+attributes = req_attributes
+x509_extensions = v3_ca # The extentions to add to the self signed cert
+
+# Passwords for private keys if not present they will be prompted for
+# input_password = secret
+# output_password = secret
+
+# This sets a mask for permitted string types. There are several options.
+# default: PrintableString, T61String, BMPString.
+# pkix : PrintableString, BMPString.
+# utf8only: only UTF8Strings.
+# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
+# MASK:XXXX a literal mask value.
+# WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings
+# so use this option with caution!
+string_mask = nombstr
+
+# req_extensions = v3_req # The extensions to add to a certificate request
+
+[ req_distinguished_name ]
+countryName = Country Name (2 letter code)
+countryName_default = AU
+countryName_min = 2
+countryName_max = 2
+
+stateOrProvinceName = State or Province Name (full name)
+stateOrProvinceName_default = Some-State
+
+localityName = Locality Name (eg, city)
+
+0.organizationName = Organization Name (eg, company)
+0.organizationName_default = Internet Widgits Pty Ltd
+
+# we can do this but it is not needed normally :-)
+#1.organizationName = Second Organization Name (eg, company)
+#1.organizationName_default = World Wide Web Pty Ltd
+
+organizationalUnitName = Organizational Unit Name (eg, section)
+#organizationalUnitName_default =
+
+commonName = Common Name (eg, YOUR name)
+commonName_max = 64
+
+emailAddress = Email Address
+emailAddress_max = 64
+
+# SET-ex3 = SET extension number 3
+
+[ req_attributes ]
+challengePassword = A challenge password
+challengePassword_min = 4
+challengePassword_max = 20
+
+unstructuredName = An optional company name
+
+[ usr_cert ]
+
+# These extensions are added when 'ca' signs a request.
+
+# This goes against PKIX guidelines but some CAs do it and some software
+# requires this to avoid interpreting an end user certificate as a CA.
+
+basicConstraints=CA:FALSE
+crlDistributionPoints = URI:http://localhost/my.crl
+
+# Here are some examples of the usage of nsCertType. If it is omitted
+# the certificate can be used for anything *except* object signing.
+
+# This is OK for an SSL server.
+# nsCertType = server
+
+# For an object signing certificate this would be used.
+# nsCertType = objsign
+
+# For normal client use this is typical
+# nsCertType = client, email
+
+# and for everything including object signing:
+# nsCertType = client, email, objsign
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# This will be displayed in Netscape's comment listbox.
+nsComment = "OpenSSL Generated Certificate"
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer
+
+# This stuff is for subjectAltName and issuerAltname.
+# Import the email address.
+# subjectAltName=email:copy
+# An alternative to produce certificates that aren't
+# deprecated according to PKIX.
+# subjectAltName=email:move
+
+# Copy subject details
+# issuerAltName=issuer:copy
+
+#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
+#nsBaseUrl
+#nsRevocationUrl
+#nsRenewalUrl
+#nsCaPolicyUrl
+#nsSslServerName
+
+[ v3_req ]
+
+# Extensions to add to a certificate request
+
+basicConstraints = CA:FALSE
+keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+[ v3_ca ]
+
+
+# Extensions for a typical CA
+
+
+# PKIX recommendation.
+
+subjectKeyIdentifier=hash
+
+authorityKeyIdentifier=keyid:always,issuer:always
+
+# OCSP and CRL local servers - for test certificates
+authorityInfoAccess=OCSP;URI:http://localhost:8881/
+crlDistributionPoints=URI:http://localhost/my.crl
+
+# This is what PKIX recommends but some broken software chokes on critical
+# extensions.
+#basicConstraints = critical,CA:true
+# So we do this instead.
+basicConstraints = CA:true
+
+# Key usage: this is typical for a CA certificate. However since it will
+# prevent it being used as an test self-signed certificate it is best
+# left out by default.
+# keyUsage = cRLSign, keyCertSign
+
+# Some might want this also
+# nsCertType = sslCA, emailCA
+
+# Include email address in subject alt name: another PKIX recommendation
+# subjectAltName=email:copy
+# Copy issuer details
+# issuerAltName=issuer:copy
+
+# DER hex encoding of an extension: beware experts only!
+# obj=DER:02:03
+# Where 'obj' is a standard or added object
+# You can even override a supported extension:
+# basicConstraints= critical, DER:30:03:01:01:FF
+
+[ crl_ext ]
+
+# CRL extensions.
+# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
+
+# issuerAltName=issuer:copy
+authorityKeyIdentifier=keyid:always,issuer:always
+crlDistributionPoints=crldp1_section
+URI=http://localhost/my.crl
+
+[ proxy_cert_ext ]
+# These extensions should be added when creating a proxy certificate
+
+# This goes against PKIX guidelines but some CAs do it and some software
+# requires this to avoid interpreting an end user certificate as a CA.
+
+basicConstraints=CA:FALSE
+
+# Here are some examples of the usage of nsCertType. If it is omitted
+# the certificate can be used for anything *except* object signing.
+
+# This is OK for an SSL server.
+# nsCertType = server
+
+# For an object signing certificate this would be used.
+# nsCertType = objsign
+
+# For normal client use this is typical
+# nsCertType = client, email
+
+# and for everything including object signing:
+# nsCertType = client, email, objsign
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# This will be displayed in Netscape's comment listbox.
+nsComment = "OpenSSL Generated Certificate"
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer:always
+
+# This stuff is for subjectAltName and issuerAltname.
+# Import the email address.
+# subjectAltName=email:copy
+# An alternative to produce certificates that aren't
+# deprecated according to PKIX.
+# subjectAltName=email:move
+
+# Copy subject details
+# issuerAltName=issuer:copy
+
+#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
+#nsBaseUrl
+#nsRevocationUrl
+#nsRenewalUrl
+#nsCaPolicyUrl
+#nsSslServerName
+
+# This really needs to be in place for it to be a proxy certificate.
+proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
+
+[ my_v3_ext ]
+basicConstraints = CA:true
+
+[ ocsp_cert ]
+extendedKeyUsage = OCSP Signing
\ No newline at end of file
--- /dev/null
+-----BEGIN CERTIFICATE-----
+MIIEuDCCA6CgAwIBAgIBBDANBgkqhkiG9w0BAQUFADCBtDELMAkGA1UEBhMCQlIx
+EzARBgNVBAoTCklDUC1CcmFzaWwxPTA7BgNVBAsTNEluc3RpdHV0byBOYWNpb25h
+bCBkZSBUZWNub2xvZ2lhIGRhIEluZm9ybWFjYW8gLSBJVEkxETAPBgNVBAcTCEJy
+YXNpbGlhMQswCQYDVQQIEwJERjExMC8GA1UEAxMoQXV0b3JpZGFkZSBDZXJ0aWZp
+Y2Fkb3JhIFJhaXogQnJhc2lsZWlyYTAeFw0wMTExMzAxMjU4MDBaFw0xMTExMzAy
+MzU5MDBaMIG0MQswCQYDVQQGEwJCUjETMBEGA1UEChMKSUNQLUJyYXNpbDE9MDsG
+A1UECxM0SW5zdGl0dXRvIE5hY2lvbmFsIGRlIFRlY25vbG9naWEgZGEgSW5mb3Jt
+YWNhbyAtIElUSTERMA8GA1UEBxMIQnJhc2lsaWExCzAJBgNVBAgTAkRGMTEwLwYD
+VQQDEyhBdXRvcmlkYWRlIENlcnRpZmljYWRvcmEgUmFpeiBCcmFzaWxlaXJhMIIB
+IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwPMudwX/hvm+Uh2b/lQAcHVA
+isamaLkWdkwP9/S/tOKIgRrL6Oy+ZIGlOUdd6uYtk9Ma/3pUpgcfNAj0vYm5gsyj
+Qo9emsc+x6m4VWwk9iqMZSCK5EQkAq/Ut4n7KuLE1+gdftwdIgxfUsPt4CyNrY50
+QV57KM2UT8x5rrmzEjr7TICGpSUAl2gVqe6xaii+bmYR1QrmWaBSAG59LrkrjrYt
+bRhFboUDe1DK+6T8s5L6k8c8okpbHpa9veMztDVC9sPJ60MWXh6anVKo1UcLcbUR
+yEeNvZneVRKAAU6ouwdjDvwlsaKydFKwed0ToQ47bmUKgcm+wV3eTRk36UOnTwID
+AQABo4HSMIHPME4GA1UdIARHMEUwQwYFYEwBAQAwOjA4BggrBgEFBQcCARYsaHR0
+cDovL2FjcmFpei5pY3BicmFzaWwuZ292LmJyL0RQQ2FjcmFpei5wZGYwPQYDVR0f
+BDYwNDAyoDCgLoYsaHR0cDovL2FjcmFpei5pY3BicmFzaWwuZ292LmJyL0xDUmFj
+cmFpei5jcmwwHQYDVR0OBBYEFIr68VeEERM1kEL6V0lUaQ2kxPA3MA8GA1UdEwEB
+/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQAZA5c1
+U/hgIh6OcgLAfiJgFWpvmDZWqlV30/bHFpj8iBobJSm5uDpt7TirYh1Uxe3fQaGl
+YjJe+9zd+izPRbBqXPVQA34EXcwk4qpWuf1hHriWfdrx8AcqSqr6CuQFwSr75Fos
+SzlwDADa70mT7wZjAmQhnZx2xJ6wfWlT9VQfS//JYeIc7Fue2JNLd00UOSMMaiK/
+t79enKNHEA2fupH3vEigf5Eh4bVAN5VohrTm6MY53x7XQZZr1ME7a55lFEnSeT0u
+mlOAjR2mAbvSM5X5oSZNrmetdzyTj2flCM8CC7MLab0kkdngRIlUBGHF1/S5nmPb
+K+9A46sd33oqK8n8
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIHPTCCBSWgAwIBAgIBADANBgkqhkiG9w0BAQQFADB5MRAwDgYDVQQKEwdSb290
+IENBMR4wHAYDVQQLExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNB
+IENlcnQgU2lnbmluZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRA
+Y2FjZXJ0Lm9yZzAeFw0wMzAzMzAxMjI5NDlaFw0zMzAzMjkxMjI5NDlaMHkxEDAO
+BgNVBAoTB1Jvb3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEi
+MCAGA1UEAxMZQ0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJ
+ARYSc3VwcG9ydEBjYWNlcnQub3JnMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
+CgKCAgEAziLA4kZ97DYoB1CW8qAzQIxL8TtmPzHlawI229Z89vGIj053NgVBlfkJ
+8BLPRoZzYLdufujAWGSuzbCtRRcMY/pnCujW0r8+55jE8Ez64AO7NV1sId6eINm6
+zWYyN3L69wj1x81YyY7nDl7qPv4coRQKFWyGhFtkZip6qUtTefWIonvuLwphK42y
+fk1WpRPs6tqSnqxEQR5YYGUFZvjARL3LlPdCfgv3ZWiYUQXw8wWRBB0bF4LsyFe7
+w2t6iPGwcswlWyCR7BYCEo8y6RcYSNDHBS4CMEK4JZwFaz+qOqfrU0j36NK2B5jc
+G8Y0f3/JHIJ6BVgrCFvzOKKrF11myZjXnhCLotLddJr3cQxyYN/Nb5gznZY0dj4k
+epKwDpUeb+agRThHqtdB7Uq3EvbXG4OKDy7YCbZZ16oE/9KTfWgu3YtLq1i6L43q
+laegw1SJpfvbi1EinbLDvhG+LJGGi5Z4rSDTii8aP8bQUWWHIbEZAWV/RRyH9XzQ
+QUxPKZgh/TMfdQwEUfoZd9vUFBzugcMd9Zi3aQaRIt0AUMyBMawSB3s42mhb5ivU
+fslfrejrckzzAeVLIL+aplfKkQABi6F1ITe1Yw1nPkZPcCBnzsXWWdsC4PDSy826
+YreQQejdIOQpvGQpQsgi3Hia/0PsmBsJUUtaWsJx8cTLc6nloQsCAwEAAaOCAc4w
+ggHKMB0GA1UdDgQWBBQWtTIb1Mfz4OaO873SsDrusjkY0TCBowYDVR0jBIGbMIGY
+gBQWtTIb1Mfz4OaO873SsDrusjkY0aF9pHsweTEQMA4GA1UEChMHUm9vdCBDQTEe
+MBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0
+IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2Vy
+dC5vcmeCAQAwDwYDVR0TAQH/BAUwAwEB/zAyBgNVHR8EKzApMCegJaAjhiFodHRw
+czovL3d3dy5jYWNlcnQub3JnL3Jldm9rZS5jcmwwMAYJYIZIAYb4QgEEBCMWIWh0
+dHBzOi8vd3d3LmNhY2VydC5vcmcvcmV2b2tlLmNybDA0BglghkgBhvhCAQgEJxYl
+aHR0cDovL3d3dy5jYWNlcnQub3JnL2luZGV4LnBocD9pZD0xMDBWBglghkgBhvhC
+AQ0ESRZHVG8gZ2V0IHlvdXIgb3duIGNlcnRpZmljYXRlIGZvciBGUkVFIGhlYWQg
+b3ZlciB0byBodHRwOi8vd3d3LmNhY2VydC5vcmcwDQYJKoZIhvcNAQEEBQADggIB
+ACjH7pyCArpcgBLKNQodgW+JapnM8mgPf6fhjViVPr3yBsOQWqy1YPaZQwGjiHCc
+nWKdpIevZ1gNMDY75q1I08t0AoZxPuIrA2jxNGJARjtT6ij0rPtmlVOKTV39O9lg
+18p5aTuxZZKmxoGCXJzN600BiqXfEVWqFcofN8CCmHBh22p8lqOOLlQ+TyGpkO/c
+gr/c6EWtTZBzCDyUZbAEmXZ/4rzCahWqlwQ3JNgelE5tDlG+1sSPypZt90Pf6DBl
+Jzt7u0NDY8RD97LsaMzhGY4i+5jhe1o+ATc7iwiwovOVThrLm82asduycPAtStvY
+sONvRUgzEv/+PDIqVPfE94rwiCPCR/5kenHA0R6mY7AHfqQv0wGP3J8rtsYIqQ+T
+SCX8Ev2fQtzzxD72V7DX3WnRBnc0CkvSyqD/HMaMyRa+xMwyN2hzXwj7UfdJUzYF
+CpUCTPJ5GhD22Dp1nPMd8aINcGeGG7MW9S/lpOt5hvk9C8JzC6WZrG/8Z7jlLwum
+GCSNe9FINSkYQKyTYOGWhlC0elnYjyELn8+CkcY7v2vcB5G5l1YjqrZslMZIBjzk
+zk6q5PYvCdxTby78dOs6Y5nCpqyJvKeyRKANihDjbPIky/qbn3BHLt4Ui9SyIAmW
+omTxJBzcoTWcFbLUvFUufQb1nA5V9FrWk9p2rSVzTMVD
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIGCDCCA/CgAwIBAgIBATANBgkqhkiG9w0BAQQFADB5MRAwDgYDVQQKEwdSb290
+IENBMR4wHAYDVQQLExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNB
+IENlcnQgU2lnbmluZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRA
+Y2FjZXJ0Lm9yZzAeFw0wNTEwMTQwNzM2NTVaFw0zMzAzMjgwNzM2NTVaMFQxFDAS
+BgNVBAoTC0NBY2VydCBJbmMuMR4wHAYDVQQLExVodHRwOi8vd3d3LkNBY2VydC5v
+cmcxHDAaBgNVBAMTE0NBY2VydCBDbGFzcyAzIFJvb3QwggIiMA0GCSqGSIb3DQEB
+AQUAA4ICDwAwggIKAoICAQCrSTURSHzSJn5TlM9Dqd0o10Iqi/OHeBlYfA+e2ol9
+4fvrcpANdKGWZKufoCSZc9riVXbHF3v1BKxGuMO+f2SNEGwk82GcwPKQ+lHm9WkB
+Y8MPVuJKQs/iRIwlKKjFeQl9RrmK8+nzNCkIReQcn8uUBByBqBSzmGXEQ+xOgo0J
+0b2qW42S0OzekMV/CsLj6+YxWl50PpczWejDAz1gM7/30W9HxM3uYoNSbi4ImqTZ
+FRiRpoWSR7CuSOtttyHshRpocjWr//AQXcD0lKdq1TuSfkyQBX6TwSyLpI5idBVx
+bgtxA+qvFTia1NIFcm+M+SvrWnIl+TlG43IbPgTDZCciECqKT1inA62+tC4T7V2q
+SNfVfdQqe1z6RgRQ5MwOQluM7dvyz/yWk+DbETZUYjQ4jwxgmzuXVjit89Jbi6Bb
+6k6WuHzX1aCGcEDTkSm3ojyt9Yy7zxqSiuQ0e8DYbF/pCsLDpyCaWt8sXVJcukfV
+m+8kKHA4IC/VfynAskEDaJLM4JzMl0tF7zoQCqtwOpiVcK01seqFK6QcgCExqa5g
+eoAmSAC4AcCTY1UikTxW56/bOiXzjzFU6iaLgVn5odFTEcV7nQP2dBHgbbEsPyyG
+kZlxmqZ3izRg0RS0LKydr4wQ05/EavhvE/xzWfdmQnQeiuP43NJvmJzLR5iVQAX7
+6QIDAQABo4G/MIG8MA8GA1UdEwEB/wQFMAMBAf8wXQYIKwYBBQUHAQEEUTBPMCMG
+CCsGAQUFBzABhhdodHRwOi8vb2NzcC5DQWNlcnQub3JnLzAoBggrBgEFBQcwAoYc
+aHR0cDovL3d3dy5DQWNlcnQub3JnL2NhLmNydDBKBgNVHSAEQzBBMD8GCCsGAQQB
+gZBKMDMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93d3cuQ0FjZXJ0Lm9yZy9pbmRleC5w
+aHA/aWQ9MTAwDQYJKoZIhvcNAQEEBQADggIBAH8IiKHaGlBJ2on7oQhy84r3HsQ6
+tHlbIDCxRd7CXdNlafHCXVRUPIVfuXtCkcKZ/RtRm6tGpaEQU55tiKxzbiwzpvD0
+nuB1wT6IRanhZkP+VlrRekF490DaSjrxC1uluxYG5sLnk7mFTZdPsR44Q4Dvmw2M
+77inYACHV30eRBzLI++bPJmdr7UpHEV5FpZNJ23xHGzDwlVks7wU4vOkHx4y/CcV
+Bc/dLq4+gmF78CEQGPZE6lM5+dzQmiDgxrvgu1pPxJnIB721vaLbLmINQjRBvP+L
+ivVRIqqIMADisNS8vmW61QNXeZvo3MhN+FDtkaVSKKKs+zZYPumUK5FQhxvWXtaM
+zPcPEAxSTtAWYeXlCmy/F8dyRlecmPVsYGN6b165Ti/Iubm7aoW8mA3t+T6XhDSU
+rgCvoeXnkm5OvfPi2RSLXNLrAWygF6UtEOucekq9ve7O/e0iQKtwOIj1CodqwqsF
+YMlIBdpTwd5Ed2qz8zw87YC8pjhKKSRf/lk7myV6VmMAZLldpGJ9VzZPrYPvH5JT
+oI53V93lYRE9IwCQTDz6o2CTBKOvNfYOao9PSmCnhQVsRqGP9Md246FZV/dxssRu
+FFxtbUFm3xuTsdQAw+7Lzzw9IYCpX2Nl/N3gX6T0K/CFcUHUZyX7GrGXrtaZghNB
+0m6lG5kngOcLqagA
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIESzCCAzOgAwIBAgIJAJigUTEEXRQpMA0GCSqGSIb3DQEBBQUAMHYxCzAJBgNV
+BAYTAkRFMQ8wDQYDVQQIEwZIZXNzZW4xDjAMBgNVBAcTBUZ1bGRhMRAwDgYDVQQK
+EwdEZWJjb25mMRMwEQYDVQQDEwpEZWJjb25mIENBMR8wHQYJKoZIhvcNAQkBFhBq
+b2VyZ0BkZWJpYW4ub3JnMB4XDTA1MTEwNTE3NTUxNFoXDTE1MTEwMzE3NTUxNFow
+djELMAkGA1UEBhMCREUxDzANBgNVBAgTBkhlc3NlbjEOMAwGA1UEBxMFRnVsZGEx
+EDAOBgNVBAoTB0RlYmNvbmYxEzARBgNVBAMTCkRlYmNvbmYgQ0ExHzAdBgkqhkiG
+9w0BCQEWEGpvZXJnQGRlYmlhbi5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
+ggEKAoIBAQCvbOo0SrIwI5IMlsshH8WF3dHB9r9JlSKhMPaybawa1EyvZspMQ3wa
+F5qxNf3Sj+NElEmjseEqvCZiIIzqwerHu0Qw62cDYCdCd2+Wb5m0bPYB5CGHiyU1
+eNP0je42O0YeXG2BvUujN8AviocVo39X2YwNQ0ryy4OaqYgm2pRlbtT2ESbF+SfV
+Y2iqQj/f8ymF+lHo/pz8tbAqxWcqaSiHFAVQJrdqtFhtoodoNiE3q76zJoUkZTXB
+k60Yc3MJSnatZCpnsSBr/D7zpntl0THrUjjtdRWCjQVhqfhM1yZJV+ApbLdheFh0
+ZWlSxdnp25p0q0XYw/7G92ELyFDfBUUNAgMBAAGjgdswgdgwHQYDVR0OBBYEFMuV
+dFNb4mCWUFbcP5LOtxFLrEVTMIGoBgNVHSMEgaAwgZ2AFMuVdFNb4mCWUFbcP5LO
+txFLrEVToXqkeDB2MQswCQYDVQQGEwJERTEPMA0GA1UECBMGSGVzc2VuMQ4wDAYD
+VQQHEwVGdWxkYTEQMA4GA1UEChMHRGViY29uZjETMBEGA1UEAxMKRGViY29uZiBD
+QTEfMB0GCSqGSIb3DQEJARYQam9lcmdAZGViaWFuLm9yZ4IJAJigUTEEXRQpMAwG
+A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAGZXxHg4mnkvilRIM1EQfGdY
+S5b/WcyF2MYSTeTvK4aIB6VHwpZoZCnDGj2m2D3CkHT0upAD9o0zM1tdsfncLzV+
+mDT/jNmBtYo4QXx5vEPwvEIcgrWjwk7SyaEUhZjtolTkHB7ACl0oD0r71St4iEPR
+qTUCEXk2E47bg1Fz58wNt/yo2+4iqiRjg1XCH4evkQuhpW+dTZnDyFNqwSYZapOE
+TBA+9zBb6xD1KM2DdY7r4GiyYItN0BKLfuWbh9LXGbl1C+f4P11g+m2MPiavIeCe
+1iazG5pcS3KoTLACsYlEX24TINtg4kcuS81XdllcnsV3Kdts0nIqPj6uhTTZD0k=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDvjCCA3ygAwIBAgIFJQaThoEwCwYHKoZIzjgEAwUAMIGFMQswCQYDVQQGEwJG
+UjEPMA0GA1UECBMGRnJhbmNlMQ4wDAYDVQQHEwVQYXJpczEQMA4GA1UEChMHUE0v
+U0dETjEOMAwGA1UECxMFRENTU0kxDjAMBgNVBAMTBUlHQy9BMSMwIQYJKoZIhvcN
+AQkBFhRpZ2NhQHNnZG4ucG0uZ291di5mcjAeFw0wMjEyMTMxNDM5MTVaFw0yMDEw
+MTcxNDM5MTRaMIGFMQswCQYDVQQGEwJGUjEPMA0GA1UECBMGRnJhbmNlMQ4wDAYD
+VQQHEwVQYXJpczEQMA4GA1UEChMHUE0vU0dETjEOMAwGA1UECxMFRENTU0kxDjAM
+BgNVBAMTBUlHQy9BMSMwIQYJKoZIhvcNAQkBFhRpZ2NhQHNnZG4ucG0uZ291di5m
+cjCCAbYwggErBgcqhkjOOAQBMIIBHgKBgQCFkMImdk9zDzJfTO4XPdAAmLbAdWws
+ZiEMZh19RyTo3CyhFqO77OIXrwY6vc1pcc3MgWJ0dgQpAgrDMtmFFxpUu4gmjVsx
+8GpxQC+4VOgLY8Cvmcd/UDzYg07EIRto8BwCpPJ/JfUxwzV2V3N713aAX+cEoKZ/
+s+kgxC6nZCA7oQIVALME/JYjkdW2uKIGngsEPbXAjdhDAoGADh/uqWJx94UBm31c
+9d8ZTBfRGRnmSSRVFDgPWgA69JD4BR5da8tKz+1HjfMhDXljbMH86ixpD5Ka1Z0V
+pRYUPbyAoB37tsmXMJY7kjyD19d5VdaZboUjVvhH6UJy5lpNNNGSvFl4fqkxyvw+
+pq1QV0N5RcvK120hlXdfHUX+YKYDgYQAAoGAQGr7IuKJcYIvJRMjxwl43KxXY2xC
+aoCiM/bv117MfI94aNf1UusGhp7CbYAY9CXuL60P0oPMAajbaTE5Z34AuITeHq3Y
+CNMHwxalip8BHqSSGmGiQsXeK7T+r1rPXsccZ1c5ikGDZ4xn5gUaCyy2rCmb+fOJ
+6VAfCbAbAjmNKwejdzB1MA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgFGMBUG
+A1UdIAQOMAwwCgYIKoF6AXkBAQEwHQYDVR0OBBYEFPkeNRcUf8idzpKblYbLNxs0
+MQhSMB8GA1UdIwQYMBaAFPkeNRcUf8idzpKblYbLNxs0MQhSMAsGByqGSM44BAMF
+AAMvADAsAhRVh+CJA5eVyEYU5AO9Tm7GxX0rmQIUBCqsU5u1WxoZ5lEXicDX5/Ob
+sRQ=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEAjCCAuqgAwIBAgIFORFFEJQwDQYJKoZIhvcNAQEFBQAwgYUxCzAJBgNVBAYT
+AkZSMQ8wDQYDVQQIEwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQ
+TS9TR0ROMQ4wDAYDVQQLEwVEQ1NTSTEOMAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG
+9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZyMB4XDTAyMTIxMzE0MjkyM1oXDTIw
+MTAxNzE0MjkyMlowgYUxCzAJBgNVBAYTAkZSMQ8wDQYDVQQIEwZGcmFuY2UxDjAM
+BgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVEQ1NTSTEO
+MAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2
+LmZyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsh/R0GLFMzvABIaI
+s9z4iPf930Pfeo2aSVz2TqrMHLmh6yeJ8kbpO0px1R2OLc/mratjUMdUC24SyZA2
+xtgv2pGqaMVy/hcKshd+ebUyiHDKcMCWSo7kVc0dJ5S/znIq7Fz5cyD+vfcuiWe4
+u0dzEvfRNWk68gq5rv9GQkaiv6GFGvm/5P9JhfejcIYyHF2fYPepraX/z9E0+X1b
+F8bc1g4oa8Ld8fUzaJ1O/Id8NhLWo4DoQw1VYZTqZDdH6nfK0LJYBcNdfrGoRpAx
+Vs5wKpayMLh35nnAvSk7/ZR3TL0gzUEl4C7HG7vupARB0l2tEmqKm0f7yd1GQOGd
+PDPQtQIDAQABo3cwdTAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBRjAVBgNV
+HSAEDjAMMAoGCCqBegF5AQEBMB0GA1UdDgQWBBSjBS8YYFDCiQrdKyFP/45OqDAx
+NjAfBgNVHSMEGDAWgBSjBS8YYFDCiQrdKyFP/45OqDAxNjANBgkqhkiG9w0BAQUF
+AAOCAQEABdwm2Pp3FURo/C9mOnTgXeQp/wYHE4RKq89toB9RlPhJy3Q2FLwV3duJ
+L92PoF189RLrn544pEfMs5bZvpwlqwN+Mw+VgQ39FuCIvjfwbF3QMZsyK10XZZOY
+YLxuj7GoPB7ZHPOpJkL5ZB3C55L29B5aqhlSXa/oovdgoPaN8In1buAKBQGVyYsg
+Crpa/JosPL3Dt8ldeCUFP1YUmwza+zpI/pdpXsoQhvdOlgQITeywvl3cO45Pwf2a
+NjSaTFR+FwNIlQgRHAdvhQh+XU3Endv7rs6y0bO4g2wdsrN58dhwmX7wEwLOXt1R
+0982gaEbeC9xs/FZTEYYKKuF0mBWWg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDtTCCAp2gAwIBAgIRANAeQJAAAEZSAAAAAQAAAAQwDQYJKoZIhvcNAQEFBQAw
+gYkxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJEQzETMBEGA1UEBxMKV2FzaGluZ3Rv
+bjEXMBUGA1UEChMOQUJBLkVDT00sIElOQy4xGTAXBgNVBAMTEEFCQS5FQ09NIFJv
+b3QgQ0ExJDAiBgkqhkiG9w0BCQEWFWFkbWluQGRpZ3NpZ3RydXN0LmNvbTAeFw05
+OTA3MTIxNzMzNTNaFw0wOTA3MDkxNzMzNTNaMIGJMQswCQYDVQQGEwJVUzELMAkG
+A1UECBMCREMxEzARBgNVBAcTCldhc2hpbmd0b24xFzAVBgNVBAoTDkFCQS5FQ09N
+LCBJTkMuMRkwFwYDVQQDExBBQkEuRUNPTSBSb290IENBMSQwIgYJKoZIhvcNAQkB
+FhVhZG1pbkBkaWdzaWd0cnVzdC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
+ggEKAoIBAQCx0xHgeVVDBwhMywVCAOINg0Y95JO6tgbTDVm9PsHOQ2cBiiGo77zM
+0KLMsFWWU4RmBQDaREmA2FQKpSWGlO1jVv9wbKOhGdJ4vmgqRF4vz8wYXke8OrFG
+PR7wuSw0X4x8TAgpnUBV6zx9g9618PeKgw6hTLQ6pbNfWiKX7BmbwQVo/ea3qZGU
+LOR4SCQaJRk665WcOQqKz0Ky8BzVX/tr7WhWezkscjiw7pOp03t3POtxA6k4ShZs
+iSrK2jMTecJVjO2cu/LLWxD4LmE1xilMKtAqY9FlWbT4zfn0AIS2V0KFnTKo+SpU
++/94Qby9cSj0u5C8/5Y0BONFnqFGKECBAgMBAAGjFjAUMBIGA1UdEwEB/wQIMAYB
+Af8CAQgwDQYJKoZIhvcNAQEFBQADggEBAARvJYbk5pYntNlCwNDJALF/VD6Hsm0k
+qS8Kfv2kRLD4VAe9G52dyntQJHsRW0mjpr8SdNWJt7cvmGQlFLdh6X9ggGvTZOir
+vRrWUfrAtF13Gn9kCF55xgVM8XrdTX3O5kh7VNJhkoHWG9YA8A6eKHegTYjHInYZ
+w8eeG6Z3ePhfm1bR8PIXrI6dWeYf/le22V7hXZ9F7GFoGUHhsiAm/lowdiT/QHI8
+eZ98IkirRs3bs4Ysj78FQdPB4xTjQRcm0HyncUwZ6EoPclgxfexgeqMiKL0ZJGA/
+O4dzwGvky663qyVDslUte6sGDnVdNOVdc22esnVApVnJTzFxiNmIf1Q=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIID5jCCAs6gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBgzELMAkGA1UEBhMCVVMx
+HTAbBgNVBAoTFEFPTCBUaW1lIFdhcm5lciBJbmMuMRwwGgYDVQQLExNBbWVyaWNh
+IE9ubGluZSBJbmMuMTcwNQYDVQQDEy5BT0wgVGltZSBXYXJuZXIgUm9vdCBDZXJ0
+aWZpY2F0aW9uIEF1dGhvcml0eSAxMB4XDTAyMDUyOTA2MDAwMFoXDTM3MTEyMDE1
+MDMwMFowgYMxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRBT0wgVGltZSBXYXJuZXIg
+SW5jLjEcMBoGA1UECxMTQW1lcmljYSBPbmxpbmUgSW5jLjE3MDUGA1UEAxMuQU9M
+IFRpbWUgV2FybmVyIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMTCCASIw
+DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJnej8Mlo2k06AX3dLm/WpcZuS+U
+0pPlLYnKhHw/EEMbjIt8hFj4JHxIzyr9wBXZGH6EGhfT257XyuTZ16pYUYfw8ItI
+TuLCxFlpMGK2MKKMCxGZYTVtfu/FsRkGIBKOQuHfD5YQUqjPnF+VFNivO3ULMSAf
+RC+iYkGzuxgh28pxPIzstrkNn+9R7017EvILDOGsQI93f7DKeHEMXRZxcKLXwjqF
+zQ6axOAAsNUl6twr5JQtOJyJQVdkKGUZHLZEtMgxa44Be3ZZJX8VHIQIfHNlIAqh
+BC4aMqiaILGcLCFZ5/vP7nAtCMpjPiybkxlqpMKX/7eGV4iFbJ4VFitNLLMCAwEA
+AaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUoTYwFsuGkABFgFOxj8jY
+PXy+XxIwHwYDVR0jBBgwFoAUoTYwFsuGkABFgFOxj8jYPXy+XxIwDgYDVR0PAQH/
+BAQDAgGGMA0GCSqGSIb3DQEBBQUAA4IBAQCKIBilvrMvtKaEAEAwKfq0FHNMeUWn
+9nDg6H5kHgqVfGphwu9OH77/yZkfB2FK4V1Mza3u0FIy2VkyvNp5ctZ7CegCgTXT
+Ct8RHcl5oIBN/lrXVtbtDyqvpxh1MwzqwWEFT2qaifKNuZ8u77BfWgDrvq2g+EQF
+Z7zLBO+eZMXpyD8Fv8YvBxzDNnGGyjhmSs3WuEvGbKeXO/oTLW4jYYehY0KswsuX
+n2Fozy1MBJ3XJU8KDk2QixhWqJNIV9xvrr2eZ1d3iVCzvhGbRWeDhhmH05i9CBoW
+H1iCC+GWaQVLjuyDUTEH1dSf/1l7qG6Fz9NLqUmwX7A5KGgOc90lmt4S
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF5jCCA86gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBgzELMAkGA1UEBhMCVVMx
+HTAbBgNVBAoTFEFPTCBUaW1lIFdhcm5lciBJbmMuMRwwGgYDVQQLExNBbWVyaWNh
+IE9ubGluZSBJbmMuMTcwNQYDVQQDEy5BT0wgVGltZSBXYXJuZXIgUm9vdCBDZXJ0
+aWZpY2F0aW9uIEF1dGhvcml0eSAyMB4XDTAyMDUyOTA2MDAwMFoXDTM3MDkyODIz
+NDMwMFowgYMxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRBT0wgVGltZSBXYXJuZXIg
+SW5jLjEcMBoGA1UECxMTQW1lcmljYSBPbmxpbmUgSW5jLjE3MDUGA1UEAxMuQU9M
+IFRpbWUgV2FybmVyIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMjCCAiIw
+DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALQ3WggWmRToVbEbJGv8x4vmh6mJ
+7ouZzU9AhqS2TcnZsdw8TQ2FTBVsRotSeJ/4I/1n9SQ6aF3Q92RhQVSji6UI0ilb
+m2BPJoPRYxJWSXakFsKlnUWsi4SVqBax7J/qJBrvuVdcmiQhLE0OcR+mrF1FdAOY
+xFSMFkpBd4aVdQxHAWZg/BXxD+r1FHjHDtdugRxev17nOirYlxcwfACtCJ0zr7iZ
+YYCLqJV+FNwSbKTQ2O9ASQI2+W6p1h2WVgSysy0WVoaP2SBXgM1nEG2wTPDaRrbq
+JS5Gr42whTg0ixQmgiusrpkLjhTXUr2eacOGAgvqdnUxCc4zGSGFQ+aJLZ8lN2fx
+I2rSAG2X+Z/nKcrdH9cG6rjJuQkhn8g/BsXS6RJGAE57COtCPStIbp1n3UsC5ETz
+kxmlJ85per5n0/xQpCyrw2u544BMzwVhSyvcG7mm0tCq9Stz+86QNZ8MUhy/XCFh
+EVsVS6kkUfykXPcXnbDS+gfpj1bkGoxoigTTfFrjnqKhynFbotSg5ymFXQNoKk/S
+Btc9+cMDLz9l+WceR0DTYw/j1Y75hauXTLPXJuuWCpTehTacyH+BCQJJKg71ZDIM
+gtG6aoIbs0t0EfOMd9afv9w3pKdVBC/UMejTRrkDfNoSTllkt1ExMVCgyhwn2RAu
+rda9EGYrw7AiShJbAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE
+FE9pbQN+nZ8HGEO8txBO1b+pxCAoMB8GA1UdIwQYMBaAFE9pbQN+nZ8HGEO8txBO
+1b+pxCAoMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAgEAO/Ouyugu
+h4X7ZVnnrREUpVe8WJ8kEle7+z802u6teio0cnAxa8cZmIDJgt43d15Ui47y6mdP
+yXSEkVYJ1eV6moG2gcKtNuTxVBFT8zRFASbI5Rq8NEQh3q0l/HYWdyGQgJhXnU7q
+7C+qPBR7V8F+GBRn7iTGvboVsNIYvbdVgaxTwOjdaRITQrcCtQVBynlQboIOcXKT
+RuidDV29rs4prWPVVRaAMCf/drr3uNZK49m1+VLQTkCpx+XCMseqdiThawVQ68W/
+ClTluUI8JPu3B5wwn3la5uBAUhX0/Kr0VvlEl4ftDmVyXr4m+02kLQgH3thcoNyB
+M5kYJRF3p+v9WAksmWsbivNSPxpNSGDxoPYzAlOL7SUJuA0t7Zdz7NeWH45gDtoQ
+my8YJPamTQr5O8t1wswvziRpyQoijlmn94IM19drNZxDAGrElWe6nEXLuA4399xO
+AU++CrYD062KRffaJ00psUjf5BHklka9bAI+1lHIlRcBFanyqqryvy9lG2/QuRqT
+9Y41xICHPpQvZuTpqP9BnHAqTyo5GJUefvthATxRCC4oGKQWDzH9OmwjkyB24f0H
+hdFbP9IcczLd+rn4jM8Ch3qaluTtT4mNU0OrDhPAARW0eTjb/G49nlG2uBOLZ8/5
+fNkiHfZdxRwBL5joeiQYvITX+txyW/fBOmg=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU
+MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs
+IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290
+MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux
+FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h
+bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v
+dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt
+H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9
+uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX
+mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX
+a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN
+E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0
+WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD
+VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0
+Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU
+cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx
+IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN
+AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH
+YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5
+6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC
+Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX
+c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a
+mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEU
+MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3
+b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwHhcNMDAwNTMw
+MTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQswCQYDVQQGEwJTRTEUMBIGA1UEChML
+QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYD
+VQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUA
+A4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwzexODcEyPNwTXH+9ZOEQpnXvUGW2ul
+CDtbKRY654eyNAbFvAWlA3yCyykQruGIgb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6n
+tGO0/7Gcrjyvd7ZWxbWroulpOj0OM3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyl
+dI+Yrsj5wAYi56xz36Uu+1LcsRVlIPo1Zmne3yzxbrww2ywkEtvrNTVokMsAsJch
+PXQhI2U0K7t4WaPW4XY5mqRJjox0r26kmqPZm9I4XJuiGMx1I4S+6+JNM3GOGvDC
++Mcdoq0Dlyz4zyXG9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8wHQYDVR0O
+BBYEFJWxtPCUtr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8E
+BTADAQH/MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBl
+MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFk
+ZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENB
+IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxtZBsfzQ3duQH6lmM0MkhHma6X
+7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0PhiVYrqW9yTkkz
+43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9tTEv2dB8Xfjea4MY
+eDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL/bscVjby/rK25Xa71SJl
+pz/+0WatC7xrmYbvP33zGDLKe8bjq2RGlfgmadlVg3sslgf/WSxEo8bl6ancoWOA
+WiFeIc9TVPC6b4nbqKqVz4vjccweGyBECMB6tkD9xOQ14R0WHNC8K47Wcdk=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEFTCCAv2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJTRTEU
+MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3
+b3JrMSAwHgYDVQQDExdBZGRUcnVzdCBQdWJsaWMgQ0EgUm9vdDAeFw0wMDA1MzAx
+MDQxNTBaFw0yMDA1MzAxMDQxNTBaMGQxCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtB
+ZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5ldHdvcmsxIDAeBgNV
+BAMTF0FkZFRydXN0IFB1YmxpYyBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOC
+AQ8AMIIBCgKCAQEA6Rowj4OIFMEg2Dybjxt+A3S72mnTRqX4jsIMEZBRpS9mVEBV
+6tsfSlbunyNu9DnLoblv8n75XYcmYZ4c+OLspoH4IcUkzBEMP9smcnrHAZcHF/nX
+GCwwfQ56HmIexkvA/X1id9NEHif2P0tEs7c42TkfYNVRknMDtABp4/MUTu7R3AnP
+dzRGULD4EfL+OHn3Bzn+UZKXC1sIXzSGAa2Il+tmzV7R/9x98oTaunet3IAIx6eH
+1lWfl2royBFkuucZKT8Rs3iQhCBSWxHveNCD9tVIkNAwHM+A+WD+eeSI8t0A65RF
+62WUaUC6wNW0uLp9BBGo6zEFlpROWCGOn9Bg/QIDAQABo4HRMIHOMB0GA1UdDgQW
+BBSBPjfYkrAfd59ctKtzquf2NGAv+jALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUw
+AwEB/zCBjgYDVR0jBIGGMIGDgBSBPjfYkrAfd59ctKtzquf2NGAv+qFopGYwZDEL
+MAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRU
+cnVzdCBUVFAgTmV0d29yazEgMB4GA1UEAxMXQWRkVHJ1c3QgUHVibGljIENBIFJv
+b3SCAQEwDQYJKoZIhvcNAQEFBQADggEBAAP3FUr4JNojVhaTdt02KLmuG7jD8WS6
+IBh4lSknVwW8fCr0uVFV2ocC3g8WFzH4qnkuCRO7r7IgGRLlk/lL+YPoRNWyQSW/
+iHVv/xD8SlTQX/D67zZzfRs2RcYhbbQVuE7PnFylPVoAjgbjPGsye/Kf8Lb93/Ao
+GEjwxrzQvzSAlsJKsW2Ox5BF3i9nrEUEo3rcVZLJR2bYGozH7ZxOmuASu7VqTITh
+4SINhwBk/ox9Yjllpu9CtoAlEmEBqCQTcAARJl/6NVDFSMwGR+gn2HCNX2TmoUQm
+XiLsks3/QppEIW1cxeMiHV9HEufOX1362KqxMy3ZdvJOOjMMK7MtkAY=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJTRTEU
+MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3
+b3JrMSMwIQYDVQQDExpBZGRUcnVzdCBRdWFsaWZpZWQgQ0EgUm9vdDAeFw0wMDA1
+MzAxMDQ0NTBaFw0yMDA1MzAxMDQ0NTBaMGcxCzAJBgNVBAYTAlNFMRQwEgYDVQQK
+EwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5ldHdvcmsxIzAh
+BgNVBAMTGkFkZFRydXN0IFF1YWxpZmllZCBDQSBSb290MIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEA5B6a/twJWoekn0e+EV+vhDTbYjx5eLfpMLXsDBwq
+xBb/4Oxx64r1EW7tTw2R0hIYLUkVAcKkIhPHEWT/IhKauY5cLwjPcWqzZwFZ8V1G
+87B4pfYOQnrjfxvM0PC3KP0q6p6zsLkEqv32x7SxuCqg+1jxGaBvcCV+PmlKfw8i
+2O+tCBGaKZnhqkRFmhJePp1tUvznoD1oL/BLcHwTOK28FSXx1s6rosAx1i+f4P8U
+WfyEk9mHfExUE+uf0S0R+Bg6Ot4l2ffTQO2kBhLEO+GRwVY18BTcZTYJbqukB8c1
+0cIDMzZbdSZtQvESa0NvS3GU+jQd7RNuyoB/mC9suWXY6QIDAQABo4HUMIHRMB0G
+A1UdDgQWBBQ5lYtii1zJ1IC6WA+XPxUIQ8yYpzALBgNVHQ8EBAMCAQYwDwYDVR0T
+AQH/BAUwAwEB/zCBkQYDVR0jBIGJMIGGgBQ5lYtii1zJ1IC6WA+XPxUIQ8yYp6Fr
+pGkwZzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQL
+ExRBZGRUcnVzdCBUVFAgTmV0d29yazEjMCEGA1UEAxMaQWRkVHJ1c3QgUXVhbGlm
+aWVkIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBABmrder4i2VhlRO6aQTv
+hsoToMeqT2QbPxj2qC0sVY8FtzDqQmodwCVRLae/DLPt7wh/bDxGGuoYQ992zPlm
+hpwsaPXpF/gxsxjE1kh9I0xowX67ARRvxdlu3rsEQmr49lx95dr6h+sNNVJn0J6X
+dgWTP5XHAeZpVTh/EGGZyeNfpso+gmNIquIISD6q8rKFYqa0p9m9N5xotS1WfbC3
+P6CxB9bpT9zeRXEwMn8bLgn5v1Kh7sKAPgZcLlVAwRv1cEWw3F369nJad9Jjzc9Y
+iQBCYz95OdBEsIJuQRno3eDBiFrRHnGTHyQwdOUeqN48Jzd/g66ed8/wMLH/S5no
+xqE=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDpDCCAoygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEc
+MBoGA1UEChMTQW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBP
+bmxpbmUgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAxMB4XDTAyMDUyODA2
+MDAwMFoXDTM3MTExOTIwNDMwMFowYzELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0Ft
+ZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2EgT25saW5lIFJvb3Qg
+Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBAKgv6KRpBgNHw+kqmP8ZonCaxlCyfqXfaE0bfA+2l2h9LaaLl+lk
+hsmj76CGv2BlnEtUiMJIxUo5vxTjWVXlGbR0yLQFOVwWpeKVBeASrlmLojNoWBym
+1BW32J/X3HGrfpq/m44zDyL9Hy7nBzbvYjnF3cu6JRQj3gzGPTzOggjmZj7aUTsW
+OqMFf6Dch9Wc/HKpoH145LcxVR5lu9RhsCFg7RAycsWSJR74kEoYeEfffjA3PlAb
+2xzTa5qGUwew76wGePiEmf4hjUyAtgyC9mZweRrTT6PP8c9GsEsPPt2IYriMqQko
+O3rHl+Ee5fSfwMCuJKDIodkP1nsmgmkyPacCAwEAAaNjMGEwDwYDVR0TAQH/BAUw
+AwEB/zAdBgNVHQ4EFgQUAK3Zo/Z59m50qX8zPYEX10zPM94wHwYDVR0jBBgwFoAU
+AK3Zo/Z59m50qX8zPYEX10zPM94wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB
+BQUAA4IBAQB8itEfGDeC4Liwo+1WlchiYZwFos3CYiZhzRAW18y0ZTTQEYqtqKkF
+Zu90821fnZmv9ov761KyBZiibyrFVL0lvV+uyIbqRizBs73B6UlwGBaXCBOMIOAb
+LjpHyx7kADCVW/RFo8AasAFOq73AI25jP4BKxQft3OJvx8Fi8eNy1gTIdGcL+oir
+oQHIb/AUr9KZzVGTfu0uOMe9zkZQPXLjeSWdm4grECDdpbgyn43gKd8hdIaC2y+C
+MMbHNYaz+ZZfRtsMRf3zUMNvxsNIrUam4SdHCh0Om7bCd39j8uB9Gr784N/Xx6ds
+sPmuujz9dLQR6FgNgLzTqIA6me11zEZ7
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFpDCCA4ygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEc
+MBoGA1UEChMTQW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBP
+bmxpbmUgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAyMB4XDTAyMDUyODA2
+MDAwMFoXDTM3MDkyOTE0MDgwMFowYzELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0Ft
+ZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2EgT25saW5lIFJvb3Qg
+Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIP
+ADCCAgoCggIBAMxBRR3pPU0Q9oyxQcngXssNt79Hc9PwVU3dxgz6sWYFas14tNwC
+206B89enfHG8dWOgXeMHDEjsJcQDIPT/DjsS/5uN4cbVG7RtIuOx238hZK+GvFci
+KtZHgVdEglZTvYYUAQv8f3SkWq7xuhG1m1hagLQ3eAkzfDJHA1zEpYNI9FdWboE2
+JxhP7JsowtS013wMPgwr38oE18aO6lhOqKSlGBxsRZijQdEt0sdtjRnxrXm3gT+9
+BoInLRBYBbV4Bbkv2wxrkJB+FFk4u5QkE+XRnRTf04JNRvCAOVIyD+OEsnpD8l7e
+Xz8d3eOyG6ChKiMDbi4BFYdcpnV1x5dhvt6G3NRI270qv0pV2uh9UPu0gBe4lL8B
+PeraunzgWGcXuVjgiIZGZ2ydEEdYMtA1fHkqkKJaEBEjNa0vzORKW6fIJ/KD3l67
+Xnfn6KVuY8INXWHQjNJsWiEOyiijzirplcdIz5ZvHZIlyMbGwcEMBawmxNJ10uEq
+Z8A9W6Wa6897GqidFEXlD6CaZd4vKL3Ob5Rmg0gp2OpljK+T2WSfVVcmv2/LNzGZ
+o2C7HK2JNDJiuEMhBnIMoVxtRsX6Kc8w3onccVvdtjc+31D1uAclJuW8tf48ArO3
++L5DwYcRlJ4jbBeKuIonDFRH8KmzwICMoCfrHRnjB453cMor9H124HhnAgMBAAGj
+YzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFE1FwWg4u3OpaaEg5+31IqEj
+FNeeMB8GA1UdIwQYMBaAFE1FwWg4u3OpaaEg5+31IqEjFNeeMA4GA1UdDwEB/wQE
+AwIBhjANBgkqhkiG9w0BAQUFAAOCAgEAZ2sGuV9FOypLM7PmG2tZTiLMubekJcmn
+xPBUlgtk87FYT15R/LKXeydlwuXK5w0MJXti4/qftIe3RUavg6WXSIylvfEWK5t2
+LHo1YGwRgJfMqZJS5ivmae2p+DYtLHe/YUjRYwu5W1LtGLBDQiKmsXeu3mnFzccc
+obGlHBD7GL4acN3Bkku+KVqdPzW+5X1R+FXgJXUjhx5c3LqdsKyzadsXg8n33gy8
+CNyRnqjQ1xU3c6U1uPx+xURABsPr+CKAXEfOAuMRn0T//ZoyzH1kUQ7rVyZ2OuMe
+IjzCpjbdGe+n/BLzJsBZMYVMnNjP36TMzCmT/5RtdlwTCJfy7aULTd3oyWgOZtMA
+DjMSW7yV5TKQqLPGbIOtd+6Lfn6xqavT4fG2wLHqiMDn05DpKJKUe2h7lyoKZy2F
+AjgQ5ANh1NolNscIWC2hp1GvMApJ9aZphwctREZ2jirlmjvXGKL8nDgQzMY70rUX
+Om/9riW99XJZZLF0KjhfGEzfz3EEWjbUvy+ZnOjZurGV5gJLIaFb1cFPj65pbVPb
+AZO1XB4Y3WRayhgoPmMEEf0cjQAPuDffZ4qdZqkCapH/E8ovXYO8h5Ns3CRRFgQl
+Zvqz2cK6Kb6aSDiCmfS/O0oxGfm/jiEzFMpPVF/7zvuPcX/9XhmgD0uRuMRUvAaw
+RY8mkaKO/qk=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ
+RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
+VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX
+DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y
+ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy
+VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr
+mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr
+IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK
+mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu
+XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy
+dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye
+jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1
+BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3
+DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92
+9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx
+jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0
+Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz
+ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS
+R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB
+gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
+A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV
+BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw
+MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl
+YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P
+RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0
+aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3
+UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI
+2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8
+Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp
++2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+
+DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O
+nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW
+/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g
+PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u
+QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY
+SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv
+IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/
+RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4
+zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd
+BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB
+ZQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL
+MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
+BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT
+IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw
+MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy
+ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N
+T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv
+biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR
+FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J
+cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW
+BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
+BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm
+fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv
+GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEvTCCA6WgAwIBAgIBADANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEn
+MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL
+ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMg
+b2YgQ29tbWVyY2UgUm9vdDAeFw0wMzA5MzAxNjEzNDNaFw0zNzA5MzAxNjEzNDRa
+MH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZpcm1hIFNBIENJRiBB
+ODI3NDMyODcxIzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3JnMSIw
+IAYDVQQDExlDaGFtYmVycyBvZiBDb21tZXJjZSBSb290MIIBIDANBgkqhkiG9w0B
+AQEFAAOCAQ0AMIIBCAKCAQEAtzZV5aVdGDDg2olUkfzIx1L4L1DZ77F1c2VHfRtb
+unXF/KGIJPov7coISjlUxFF6tdpg6jg8gbLL8bvZkSM/SAFwdakFKq0fcfPJVD0d
+BmpAPrMMhe5cG3nCYsS4No41XQEMIwRHNaqbYE6gZj3LJgqcQKH0XZi/caulAGgq
+7YN6D6IUtdQis4CwPAxaUWktWBiP7Zme8a7ileb2R6jWDA+wWFjbw2Y3npuRVDM3
+0pQcakjJyfKl2qUMI/cjDpwyVV5xnIQFUZot/eZOKjRa3spAN2cMVCFVd9oKDMyX
+roDclDZK9D7ONhMeU+SsTjoF7Nuucpw4i9A5O4kKPnf+dQIBA6OCAUQwggFAMBIG
+A1UdEwEB/wQIMAYBAf8CAQwwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybC5j
+aGFtYmVyc2lnbi5vcmcvY2hhbWJlcnNyb290LmNybDAdBgNVHQ4EFgQU45T1sU3p
+26EpW1eLTXYGduHRooowDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIA
+BzAnBgNVHREEIDAegRxjaGFtYmVyc3Jvb3RAY2hhbWJlcnNpZ24ub3JnMCcGA1Ud
+EgQgMB6BHGNoYW1iZXJzcm9vdEBjaGFtYmVyc2lnbi5vcmcwWAYDVR0gBFEwTzBN
+BgsrBgEEAYGHLgoDATA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY3BzLmNoYW1iZXJz
+aWduLm9yZy9jcHMvY2hhbWJlcnNyb290Lmh0bWwwDQYJKoZIhvcNAQEFBQADggEB
+AAxBl8IahsAifJ/7kPMa0QOx7xP5IV8EnNrJpY0nbJaHkb5BkAFyk+cefV/2icZd
+p0AJPaxJRUXcLo0waLIJuvvDL8y6C98/d3tGfToSJI6WjzwFCm/SlCgdbQzALogi
+1djPHRPH8EjX1wWnz8dHnjs8NMiAT9QUu/wNUPf6s+xCX6ndbcj0dc97wXImsQEc
+XCz9ek60AcUFV7nnPKoF2YjpB0ZBzu9Bga5Y34OirsrXdx/nADydb47kMgkdTXg0
+eDQ8lJsm7U9xxhl6vSAiSFr+S30Dt+dYvsYyTnQeaN2oaFuzPu5ifdmA6Ap1erfu
+tGWaIZDgqtCYvDi1czyL+Nw=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIExTCCA62gAwIBAgIBADANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJFVTEn
+MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL
+ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4GA1UEAxMXR2xvYmFsIENo
+YW1iZXJzaWduIFJvb3QwHhcNMDMwOTMwMTYxNDE4WhcNMzcwOTMwMTYxNDE4WjB9
+MQswCQYDVQQGEwJFVTEnMCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgy
+NzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4G
+A1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwggEgMA0GCSqGSIb3DQEBAQUA
+A4IBDQAwggEIAoIBAQCicKLQn0KuWxfH2H3PFIP8T8mhtxOviteePgQKkotgVvq0
+Mi+ITaFgCPS3CU6gSS9J1tPfnZdan5QEcOw/Wdm3zGaLmFIoCQLfxS+EjXqXd7/s
+QJ0lcqu1PzKY+7e3/HKE5TWH+VX6ox8Oby4o3Wmg2UIQxvi1RMLQQ3/bvOSiPGpV
+eAp3qdjqGTK3L/5cPxvusZjsyq16aUXjlg9V9ubtdepl6DJWk0aJqCWKZQbua795
+B9Dxt6/tLE2Su8CoX6dnfQTyFQhwrJLWfQTSM/tMtgsL+xrJxI0DqX5c8lCrEqWh
+z0hQpe/SyBoT+rB/sYIcd2oPX9wLlY/vQ37mRQklAgEDo4IBUDCCAUwwEgYDVR0T
+AQH/BAgwBgEB/wIBDDA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3JsLmNoYW1i
+ZXJzaWduLm9yZy9jaGFtYmVyc2lnbnJvb3QuY3JsMB0GA1UdDgQWBBRDnDafsJ4w
+TcbOX60Qq+UDpfqpFDAOBgNVHQ8BAf8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgAH
+MCoGA1UdEQQjMCGBH2NoYW1iZXJzaWducm9vdEBjaGFtYmVyc2lnbi5vcmcwKgYD
+VR0SBCMwIYEfY2hhbWJlcnNpZ25yb290QGNoYW1iZXJzaWduLm9yZzBbBgNVHSAE
+VDBSMFAGCysGAQQBgYcuCgEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly9jcHMuY2hh
+bWJlcnNpZ24ub3JnL2Nwcy9jaGFtYmVyc2lnbnJvb3QuaHRtbDANBgkqhkiG9w0B
+AQUFAAOCAQEAPDtwkfkEVCeR4e3t/mh/YV3lQWVPMvEYBZRqHN4fcNs+ezICNLUM
+bKGKfKX0j//U2K0X1S0E0T9YgOKBWYi+wONGkyT+kL0mojAt6JcmVzWJdJYY9hXi
+ryQZVgICsroPFOrGimbBhkVVi76SvpykBMdJPJ7oKXqJ1/6v/2j1pReQvayZzKWG
+VwlnRtvWFsJG8eSpUPWP0ZIV018+xgBJOm5YstHRJw0lyDL4IBHNfTIzSJRUTN3c
+ecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREest2d/
+AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAw
+PTELMAkGA1UEBhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFz
+cyAyIFByaW1hcnkgQ0EwHhcNOTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9
+MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2VydHBsdXMxGzAZBgNVBAMTEkNsYXNz
+IDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANxQ
+ltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR5aiR
+VhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyL
+kcAbmXuZVg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCd
+EgETjdyAYveVqUSISnFOYFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yas
+H7WLO7dDWWuwJKZtkIvEcupdM5i3y95ee++U8Rs+yskhwcWYAqqi9lt3m/V+llU0
+HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRMECDAGAQH/AgEKMAsGA1Ud
+DwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJYIZIAYb4
+QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMu
+Y29tL0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/
+AN9WM2K191EBkOvDP9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8
+yfFC82x/xXp8HVGIutIKPidd3i1RTtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMR
+FcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+7UCmnYR0ObncHoUW2ikbhiMA
+ybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW//1IMwrh3KWB
+kJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7
+l7+ijrRU
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBM
+MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD
+QTAeFw0wMjA2MTExMDQ2MzlaFw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBM
+MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD
+QTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6xwS7TT3zNJc4YPk/E
+jG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdLkKWo
+ePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GI
+ULdtlkIJ89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapu
+Ob7kky/ZR6By6/qmW6/KUz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUg
+AKpoC6EahQGcxEZjgoi2IrHu/qpGWX7PNSzVttpd90gzFFS269lvzs2I1qsb2pY7
+HVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEA
+uI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+GXYkHAQa
+TOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTg
+xSvgGrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1q
+CjqTE5s7FCMTY5w/0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5x
+O/fIR/RpbxXyEV6DHpx8Uq79AtoSqFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs
+6GAqm4VKQPNriiTsBhYscw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb
+MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
+GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj
+YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL
+MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
+BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM
+GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua
+BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe
+3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4
+YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR
+rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm
+ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU
+oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF
+MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v
+QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t
+b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF
+AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q
+GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz
+Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2
+G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi
+l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3
+smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJHQjEb
+MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
+GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEkMCIGA1UEAwwbU2VjdXJlIENlcnRp
+ZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVow
+fjELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
+A1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxJDAiBgNV
+BAMMG1NlY3VyZSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEB
+BQADggEPADCCAQoCggEBAMBxM4KK0HDrc4eCQNUd5MvJDkKQ+d40uaG6EfQlhfPM
+cm3ye5drswfxdySRXyWP9nQ95IDC+DwN879A6vfIUtFyb+/Iq0G4bi4XKpVpDM3S
+HpR7LZQdqnXXs5jLrLxkU0C8j6ysNstcrbvd4JQX7NFc0L/vpZXJkMWwrPsbQ996
+CF23uPJAGysnnlDOXmWCiIxe004MeuoIkbY2qitC++rCoznl2yY4rYsK7hljxxwk
+3wN42ubqwUcaCwtGCd0C/N7Lh1/XMGNooa7cMqG6vv5Eq2i2pRcV/b3Vp6ea5EQz
+6YiO/O1R65NxTq0B50SOqy3LqP4BSUjwwN3HaNiS/j0CAwEAAaOBxzCBxDAdBgNV
+HQ4EFgQUPNiTiMLAggnMAZkGkyDpnnAJY08wDgYDVR0PAQH/BAQDAgEGMA8GA1Ud
+EwEB/wQFMAMBAf8wgYEGA1UdHwR6MHgwO6A5oDeGNWh0dHA6Ly9jcmwuY29tb2Rv
+Y2EuY29tL1NlY3VyZUNlcnRpZmljYXRlU2VydmljZXMuY3JsMDmgN6A1hjNodHRw
+Oi8vY3JsLmNvbW9kby5uZXQvU2VjdXJlQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmww
+DQYJKoZIhvcNAQEFBQADggEBAIcBbSMdflsXfcFhMs+P5/OKlFlm4J4oqF7Tt/Q0
+5qo5spcWxYJvMqTpjOev/e/C6LlLqqP05tqNZSH7uoDrJiiFGv45jN5bBAS0VPmj
+Z55B+glSzAVIqMk/IQQezkhr/IXownuvf7fM+F86/TXGDe+X3EyrEeFryzHRbPtI
+gKvcnDe4IRRLDXE97IMzbtFuMhbsmMcWi1mmNKsFVy2T96oTy9IT4rcuO81rUBcJ
+aD61JlfutuC23bkpgHl9j6PwpCikFcSF9CfUa7/lXORlAnZUtOM3ZiTTGWHIUhDl
+izeauan5Hb/qmZJhlv8BzaFfDbxxvA6sCx1HRR3B7Hzs/Sk=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEQzCCAyugAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJHQjEb
+MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
+GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDElMCMGA1UEAwwcVHJ1c3RlZCBDZXJ0
+aWZpY2F0ZSBTZXJ2aWNlczAeFw0wNDAxMDEwMDAwMDBaFw0yODEyMzEyMzU5NTla
+MH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO
+BgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSUwIwYD
+VQQDDBxUcnVzdGVkIENlcnRpZmljYXRlIFNlcnZpY2VzMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEA33FvNlhTWvI2VFeAxHQIIO0Yfyod5jWaHiWsnOWW
+fnJSoBVC21ndZHoa0Lh73TkVvFVIxO06AOoxEbrycXQaZ7jPM8yoMa+j49d/vzMt
+TGo87IvDktJTdyR0nAducPy9C1t2ul/y/9c3S0pgePfw+spwtOpZqqPOSC+pw7IL
+fhdyFgymBwwbOM/JYrc/oJOlh0Hyt3BAd9i+FHzjqMB6juljatEPmsbS9Is6FARW
+1O24zG71++IsWL1/T2sr92AkWCTOJu80kTrV44HQsvAEAtdbtz6SrGsSivnkBbA7
+kUlcsutT6vifR4buv5XAwAaf0lteERv0xwQ1KdJVXOTt6wIDAQABo4HJMIHGMB0G
+A1UdDgQWBBTFe1i97doladL3WRaoszLAeydb9DAOBgNVHQ8BAf8EBAMCAQYwDwYD
+VR0TAQH/BAUwAwEB/zCBgwYDVR0fBHwwejA8oDqgOIY2aHR0cDovL2NybC5jb21v
+ZG9jYS5jb20vVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMuY3JsMDqgOKA2hjRo
+dHRwOi8vY3JsLmNvbW9kby5uZXQvVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMu
+Y3JsMA0GCSqGSIb3DQEBBQUAA4IBAQDIk4E7ibSvuIQSTI3S8NtwuleGFTQQuS9/
+HrCoiWChisJ3DFBKmwCL2Iv0QeLQg4pKHBQGsKNoBXAxMKdTmw7pSqBYaWcOrp32
+pSxBvzwGa+RZzG0Q8ZZvH9/0BAKkn0U+yNj6NkZEUD+Cl5EfKNsYEYwq5GWDVxIS
+jBc/lDb+XbDABHcTuPQV1T84zJQ6VdCsmPW6AF/ghhmBeC8owH7TzEIK9a5QoNE+
+xqFx7D+gIIxmOom0jtTYsU0lR+4viMi14QVFwL4Ucd56/Y57fU0IlqUSc/Atyjcn
+dBInTMu2l+nZrghtWjlA3QVHdWpaIbOjGM9O9y5Xt5hwXsjEeLBi
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIECTCCAvGgAwIBAgIQDV6ZCtadt3js2AdWO4YV2TANBgkqhkiG9w0BAQUFADBb
+MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3Qx
+ETAPBgNVBAsTCERTVCBBQ0VTMRcwFQYDVQQDEw5EU1QgQUNFUyBDQSBYNjAeFw0w
+MzExMjAyMTE5NThaFw0xNzExMjAyMTE5NThaMFsxCzAJBgNVBAYTAlVTMSAwHgYD
+VQQKExdEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdDERMA8GA1UECxMIRFNUIEFDRVMx
+FzAVBgNVBAMTDkRTVCBBQ0VTIENBIFg2MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
+MIIBCgKCAQEAuT31LMmU3HWKlV1j6IR3dma5WZFcRt2SPp/5DgO0PWGSvSMmtWPu
+ktKe1jzIDZBfZIGxqAgNTNj50wUoUrQBJcWVHAx+PhCEdc/BGZFjz+iokYi5Q1K7
+gLFViYsx+tC3dr5BPTCapCIlF3PoHuLTrCq9Wzgh1SpL11V94zpVvddtawJXa+ZH
+fAjIgrrep4c9oW24MFbCswKBXy314powGCi4ZtPLAZZv6opFVdbgnf9nKxcCpk4a
+ahELfrd755jWjHZvwTvbUJN+5dCOHze4vbrGn2zpfDPyMjwmR/onJALJfh1biEIT
+ajV8fTXpLmaRcpPVMibEdPVTo7NdmvYJywIDAQABo4HIMIHFMA8GA1UdEwEB/wQF
+MAMBAf8wDgYDVR0PAQH/BAQDAgHGMB8GA1UdEQQYMBaBFHBraS1vcHNAdHJ1c3Rk
+c3QuY29tMGIGA1UdIARbMFkwVwYKYIZIAWUDAgEBATBJMEcGCCsGAQUFBwIBFjto
+dHRwOi8vd3d3LnRydXN0ZHN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L0FDRVMt
+aW5kZXguaHRtbDAdBgNVHQ4EFgQUCXIGThhDD+XWzMNqizF7eI+og7gwDQYJKoZI
+hvcNAQEFBQADggEBAKPYjtay284F5zLNAdMEA+V25FYrnJmQ6AgwbN99Pe7lv7Uk
+QIRJ4dEorsTCOlMwiPH1d25Ryvr/ma8kXxug/fKshMrfqfBfBC6tFr8hlxCBPeP/
+h40y3JTlR4peahPJlJU90u7INJXQgNStMgiAVDzgvVJT11J8smk/f3rPanTK+gQq
+nExaBqXpIK1FZg9p8d2/6eMyi/rgwYZNcjwu2JN4Cir42NInPRmJX1p7ijvMDNpR
+rscL9yuwNwXsvFcj4jjSm2jzVhKIT0J8uDHEtdvkyCE06UgRNe76x5JXxZ805Mf2
+9w4LTJxoeHtxMcfrHuBnQfO3oKfN5XozNmr6mis=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/
+MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
+DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow
+PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
+Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O
+rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq
+OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b
+xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw
+7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD
+aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
+HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG
+SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69
+ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr
+AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz
+R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5
+JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo
+Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
+b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG
+EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
+cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c
+JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP
+mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+
+wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4
+VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/
+AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB
+AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
+BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun
+pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC
+dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf
+fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm
+NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx
+H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe
++o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
+QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
+MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
+b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
+CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
+nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
+43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
+T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
+gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
+BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
+TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
+DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
+hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
+06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
+PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
+YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
+CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
+ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
+MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
+LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
+RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
++9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
+PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
+xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
+Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
+hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
+EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
+MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
+FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
+nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
+eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
+hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
+Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
+vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
++OkuE6N36B9K
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFijCCA3KgAwIBAgIQDHbanJEMTiye/hXQWJM8TDANBgkqhkiG9w0BAQUFADBf
+MQswCQYDVQQGEwJOTDESMBAGA1UEChMJRGlnaU5vdGFyMRowGAYDVQQDExFEaWdp
+Tm90YXIgUm9vdCBDQTEgMB4GCSqGSIb3DQEJARYRaW5mb0BkaWdpbm90YXIubmww
+HhcNMDcwNTE2MTcxOTM2WhcNMjUwMzMxMTgxOTIxWjBfMQswCQYDVQQGEwJOTDES
+MBAGA1UEChMJRGlnaU5vdGFyMRowGAYDVQQDExFEaWdpTm90YXIgUm9vdCBDQTEg
+MB4GCSqGSIb3DQEJARYRaW5mb0BkaWdpbm90YXIubmwwggIiMA0GCSqGSIb3DQEB
+AQUAA4ICDwAwggIKAoICAQCssFjBAL3YIQgLK5r+blYwBZ8bd5AQQVzDDYcRd46B
+8cp86Yxq7Th0Nbva3/m7wAk3tJZzgX0zGpg595NvlX89ubF1h7pRSOiLcD6VBMXY
+tsMW2YiwsYcdcNqGtA8Ui3rPENF0NqISe3eGSnnme98CEWilToauNFibJBN4ViIl
+HgGLS1Fx+4LMWZZpiFpoU8W5DQI3y0u8ZkqQfioLBQftFl9VkHXYRskbg+IIvvEj
+zJkd1ioPgyAVWCeCLvriIsJJsbkBgWqdbZ1Ad2h2TiEqbYRAhU52mXyC8/O3AlnU
+JgEbjt+tUwbRrhjd4rI6y9eIOI6sWym5GdOY+RgDz0iChmYLG2kPyes4iHomGgVM
+ktck1JbyrFIto0fVUvY//s6EBnCmqj6i8rZWNBhXouSBbefK8GrTx5FrAoNBfBXv
+a5pkXuPQPOWx63tdhvvL5ndJzaNl3Pe5nLjkC1+Tz8wwGjIczhxjlaX56uF0i57p
+K6kwe6AYHw4YC+VbqdPRbB4HZ4+RS6mKvNJmqpMBiLKR+jFc1abBUggJzQpjotMi
+puih2TkGl/VujQKQjBR7P4DNG5y6xFhyI6+2Vp/GekIzKQc/gsnmHwUNzUwoNovT
+yD4cxojvXu6JZOkd69qJfjKmadHdzIif0dDJZiHcBmfFlHqabWJMfczgZICynkeO
+owIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV
+HQ4EFgQUiGi/4I41xDs4a2L3KDuEgcgM100wDQYJKoZIhvcNAQEFBQADggIBADsC
+jcs8MOhuoK3yc7NfniUTBAXT9uOLuwt5zlPe5JbF0a9zvNXD0EBVfEB/zRtfCdXy
+fJ9oHbtdzno5wozWmHvFg1Wo1X1AyuAe94leY12hE8JdiraKfADzI8PthV9xdvBo
+Y6pFITlIYXg23PFDk9Qlx/KAZeFTAnVR/Ho67zerhChXDNjU1JlWbOOi/lmEtDHo
+M/hklJRRl6s5xUvt2t2AC298KQ3EjopyDedTFLJgQT2EkTFoPSdE2+Xe9PpjRchM
+Ppj1P0G6Tss3DbpmmPHdy59c91Q2gmssvBNhl0L4eLvMyKKfyvBovWsdst+Nbwed
+2o5nx0ceyrm/KkKRt2NTZvFCo+H0Wk1Ya7XkpDOtXHAd3ODy63MUkZoDweoAZbwH
+/M8SESIsrqC9OuCiKthZ6SnTGDWkrBFfGbW1G/8iSlzGeuQX7yCpp/Q/rYqnmgQl
+nQ7KN+ZQ/YxCKQSa7LnPS3K94gg2ryMvYuXKAdNw23yCIywWMQzGNgeQerEfZ1jE
+O1hZibCMjFCz2IbLaKPECudpSyDOwR5WS5WpI2jYMNjD67BVUc3l/Su49bsRn1NU
+9jQZjHkJNsphFyUXC4KYcwx3dMPVDceoEkzHp1RxRy4sGn3J4ys7SN4nhKdjNrN9
+j6BkOSQNPXuHr2ZcdBtLc7LljPCGmbjlxd+Ewbfr
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDKTCCApKgAwIBAgIENnAVljANBgkqhkiG9w0BAQUFADBGMQswCQYDVQQGEwJV
+UzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMREwDwYDVQQL
+EwhEU1RDQSBFMTAeFw05ODEyMTAxODEwMjNaFw0xODEyMTAxODQwMjNaMEYxCzAJ
+BgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4x
+ETAPBgNVBAsTCERTVENBIEUxMIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQCg
+bIGpzzQeJN3+hijM3oMv+V7UQtLodGBmE5gGHKlREmlvMVW5SXIACH7TpWJENySZ
+j9mDSI+ZbZUTu0M7LklOiDfBu1h//uG9+LthzfNHwJmm8fOR6Hh8AMthyUQncWlV
+Sn5JTe2io74CTADKAqjuAQIxZA9SLRN0dja1erQtcQIBA6OCASQwggEgMBEGCWCG
+SAGG+EIBAQQEAwIABzBoBgNVHR8EYTBfMF2gW6BZpFcwVTELMAkGA1UEBhMCVVMx
+JDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLjERMA8GA1UECxMI
+RFNUQ0EgRTExDTALBgNVBAMTBENSTDEwKwYDVR0QBCQwIoAPMTk5ODEyMTAxODEw
+MjNagQ8yMDE4MTIxMDE4MTAyM1owCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaAFGp5
+fpFpRhgTCgJ3pVlbYJglDqL4MB0GA1UdDgQWBBRqeX6RaUYYEwoCd6VZW2CYJQ6i
++DAMBgNVHRMEBTADAQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqG
+SIb3DQEBBQUAA4GBACIS2Hod3IEGtgllsofIH160L+nEHvI8wbsEkBFKg05+k7lN
+QseSJqBcNJo4cvj9axY+IO6CizEqkzaFI4iKPANo08kJD038bKTaKHKTDomAsH3+
+gG9lbRgzl4vCa4nuYD3Im+9/KzJic5PLPON74nZ4RbyhkwS7hp86W0N6w4pl
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIID2DCCAsACEQDQHkCLAAACfAAAAAIAAAABMA0GCSqGSIb3DQEBBQUAMIGpMQsw
+CQYDVQQGEwJ1czENMAsGA1UECBMEVXRhaDEXMBUGA1UEBxMOU2FsdCBMYWtlIENp
+dHkxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLjERMA8GA1UE
+CxMIRFNUQ0EgWDExFjAUBgNVBAMTDURTVCBSb290Q0EgWDExITAfBgkqhkiG9w0B
+CQEWEmNhQGRpZ3NpZ3RydXN0LmNvbTAeFw05ODEyMDExODE4NTVaFw0wODExMjgx
+ODE4NTVaMIGpMQswCQYDVQQGEwJ1czENMAsGA1UECBMEVXRhaDEXMBUGA1UEBxMO
+U2FsdCBMYWtlIENpdHkxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0
+IENvLjERMA8GA1UECxMIRFNUQ0EgWDExFjAUBgNVBAMTDURTVCBSb290Q0EgWDEx
+ITAfBgkqhkiG9w0BCQEWEmNhQGRpZ3NpZ3RydXN0LmNvbTCCASIwDQYJKoZIhvcN
+AQEBBQADggEPADCCAQoCggEBANLGJrbnpT3BxGjVUG9TxW9JEwm4ryxIjRRqoxdf
+WvnTLnUv2Chi0ZMv/E3Uq4flCMeZ55I/db3rJbQVwZsZPdJEjdd0IG03Ao9pk1uK
+xBmd9LIO/BZsubEFkoPRhSxglD5FVaDZqwgh5mDoO3TymVBRaNADLbGAvqPYUrBE
+zUNKcI5YhZXhTizWLUFv1oTnyJhEykfbLCSlaSbPa7gnYsP0yXqSI+0TZ4KuRS5F
+5X5yP4WdlGIQ5jyRoa13AOAV7POEgHJ6jm5gl8ckWRA0g1vhpaRptlc1HHhZxtMv
+OnNn7pTKBBMFYgZwI7P0fO5F2WQLW0mqpEPOJsREEmy43XkCAwEAATANBgkqhkiG
+9w0BAQUFAAOCAQEAojeyP2n714Z5VEkxlTMr89EJFEliYIalsBHiUMIdBlc+Legz
+ZL6bqq1fG03UmZWii5rJYnK1aerZWKs17RWiQ9a2vAd5ZWRzfdd5ynvVWlHG4VME
+lo04z6MXrDlxawHDi1M8Y+nuecDkvpIyZHqzH5eUYr3qsiAVlfuX8ngvYzZAOONG
+Dx3drJXK50uQe7FLqdTF65raqtWjlBRGjS0f8zrWkzr2Pnn86Oawde3uPclwx12q
+gUtGJRzHbBXjlU4PqjI3lAoXJJIThFjSY28r9+ZbYgsTF7ANUkz+/m9c4pFuHf2k
+Ytdo+o56T9II2pPc8JIRetDccpMMc5NihWjQ9A==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDKTCCApKgAwIBAgIENm7TzjANBgkqhkiG9w0BAQUFADBGMQswCQYDVQQGEwJV
+UzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMREwDwYDVQQL
+EwhEU1RDQSBFMjAeFw05ODEyMDkxOTE3MjZaFw0xODEyMDkxOTQ3MjZaMEYxCzAJ
+BgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4x
+ETAPBgNVBAsTCERTVENBIEUyMIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQC/
+k48Xku8zExjrEH9OFr//Bo8qhbxe+SSmJIi2A7fBw18DW9Fvrn5C6mYjuGODVvso
+LeE4i7TuqAHhzhy2iCoiRoX7n6dwqUcUP87eZfCocfdPJmyMvMa1795JJ/9IKn3o
+TQPMx7JSxhcxEzu1TdvIxPbDDyQq2gyd55FbgM2UnQIBA6OCASQwggEgMBEGCWCG
+SAGG+EIBAQQEAwIABzBoBgNVHR8EYTBfMF2gW6BZpFcwVTELMAkGA1UEBhMCVVMx
+JDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLjERMA8GA1UECxMI
+RFNUQ0EgRTIxDTALBgNVBAMTBENSTDEwKwYDVR0QBCQwIoAPMTk5ODEyMDkxOTE3
+MjZagQ8yMDE4MTIwOTE5MTcyNlowCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaAFB6C
+TShlgDzJQW6sNS5ay97u+DlbMB0GA1UdDgQWBBQegk0oZYA8yUFurDUuWsve7vg5
+WzAMBgNVHRMEBTADAQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqG
+SIb3DQEBBQUAA4GBAEeNg61i8tuwnkUiBbmi1gMOOHLnnvx75pO2mqWilMg0HZHR
+xdf0CiUPPXiBng+xZ8SQTGPdXqfiup/1902lMXucKS1M/mQ+7LZT/uqb7YLbdHVL
+B3luHtgZg3Pe9T7Qtd7nS2h9Qy4qIOF+oHhEngj1mPnHfxsb1gYgAlihw6ID
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIID2DCCAsACEQDQHkCLAAB3bQAAAAEAAAAEMA0GCSqGSIb3DQEBBQUAMIGpMQsw
+CQYDVQQGEwJ1czENMAsGA1UECBMEVXRhaDEXMBUGA1UEBxMOU2FsdCBMYWtlIENp
+dHkxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLjERMA8GA1UE
+CxMIRFNUQ0EgWDIxFjAUBgNVBAMTDURTVCBSb290Q0EgWDIxITAfBgkqhkiG9w0B
+CQEWEmNhQGRpZ3NpZ3RydXN0LmNvbTAeFw05ODExMzAyMjQ2MTZaFw0wODExMjcy
+MjQ2MTZaMIGpMQswCQYDVQQGEwJ1czENMAsGA1UECBMEVXRhaDEXMBUGA1UEBxMO
+U2FsdCBMYWtlIENpdHkxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0
+IENvLjERMA8GA1UECxMIRFNUQ0EgWDIxFjAUBgNVBAMTDURTVCBSb290Q0EgWDIx
+ITAfBgkqhkiG9w0BCQEWEmNhQGRpZ3NpZ3RydXN0LmNvbTCCASIwDQYJKoZIhvcN
+AQEBBQADggEPADCCAQoCggEBANx18IzAdZaawGIfJvfE4Zrq4FZzW5nNAUSoCLbV
+p9oaBBg5kkp4o4HC9Xd6ULRw/5qrxsfKboNPQpj7Jgva3G3WqZlVUmfpKAOS3OWw
+BZoPFflrWXJW8vo5/Kpo7g8fEIMv/J36F5bdguPmRX3AS4BEH+0s4IT9kVySVGkl
+5WJp3OXuAFK9MwutdQKFp2RQLcUZGTDAJtvJ0/0uma1ZtQtN1EGuhUhDWdy3qOKi
+3sOP17ihYqZoUFLkzzGnlIXan0YyF1bl8utmPRL/Q9uY73fPy4GNNLHGUEom0eQ+
+QVCvbK4iNC7Va26Dunm4dmVI2gkpZGMiuftHdoWMhkTLCdsCAwEAATANBgkqhkiG
+9w0BAQUFAAOCAQEAtTYOXeFhKFoRZcA/gwN5Tb4opgsHAlKFzfiR0BBstWogWxyQ
+2TA8xkieil5k+aFxd+8EJx8H6+Qm93N0yUQYGmbT4EOvkTvRyyzYdFQ6HE3K1GjN
+I3wdEJ5F6fYAbqbNGf9PLCmPV03Ed5K+4EwJ+11EhmYhqLkyolbV6YyDfFk/xPEL
+553snr2cGA4+wjl5KLcDDQjLxufZATdQEOzMYRZA1K8xdHv8PzGn0EdzMzkbzE5q
+10mDEQb+64JYMzJM8FasHpwvVpp7wUocpf1VNs78lk30sPDst2yC7S8xmUJMqbIN
+uBVd8d+6ybVK1GSYsyapMMj9puyrliGtf8J4tg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEgzCCA+ygAwIBAgIEOJ725DANBgkqhkiG9w0BAQQFADCBtDEUMBIGA1UEChML
+RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9HQ0NBX0NQUyBp
+bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAyMDAw
+IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENsaWVu
+dCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMDAyMDcxNjE2NDBaFw0yMDAy
+MDcxNjQ2NDBaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3
+LmVudHJ1c3QubmV0L0dDQ0FfQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp
+YWIuKTElMCMGA1UECxMcKGMpIDIwMDAgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG
+A1UEAxMqRW50cnVzdC5uZXQgQ2xpZW50IENlcnRpZmljYXRpb24gQXV0aG9yaXR5
+MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCTdLS25MVL1qFof2LV7PdRV7Ny
+Spj10InJrWPNTTVRaoTUrcloeW+46xHbh65cJFET8VQlhK8pK5/jgOLZy93GRUk0
+iJBeAZfv6lOm3fzB3ksqJeTpNfpVBQbliXrqpBFXO/x8PTbNZzVtpKklWb1m9fkn
+5JVn1j+SgF7yNH0rhQIDAQABo4IBnjCCAZowEQYJYIZIAYb4QgEBBAQDAgAHMIHd
+BgNVHR8EgdUwgdIwgc+ggcyggcmkgcYwgcMxFDASBgNVBAoTC0VudHJ1c3QubmV0
+MUAwPgYDVQQLFDd3d3cuZW50cnVzdC5uZXQvR0NDQV9DUFMgaW5jb3JwLiBieSBy
+ZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMjAwMCBFbnRydXN0Lm5l
+dCBMaW1pdGVkMTMwMQYDVQQDEypFbnRydXN0Lm5ldCBDbGllbnQgQ2VydGlmaWNh
+dGlvbiBBdXRob3JpdHkxDTALBgNVBAMTBENSTDEwKwYDVR0QBCQwIoAPMjAwMDAy
+MDcxNjE2NDBagQ8yMDIwMDIwNzE2NDY0MFowCwYDVR0PBAQDAgEGMB8GA1UdIwQY
+MBaAFISLdP3FjcD/J20gN0V8/i3OutN9MB0GA1UdDgQWBBSEi3T9xY3A/ydtIDdF
+fP4tzrrTfTAMBgNVHRMEBTADAQH/MB0GCSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4w
+AwIEkDANBgkqhkiG9w0BAQQFAAOBgQBObzWAO9GK9Q6nIMstZVXQkvTnhLUGJoMS
+hAusO7JE7r3PQNsgDrpuFOow4DtifH+La3xKp9U1PL6oXOpLu5OOgGarDyn9TS2/
+GpsKkMWr2tGzhtQvJFJcem3G8v7lTRowjJDyutdKPkN+1MhQGof4T4HHdguEOnKd
+zmVml64mXg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIElTCCA/6gAwIBAgIEOJsRPDANBgkqhkiG9w0BAQQFADCBujEUMBIGA1UEChML
+RW50cnVzdC5uZXQxPzA9BgNVBAsUNnd3dy5lbnRydXN0Lm5ldC9TU0xfQ1BTIGlu
+Y29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMcKGMpIDIwMDAg
+RW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5uZXQgU2VjdXJl
+IFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMDAyMDQxNzIwMDBa
+Fw0yMDAyMDQxNzUwMDBaMIG6MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDE/MD0GA1UE
+CxQ2d3d3LmVudHJ1c3QubmV0L1NTTF9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1p
+dHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMjAwMCBFbnRydXN0Lm5ldCBMaW1pdGVk
+MTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRp
+b24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDHwV9OcfHO
+8GCGD9JYf9Mzly0XonUwtZZkJi9ow0SrqHXmAGc0V55lxyKbc+bT3QgON1WqJUaB
+bL3+qPZ1V1eMkGxKwz6LS0MKyRFWmponIpnPVZ5h2QLifLZ8OAfc439PmrkDQYC2
+dWcTC5/oVzbIXQA23mYU2m52H083jIITiQIDAQABo4IBpDCCAaAwEQYJYIZIAYb4
+QgEBBAQDAgAHMIHjBgNVHR8EgdswgdgwgdWggdKggc+kgcwwgckxFDASBgNVBAoT
+C0VudHJ1c3QubmV0MT8wPQYDVQQLFDZ3d3cuZW50cnVzdC5uZXQvU1NMX0NQUyBp
+bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAyMDAw
+IEVudHJ1c3QubmV0IExpbWl0ZWQxOjA4BgNVBAMTMUVudHJ1c3QubmV0IFNlY3Vy
+ZSBTZXJ2ZXIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxDTALBgNVBAMTBENSTDEw
+KwYDVR0QBCQwIoAPMjAwMDAyMDQxNzIwMDBagQ8yMDIwMDIwNDE3NTAwMFowCwYD
+VR0PBAQDAgEGMB8GA1UdIwQYMBaAFMtswGvjuz7L/CKc/vuLkpyw8m4iMB0GA1Ud
+DgQWBBTLbMBr47s+y/winP77i5KcsPJuIjAMBgNVHRMEBTADAQH/MB0GCSqGSIb2
+fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0BAQQFAAOBgQBi24GRzsia
+d0Iv7L0no1MPUBvqTpLwqa+poLpIYcvvyQbvH9X07t9WLebKahlzqlO+krNQAraF
+JnJj2HVQYnUUt7NQGj/KEQALhUVpbbalrlHhStyCP2yMNLJ3a9kC9n8O6mUE8c1U
+yrrJzOCE98g+EZfTYAkYvAX/bIkz8OwVDw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEXDCCA0SgAwIBAgIEOGO5ZjANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML
+RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp
+bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5
+IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp
+ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0xOTEy
+MjQxODIwNTFaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3
+LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp
+YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG
+A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq
+K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe
+sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX
+MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT
+XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/
+HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH
+4QIDAQABo3QwcjARBglghkgBhvhCAQEEBAMCAAcwHwYDVR0jBBgwFoAUVeSB0RGA
+vtiJuQijMfmhJAkWuXAwHQYDVR0OBBYEFFXkgdERgL7YibkIozH5oSQJFrlwMB0G
+CSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEA
+WUesIYSKF8mciVMeuoCFGsY8Tj6xnLZ8xpJdGGQC49MGCBFhfGPjK50xA3B20qMo
+oPS7mmNz7W3lKtvtFKkrxjYR0CvrB4ul2p5cGZ1WEvVUKcgF7bISKo30Axv/55IQ
+h7A6tcOdBTcSo8f0FbnVpDkWm1M6I5HxqIKiaohowXkCIryqptau37AUX7iH0N18
+f3v/rxzP5tsHrV7bhZ3QKw0z2wTR5klAEyt2+z7pnIkPFc4YsIV4IU9rTw76NmfN
+B/L/CNDi3tm/Kq+4h4YhPATKt5Rof8886ZjXOP/swNlQ8C5LWK5Gb9Auw2DaclVy
+vUxFnmG6v4SBkgPR0ml8xQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIE7TCCBFagAwIBAgIEOAOR7jANBgkqhkiG9w0BAQQFADCByTELMAkGA1UEBhMC
+VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MUgwRgYDVQQLFD93d3cuZW50cnVzdC5u
+ZXQvQ2xpZW50X0NBX0luZm8vQ1BTIGluY29ycC4gYnkgcmVmLiBsaW1pdHMgbGlh
+Yi4xJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNV
+BAMTKkVudHJ1c3QubmV0IENsaWVudCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe
+Fw05OTEwMTIxOTI0MzBaFw0xOTEwMTIxOTU0MzBaMIHJMQswCQYDVQQGEwJVUzEU
+MBIGA1UEChMLRW50cnVzdC5uZXQxSDBGBgNVBAsUP3d3dy5lbnRydXN0Lm5ldC9D
+bGllbnRfQ0FfSW5mby9DUFMgaW5jb3JwLiBieSByZWYuIGxpbWl0cyBsaWFiLjEl
+MCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMq
+RW50cnVzdC5uZXQgQ2xpZW50IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0G
+CSqGSIb3DQEBAQUAA4GLADCBhwKBgQDIOpleMRffrCdvkHvkGf9FozTC28GoT/Bo
+6oT9n3V5z8GKUZSvx1cDR2SerYIbWtp/N3hHuzeYEpbOxhN979IMMFGpOZ5V+Pux
+5zDeg7K6PvHViTs7hbqqdCz+PzFur5GVbgbUB01LLFZHGARS2g4Qk79jkJvh34zm
+AqTmT173iwIBA6OCAeAwggHcMBEGCWCGSAGG+EIBAQQEAwIABzCCASIGA1UdHwSC
+ARkwggEVMIHkoIHhoIHepIHbMIHYMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50
+cnVzdC5uZXQxSDBGBgNVBAsUP3d3dy5lbnRydXN0Lm5ldC9DbGllbnRfQ0FfSW5m
+by9DUFMgaW5jb3JwLiBieSByZWYuIGxpbWl0cyBsaWFiLjElMCMGA1UECxMcKGMp
+IDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5uZXQg
+Q2xpZW50IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCyg
+KqAohiZodHRwOi8vd3d3LmVudHJ1c3QubmV0L0NSTC9DbGllbnQxLmNybDArBgNV
+HRAEJDAigA8xOTk5MTAxMjE5MjQzMFqBDzIwMTkxMDEyMTkyNDMwWjALBgNVHQ8E
+BAMCAQYwHwYDVR0jBBgwFoAUxPucKXuXzUyW/O5bs8qZdIuV6kwwHQYDVR0OBBYE
+FMT7nCl7l81MlvzuW7PKmXSLlepMMAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EA
+BAwwChsEVjQuMAMCBJAwDQYJKoZIhvcNAQEEBQADgYEAP66K8ddmAwWePvrqHEa7
+pFuPeJoSSJn59DXeDDYHAmsQOokUgZwxpnyyQbJq5wcBoUv5nyU7lsqZwz6hURzz
+wy5E97BnRqqS5TvaHBkUODDV4qIxJS7x7EU47fgGWANzYrAQMY9Av2TgXD7FTx/a
+EkP/TOYGJqibGapEPHayXOw=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC
+VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u
+ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc
+KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u
+ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05OTA1
+MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQswCQYDVQQGEwJVUzEUMBIGA1UE
+ChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5j
+b3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBF
+bnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUg
+U2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUA
+A4GLADCBhwKBgQDNKIM0VBuJ8w+vN5Ex/68xYMmo6LIQaO2f55M28Qpku0f1BBc/
+I0dNxScZgSYMVHINiC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5gXpa0zf3
+wkrYKZImZNHkmGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OC
+AdcwggHTMBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHb
+oIHYpIHVMIHSMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5
+BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1p
+dHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1pdGVk
+MTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRp
+b24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNodHRwOi8vd3d3LmVu
+dHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAigA8xOTk5MDUyNTE2MDk0
+MFqBDzIwMTkwNTI1MTYwOTQwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAU8Bdi
+E1U9s/8KAGv7UISX8+1i0BowHQYDVR0OBBYEFPAXYhNVPbP/CgBr+1CEl/PtYtAa
+MAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI
+hvcNAQEFBQADgYEAkNwwAvpkdMKnCqV8IY00F6j7Rw7/JXyNEwr75Ji174z4xRAN
+95K+8cPV1ZVqBLssziY2ZcgxxufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9n9cd
+2cNgQ4xYDiKWL2KjLB+6rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC
+VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0
+Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW
+KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl
+cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw
+NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw
+NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy
+ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV
+BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ
+KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo
+Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4
+4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9
+KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI
+rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi
+94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB
+sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi
+gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo
+kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE
+vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA
+A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t
+O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua
+AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP
+9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/
+eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m
+0vdXcDazv/wor3ElhVsT/h5/WrQ8
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV
+UzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy
+dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1
+MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx
+dWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B
+AQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f
+BeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A
+cJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC
+AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ
+MA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm
+aWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw
+ODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj
+IBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF
+MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA
+A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y
+7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh
+1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEc
+MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBT
+ZWN1cmUgR2xvYmFsIGVCdXNpbmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIw
+MDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0VxdWlmYXggU2Vj
+dXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEdsb2JhbCBlQnVzaW5l
+c3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRVPEnC
+UdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc
+58O/gGzNqfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/
+o5brhTMhHD4ePmBudpxnhcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAH
+MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUvqigdHJQa0S3ySPY+6j/s1dr
+aGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hsMA0GCSqGSIb3DQEBBAUA
+A4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okENI7SS+RkA
+Z70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv
+8qIYNMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICgjCCAeugAwIBAgIBBDANBgkqhkiG9w0BAQQFADBTMQswCQYDVQQGEwJVUzEc
+MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBT
+ZWN1cmUgZUJ1c2luZXNzIENBLTEwHhcNOTkwNjIxMDQwMDAwWhcNMjAwNjIxMDQw
+MDAwWjBTMQswCQYDVQQGEwJVUzEcMBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5j
+LjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNzIENBLTEwgZ8wDQYJ
+KoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vGbwXt3fek6lfWg0XTzQaDJj0ItlZ1MRo
+RvC0NcWFAyDGr0WlIVFFQesWWDYyb+JQYmT5/VGcqiTZ9J2DKocKIdMSODRsjQBu
+WqDZQu4aIZX5UkxVWsUPOE9G+m34LjXWHXzr4vCwdYDIqROsvojvOm6rXyo4YgKw
+Env+j6YDAgMBAAGjZjBkMBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTAD
+AQH/MB8GA1UdIwQYMBaAFEp4MlIR21kWNl7fwRQ2QGpHfEyhMB0GA1UdDgQWBBRK
+eDJSEdtZFjZe38EUNkBqR3xMoTANBgkqhkiG9w0BAQQFAAOBgQB1W6ibAxHm6VZM
+zfmpTMANmvPMZWnmJXbMWbfWVMMdzZmsGd20hdXgPfxiIKeES1hl8eL5lSE/9dR+
+WB5Hh1Q+WKG1tfgq73HnvMP2sUlG4tega+VWeponmHxGYhTnyfxuAxJ5gDgdSIKN
+/Bf+KpYrtWKmpj29f5JZzVoqgrI3eQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDIDCCAomgAwIBAgIEN3DPtTANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV
+UzEXMBUGA1UEChMORXF1aWZheCBTZWN1cmUxJjAkBgNVBAsTHUVxdWlmYXggU2Vj
+dXJlIGVCdXNpbmVzcyBDQS0yMB4XDTk5MDYyMzEyMTQ0NVoXDTE5MDYyMzEyMTQ0
+NVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkVxdWlmYXggU2VjdXJlMSYwJAYD
+VQQLEx1FcXVpZmF4IFNlY3VyZSBlQnVzaW5lc3MgQ0EtMjCBnzANBgkqhkiG9w0B
+AQEFAAOBjQAwgYkCgYEA5Dk5kx5SBhsoNviyoynF7Y6yEb3+6+e0dMKP/wXn2Z0G
+vxLIPw7y1tEkshHe0XMJitSxLJgJDR5QRrKDpkWNYmi7hRsgcDKqQM2mll/EcTc/
+BPO3QSQ5BxoeLmFYoBIL5aXfxavqN3HMHMg3OrmXUqesxWoklE6ce8/AatbfIb0C
+AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEX
+MBUGA1UEChMORXF1aWZheCBTZWN1cmUxJjAkBgNVBAsTHUVxdWlmYXggU2VjdXJl
+IGVCdXNpbmVzcyBDQS0yMQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTkw
+NjIzMTIxNDQ1WjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUUJ4L6q9euSBIplBq
+y/3YIHqngnYwHQYDVR0OBBYEFFCeC+qvXrkgSKZQasv92CB6p4J2MAwGA1UdEwQF
+MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA
+A4GBAAyGgq3oThr1jokn4jVYPSm0B482UJW/bsGe68SQsoWou7dC4A8HOd/7npCy
+0cE+U58DRLB+S/Rv5Hwf5+Kx5Lia78O9zt4LMjTZ3ijtM2vE1Nc9ElirfQkty3D1
+E4qUoSek1nDFbZS1yX2doNLGCEnZZpum0/QL3MUmV+GRMOrN
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEVzCCAz+gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBnTELMAkGA1UEBhMCRVMx
+IjAgBgNVBAcTGUMvIE11bnRhbmVyIDI0NCBCYXJjZWxvbmExQjBABgNVBAMTOUF1
+dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2
+MjYzNDA2ODEmMCQGCSqGSIb3DQEJARYXY2FAZmlybWFwcm9mZXNpb25hbC5jb20w
+HhcNMDExMDI0MjIwMDAwWhcNMTMxMDI0MjIwMDAwWjCBnTELMAkGA1UEBhMCRVMx
+IjAgBgNVBAcTGUMvIE11bnRhbmVyIDI0NCBCYXJjZWxvbmExQjBABgNVBAMTOUF1
+dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2
+MjYzNDA2ODEmMCQGCSqGSIb3DQEJARYXY2FAZmlybWFwcm9mZXNpb25hbC5jb20w
+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDnIwNvbyOlXnjOlSztlB5u
+Cp4Bx+ow0Syd3Tfom5h5VtP8c9/Qit5Vj1H5WuretXDE7aTt/6MNbg9kUDGvASdY
+rv5sp0ovFy3Tc9UTHI9ZpTQsHVQERc1ouKDAA6XPhUJHlShbz++AbOCQl4oBPB3z
+hxAwJkh91/zpnZFx/0GaqUC1N5wpIE8fUuOgfRNtVLcK3ulqTgesrBlf3H5idPay
+BQC6haD9HThuy1q7hryUZzM1gywfI834yJFxzJeL764P3CkDG8A563DtwW4O2GcL
+iam8NeTvtjS0pbbELaW+0MOUJEjb35bTALVmGotmBQ/dPz/LP6pemkr4tErvlTcb
+AgMBAAGjgZ8wgZwwKgYDVR0RBCMwIYYfaHR0cDovL3d3dy5maXJtYXByb2Zlc2lv
+bmFsLmNvbTASBgNVHRMBAf8ECDAGAQH/AgEBMCsGA1UdEAQkMCKADzIwMDExMDI0
+MjIwMDAwWoEPMjAxMzEwMjQyMjAwMDBaMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4E
+FgQUMwugZtHq2s7eYpMEKFK1FH84aLcwDQYJKoZIhvcNAQEFBQADggEBAEdz/o0n
+VPD11HecJ3lXV7cVVuzH2Fi3AQL0M+2TUIiefEaxvT8Ub/GzR0iLjJcG1+p+o1wq
+u00vR+L4OQbJnC4xGgN49Lw4xiKLMzHwFgQEffl25EvXwOaD7FnMP97/T2u3Z36m
+hoEyIwOdyPdfwUpgpZKpsaSgYMN4h7Mi8yrrW6ntBas3D7Hi05V2Y1Z0jFhyGzfl
+ZKG+TQyTmAyX9odtsz/ny4Cm7YjHX1BiAuiZdBbQ5rQ58SfLyEDW44YQqSMSkuBp
+QWOnryULwMWSyx6Yo1q6xTMPoJcB3X/ge9YGVM+h4k0460tQtcsm9MracEpqoeJ5
+quGnM/b9Sh/22WA=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICWjCCAcMCAgGlMA0GCSqGSIb3DQEBBAUAMHUxCzAJBgNVBAYTAlVTMRgwFgYD
+VQQKEw9HVEUgQ29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJlclRydXN0IFNv
+bHV0aW9ucywgSW5jLjEjMCEGA1UEAxMaR1RFIEN5YmVyVHJ1c3QgR2xvYmFsIFJv
+b3QwHhcNOTgwODEzMDAyOTAwWhcNMTgwODEzMjM1OTAwWjB1MQswCQYDVQQGEwJV
+UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU
+cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds
+b2JhbCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVD6C28FCc6HrH
+iM3dFw4usJTQGz0O9pTAipTHBsiQl8i4ZBp6fmw8U+E3KHNgf7KXUwefU/ltWJTS
+r41tiGeA5u2ylc9yMcqlHHK6XALnZELn+aks1joNrI1CqiQBOeacPwGFVw1Yh0X4
+04Wqk2kmhXBIgD8SFcd5tB8FLztimQIDAQABMA0GCSqGSIb3DQEBBAUAA4GBAG3r
+GwnpXtlR22ciYaQqPEh346B8pt5zohQDhT37qw4wxYMWM4ETCJ57NE7fQMh017l9
+3PR2VX2bY1QY6fDq81yx2YtCHrnAlU66+tXifPVoYb+O7AWXX1uw16OFNMQkpw0P
+lZPvy5TYnh+dXIVtx6quTx8itc2VrbqnzPmrC3p/
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIB+jCCAWMCAgGjMA0GCSqGSIb3DQEBBAUAMEUxCzAJBgNVBAYTAlVTMRgwFgYD
+VQQKEw9HVEUgQ29ycG9yYXRpb24xHDAaBgNVBAMTE0dURSBDeWJlclRydXN0IFJv
+b3QwHhcNOTYwMjIzMjMwMTAwWhcNMDYwMjIzMjM1OTAwWjBFMQswCQYDVQQGEwJV
+UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMRwwGgYDVQQDExNHVEUgQ3liZXJU
+cnVzdCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC45k+625h8cXyv
+RLfTD0bZZOWTwUKOx7pJjTUteueLveUFMVnGsS8KDPufpz+iCWaEVh43KRuH6X4M
+ypqfpX/1FZSj1aJGgthoTNE3FQZor734sLPwKfWVWgkWYXcKIiXUT0Wqx73llt/5
+1KiOQswkwB6RJ0q1bQaAYznEol44AwIDAQABMA0GCSqGSIb3DQEBBAUAA4GBABKz
+dcZfHeFhVYAA1IFLezEPI2PnPfMD+fQ2qLvZ46WXTeorKeDWanOB5sCJo9Px4KWl
+IjeaY8JIILTbcuPI9tl8vrGvU9oUtCG41tWW4/5ODFlitppK+ULdjG+BqXH/9Apy
+bW1EDp3zdHSo1TRJ6V6e6bR64eVaH4QwnNOfpSXY
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
+MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
+YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG
+EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg
+R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9
+9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq
+fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv
+iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU
+1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+
+bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW
+MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA
+ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l
+uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn
+Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS
+tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF
+PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un
+hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV
+5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDZjCCAk6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJVUzEW
+MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFs
+IENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMTkwMzA0MDUwMDAwWjBEMQswCQYDVQQG
+EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3Qg
+R2xvYmFsIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDvPE1A
+PRDfO1MA4Wf+lGAVPoWI8YkNkMgoI5kF6CsgncbzYEbYwbLVjDHZ3CB5JIG/NTL8
+Y2nbsSpr7iFY8gjpeMtvy/wWUsiRxP89c96xPqfCfWbB9X5SJBri1WeR0IIQ13hL
+TytCOb1kLUCgsBDTOEhGiKEMuzozKmKY+wCdE1l/bztyqu6mD4b5BWHqZ38MN5aL
+5mkWRxHCJ1kDs6ZgwiFAVvqgx306E+PsV8ez1q6diYD3Aecs9pYrEw15LNnA5IZ7
+S4wMcoKK+xfNAGw6EzywhIdLFnopsk/bHdQL82Y3vdj2V7teJHq4PIu5+pIaGoSe
+2HSPqht/XvT+RSIhAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE
+FHE4NvICMVNHK266ZUapEBVYIAUJMB8GA1UdIwQYMBaAFHE4NvICMVNHK266ZUap
+EBVYIAUJMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAQEAA/e1K6td
+EPx7srJerJsOflN4WT5CBP51o62sgU7XAotexC3IUnbHLB/8gTKY0UvGkpMzNTEv
+/NgdRN3ggX+d6YvhZJFiCzkIjKx0nVnZellSlxG5FntvRdOW2TF9AjYPnDtuzywN
+A0ZF66D0f0hExghAzN4bcLUprbqLOzRldRtxIR0sFAqwlpW41uryZfspuk/qkZN0
+abby/+Ea0AzRdoXLiiW9l14sbxWZJue2Kf8i7MkCx1YAzUm5s2x7UwQa4qjJqhIF
+I8LO57sEAszAR6LkxCkvW0VXiVHuPOtSCP8HNR6fNWpHSlaY0VqFH4z1Ir+rzoPz
+4iIprn2DQKi6bA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBY
+MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMo
+R2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEx
+MjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgxCzAJBgNVBAYTAlVTMRYwFAYDVQQK
+Ew1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQcmltYXJ5IENlcnRp
+ZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
+AQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9
+AWbK7hWNb6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjA
+ZIVcFU2Ix7e64HXprQU9nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE0
+7e9GceBrAqg1cmuXm2bgyxx5X9gaBGgeRwLmnWDiNpcB3841kt++Z8dtd1k7j53W
+kBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGttm/81w7a4DSwDRp35+MI
+mO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G
+A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJ
+KoZIhvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ1
+6CePbJC/kRYkRj5KTs4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl
+4b7UVXGYNTq+k+qurUKykG/g/CFNNWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6K
+oKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHaFloxt/m0cYASSJlyc1pZU8Fj
+UjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG1riR/aYNKxoU
+AT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEW
+MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVy
+c2FsIENBMB4XDTA0MDMwNDA1MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UE
+BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xHjAcBgNVBAMTFUdlb1RydXN0
+IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKYV
+VaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9tJPi8
+cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTT
+QjOgNB0eRXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFh
+F7em6fgemdtzbvQKoiFs7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2v
+c7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d8Lsrlh/eezJS/R27tQahsiFepdaVaH/w
+mZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7VqnJNk22CDtucvc+081xd
+VHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3CgaRr0BHdCX
+teGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZ
+f9hBZ3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfRe
+Bi9Fi1jUIxaS5BZuKGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+
+nhutxx9z3SxPGWX9f5NAEC7S8O08ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB
+/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0XG0D08DYj3rWMB8GA1UdIwQY
+MBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG
+9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc
+aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fX
+IwjhmF7DWgh2qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzyn
+ANXH/KttgCJwpQzgXQQpAvvLoJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0z
+uzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsKxr2EoyNB3tZ3b4XUhRxQ4K5RirqN
+Pnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxFKyDuSN/n3QmOGKja
+QI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2DFKW
+koRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9
+ER/frslKxfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQt
+DF4JbAiXfKM9fJP/P6EUp8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/Sfuvm
+bJxPgWp6ZKy7PtXny3YuxadIwVyQD8vIP/rmMuGNG2+k5o7Y+SlIis5z/iw=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEW
+MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVy
+c2FsIENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYD
+VQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1
+c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
+AQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0DE81
+WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUG
+FF+3Qs17j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdq
+XbboW0W63MOhBW9Wjo8QJqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxL
+se4YuU6W3Nx2/zu+z18DwPw76L5GG//aQMJS9/7jOvdqdzXQ2o3rXhhqMcceujwb
+KNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2WP0+GfPtDCapkzj4T8Fd
+IgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP20gaXT73
+y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRt
+hAAnZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgoc
+QIgfksILAAX/8sgCSqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4
+Lt1ZrtmhN79UNdxzMk+MBB4zsslG8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNV
+HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAfBgNV
+HSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8EBAMCAYYwDQYJ
+KoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z
+dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQ
+L1EuxBRa3ugZ4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgr
+Fg5fNuH8KrUwJM/gYwx7WBr+mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSo
+ag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpqA1Ihn0CoZ1Dy81of398j9tx4TuaY
+T1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpgY+RdM4kX2TGq2tbz
+GDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiPpm8m
+1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJV
+OCiNUW7dFGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH
+6aLcr34YEoP9VhdBLtUpgn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwX
+QMAJKOSLakhT2+zNVVXxxvjpoixMptEmX36vWkzaH6byHCx+rgIW0lbQL1dTR+iS
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG
+A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
+b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw
+MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
+YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT
+aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ
+jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp
+xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp
+1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG
+snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ
+U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8
+9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E
+BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B
+AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz
+yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE
+38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP
+AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad
+DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME
+HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G
+A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp
+Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1
+MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG
+A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL
+v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8
+eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq
+tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd
+C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa
+zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB
+mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH
+V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n
+bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG
+3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs
+J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO
+291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS
+ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd
+AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7
+TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh
+MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE
+YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3
+MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo
+ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg
+MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN
+ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA
+PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w
+wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi
+EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY
+avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+
+YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE
+sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h
+/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5
+IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj
+YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
+ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy
+OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P
+TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
+HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER
+dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf
+ReYNnyicsbkqWletNw+vHX/bvZ8=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIH6jCCB1OgAwIBAgIBADANBgkqhkiG9w0BAQUFADCCARIxCzAJBgNVBAYTAkVT
+MRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UE
+ChMlSVBTIEludGVybmV0IHB1Ymxpc2hpbmcgU2VydmljZXMgcy5sLjErMCkGA1UE
+ChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAgQi02MDkyOTQ1MjEuMCwGA1UECxMl
+SVBTIENBIENMQVNFMSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMl
+SVBTIENBIENMQVNFMSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEeMBwGCSqGSIb3
+DQEJARYPaXBzQG1haWwuaXBzLmVzMB4XDTAxMTIyOTAwNTkzOFoXDTI1MTIyNzAw
+NTkzOFowggESMQswCQYDVQQGEwJFUzESMBAGA1UECBMJQmFyY2Vsb25hMRIwEAYD
+VQQHEwlCYXJjZWxvbmExLjAsBgNVBAoTJUlQUyBJbnRlcm5ldCBwdWJsaXNoaW5n
+IFNlcnZpY2VzIHMubC4xKzApBgNVBAoUImlwc0BtYWlsLmlwcy5lcyBDLkkuRi4g
+IEItNjA5Mjk0NTIxLjAsBgNVBAsTJUlQUyBDQSBDTEFTRTEgQ2VydGlmaWNhdGlv
+biBBdXRob3JpdHkxLjAsBgNVBAMTJUlQUyBDQSBDTEFTRTEgQ2VydGlmaWNhdGlv
+biBBdXRob3JpdHkxHjAcBgkqhkiG9w0BCQEWD2lwc0BtYWlsLmlwcy5lczCBnzAN
+BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4FEnpwvdr9G5Q1uCN0VWcu+atsIS7ywS
+zHb5BlmvXSHU0lq4oNTzav3KaY1mSPd05u42veiWkXWmcSjK5yISMmmwPh5r9FBS
+YmL9Yzt9fuzuOOpi9GyocY3h6YvJP8a1zZRCb92CRTzo3wno7wpVqVZHYUxJZHMQ
+KD/Kvwn/xi8CAwEAAaOCBEowggRGMB0GA1UdDgQWBBTrsxl588GlHKzcuh9morKb
+adB4CDCCAUQGA1UdIwSCATswggE3gBTrsxl588GlHKzcuh9morKbadB4CKGCARqk
+ggEWMIIBEjELMAkGA1UEBhMCRVMxEjAQBgNVBAgTCUJhcmNlbG9uYTESMBAGA1UE
+BxMJQmFyY2Vsb25hMS4wLAYDVQQKEyVJUFMgSW50ZXJuZXQgcHVibGlzaGluZyBT
+ZXJ2aWNlcyBzLmwuMSswKQYDVQQKFCJpcHNAbWFpbC5pcHMuZXMgQy5JLkYuICBC
+LTYwOTI5NDUyMS4wLAYDVQQLEyVJUFMgQ0EgQ0xBU0UxIENlcnRpZmljYXRpb24g
+QXV0aG9yaXR5MS4wLAYDVQQDEyVJUFMgQ0EgQ0xBU0UxIENlcnRpZmljYXRpb24g
+QXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXOCAQAwDAYD
+VR0TBAUwAwEB/zAMBgNVHQ8EBQMDB/+AMGsGA1UdJQRkMGIGCCsGAQUFBwMBBggr
+BgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYKKwYBBAGCNwIB
+FQYKKwYBBAGCNwIBFgYKKwYBBAGCNwoDAQYKKwYBBAGCNwoDBDARBglghkgBhvhC
+AQEEBAMCAAcwGgYDVR0RBBMwEYEPaXBzQG1haWwuaXBzLmVzMBoGA1UdEgQTMBGB
+D2lwc0BtYWlsLmlwcy5lczBBBglghkgBhvhCAQ0ENBYyQ0xBU0UxIENBIENlcnRp
+ZmljYXRlIGlzc3VlZCBieSBodHRwOi8vd3d3Lmlwcy5lcy8wKQYJYIZIAYb4QgEC
+BBwWGmh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvMDoGCWCGSAGG+EIBBAQtFito
+dHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL2lwczIwMDJDTEFTRTEuY3JsMD8GCWCG
+SAGG+EIBAwQyFjBodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL3Jldm9jYXRpb25D
+TEFTRTEuaHRtbD8wPAYJYIZIAYb4QgEHBC8WLWh0dHA6Ly93d3cuaXBzLmVzL2lw
+czIwMDIvcmVuZXdhbENMQVNFMS5odG1sPzA6BglghkgBhvhCAQgELRYraHR0cDov
+L3d3dy5pcHMuZXMvaXBzMjAwMi9wb2xpY3lDTEFTRTEuaHRtbDBzBgNVHR8EbDBq
+MDGgL6AthitodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL2lwczIwMDJDTEFTRTEu
+Y3JsMDWgM6Axhi9odHRwOi8vd3d3YmFjay5pcHMuZXMvaXBzMjAwMi9pcHMyMDAy
+Q0xBU0UxLmNybDAvBggrBgEFBQcBAQQjMCEwHwYIKwYBBQUHMAGGE2h0dHA6Ly9v
+Y3NwLmlwcy5lcy8wDQYJKoZIhvcNAQEFBQADgYEAK9Dr/drIyllq2tPMMi7JVBuK
+Yn4VLenZMdMu9Ccj/1urxUq2ckCuU3T0vAW0xtnIyXf7t/k0f3gA+Nak5FI/LEpj
+V4F1Wo7ojPsCwJTGKbqz3Bzosq/SLmJbGqmODszFV0VRFOlOHIilkfSj945RyKm+
+hjM+5i9Ibq9UkE6tsSU=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIH6jCCB1OgAwIBAgIBADANBgkqhkiG9w0BAQUFADCCARIxCzAJBgNVBAYTAkVT
+MRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UE
+ChMlSVBTIEludGVybmV0IHB1Ymxpc2hpbmcgU2VydmljZXMgcy5sLjErMCkGA1UE
+ChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAgQi02MDkyOTQ1MjEuMCwGA1UECxMl
+SVBTIENBIENMQVNFMyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMl
+SVBTIENBIENMQVNFMyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEeMBwGCSqGSIb3
+DQEJARYPaXBzQG1haWwuaXBzLmVzMB4XDTAxMTIyOTAxMDE0NFoXDTI1MTIyNzAx
+MDE0NFowggESMQswCQYDVQQGEwJFUzESMBAGA1UECBMJQmFyY2Vsb25hMRIwEAYD
+VQQHEwlCYXJjZWxvbmExLjAsBgNVBAoTJUlQUyBJbnRlcm5ldCBwdWJsaXNoaW5n
+IFNlcnZpY2VzIHMubC4xKzApBgNVBAoUImlwc0BtYWlsLmlwcy5lcyBDLkkuRi4g
+IEItNjA5Mjk0NTIxLjAsBgNVBAsTJUlQUyBDQSBDTEFTRTMgQ2VydGlmaWNhdGlv
+biBBdXRob3JpdHkxLjAsBgNVBAMTJUlQUyBDQSBDTEFTRTMgQ2VydGlmaWNhdGlv
+biBBdXRob3JpdHkxHjAcBgkqhkiG9w0BCQEWD2lwc0BtYWlsLmlwcy5lczCBnzAN
+BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqxf+DrDGaBtT8FK+n/ra+osTBLsBjzLZ
+H49NzjaY2uQARIwo2BNEKqRrThckQpzTiKRBgtYj+4vJhuW5qYIF3PHeH+AMmVWY
+8jjsbJ0gA8DvqqPGZARRLXgNo9KoOtYkTOmWehisEyMiG3zoMRGzXwmqMHBxRiVr
+SXGAK5UBsh8CAwEAAaOCBEowggRGMB0GA1UdDgQWBBS4k/8uy9wsjqLnev42USGj
+mFsMNDCCAUQGA1UdIwSCATswggE3gBS4k/8uy9wsjqLnev42USGjmFsMNKGCARqk
+ggEWMIIBEjELMAkGA1UEBhMCRVMxEjAQBgNVBAgTCUJhcmNlbG9uYTESMBAGA1UE
+BxMJQmFyY2Vsb25hMS4wLAYDVQQKEyVJUFMgSW50ZXJuZXQgcHVibGlzaGluZyBT
+ZXJ2aWNlcyBzLmwuMSswKQYDVQQKFCJpcHNAbWFpbC5pcHMuZXMgQy5JLkYuICBC
+LTYwOTI5NDUyMS4wLAYDVQQLEyVJUFMgQ0EgQ0xBU0UzIENlcnRpZmljYXRpb24g
+QXV0aG9yaXR5MS4wLAYDVQQDEyVJUFMgQ0EgQ0xBU0UzIENlcnRpZmljYXRpb24g
+QXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXOCAQAwDAYD
+VR0TBAUwAwEB/zAMBgNVHQ8EBQMDB/+AMGsGA1UdJQRkMGIGCCsGAQUFBwMBBggr
+BgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYKKwYBBAGCNwIB
+FQYKKwYBBAGCNwIBFgYKKwYBBAGCNwoDAQYKKwYBBAGCNwoDBDARBglghkgBhvhC
+AQEEBAMCAAcwGgYDVR0RBBMwEYEPaXBzQG1haWwuaXBzLmVzMBoGA1UdEgQTMBGB
+D2lwc0BtYWlsLmlwcy5lczBBBglghkgBhvhCAQ0ENBYyQ0xBU0UzIENBIENlcnRp
+ZmljYXRlIGlzc3VlZCBieSBodHRwOi8vd3d3Lmlwcy5lcy8wKQYJYIZIAYb4QgEC
+BBwWGmh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvMDoGCWCGSAGG+EIBBAQtFito
+dHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL2lwczIwMDJDTEFTRTMuY3JsMD8GCWCG
+SAGG+EIBAwQyFjBodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL3Jldm9jYXRpb25D
+TEFTRTMuaHRtbD8wPAYJYIZIAYb4QgEHBC8WLWh0dHA6Ly93d3cuaXBzLmVzL2lw
+czIwMDIvcmVuZXdhbENMQVNFMy5odG1sPzA6BglghkgBhvhCAQgELRYraHR0cDov
+L3d3dy5pcHMuZXMvaXBzMjAwMi9wb2xpY3lDTEFTRTMuaHRtbDBzBgNVHR8EbDBq
+MDGgL6AthitodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL2lwczIwMDJDTEFTRTMu
+Y3JsMDWgM6Axhi9odHRwOi8vd3d3YmFjay5pcHMuZXMvaXBzMjAwMi9pcHMyMDAy
+Q0xBU0UzLmNybDAvBggrBgEFBQcBAQQjMCEwHwYIKwYBBQUHMAGGE2h0dHA6Ly9v
+Y3NwLmlwcy5lcy8wDQYJKoZIhvcNAQEFBQADgYEAF2VcmZVDAyevJuXr0LMXI/dD
+qsfwfewPxqmurpYPdikc4gYtfibFPPqhwYHOU7BC0ZdXGhd+pFFhxu7pXu8Fuuu9
+D6eSb9ijBmgpjnn1/7/5p6/ksc7C0YBCJwUENPjDfxZ4IwwHJPJGR607VNCv1TGy
+r33I6unUVtkOE7LFRVA=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIH9zCCB2CgAwIBAgIBADANBgkqhkiG9w0BAQUFADCCARQxCzAJBgNVBAYTAkVT
+MRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UE
+ChMlSVBTIEludGVybmV0IHB1Ymxpc2hpbmcgU2VydmljZXMgcy5sLjErMCkGA1UE
+ChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAgQi02MDkyOTQ1MjEvMC0GA1UECxMm
+SVBTIENBIENMQVNFQTEgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxLzAtBgNVBAMT
+JklQUyBDQSBDTEFTRUExIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MR4wHAYJKoZI
+hvcNAQkBFg9pcHNAbWFpbC5pcHMuZXMwHhcNMDExMjI5MDEwNTMyWhcNMjUxMjI3
+MDEwNTMyWjCCARQxCzAJBgNVBAYTAkVTMRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQ
+BgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UEChMlSVBTIEludGVybmV0IHB1Ymxpc2hp
+bmcgU2VydmljZXMgcy5sLjErMCkGA1UEChQiaXBzQG1haWwuaXBzLmVzIEMuSS5G
+LiAgQi02MDkyOTQ1MjEvMC0GA1UECxMmSVBTIENBIENMQVNFQTEgQ2VydGlmaWNh
+dGlvbiBBdXRob3JpdHkxLzAtBgNVBAMTJklQUyBDQSBDTEFTRUExIENlcnRpZmlj
+YXRpb24gQXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXMw
+gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALsw19zQVL01Tp/FTILq0VA8R5j8
+m2mdd81u4D/u6zJfX5/S0HnllXNEITLgCtud186Nq1KLK3jgm1t99P1tCeWu4Wwd
+ByOgF9H5fahGRpEiqLJpxq339fWUoTCUvQDMRH/uxJ7JweaPCjbB/SQ9AaD1e+J8
+eGZDi09Z8pvZ+kmzAgMBAAGjggRTMIIETzAdBgNVHQ4EFgQUZyaW56G/2LUDnf47
+3P7yiuYV3TAwggFGBgNVHSMEggE9MIIBOYAUZyaW56G/2LUDnf473P7yiuYV3TCh
+ggEcpIIBGDCCARQxCzAJBgNVBAYTAkVTMRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQ
+BgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UEChMlSVBTIEludGVybmV0IHB1Ymxpc2hp
+bmcgU2VydmljZXMgcy5sLjErMCkGA1UEChQiaXBzQG1haWwuaXBzLmVzIEMuSS5G
+LiAgQi02MDkyOTQ1MjEvMC0GA1UECxMmSVBTIENBIENMQVNFQTEgQ2VydGlmaWNh
+dGlvbiBBdXRob3JpdHkxLzAtBgNVBAMTJklQUyBDQSBDTEFTRUExIENlcnRpZmlj
+YXRpb24gQXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXOC
+AQAwDAYDVR0TBAUwAwEB/zAMBgNVHQ8EBQMDB/+AMGsGA1UdJQRkMGIGCCsGAQUF
+BwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYKKwYB
+BAGCNwIBFQYKKwYBBAGCNwIBFgYKKwYBBAGCNwoDAQYKKwYBBAGCNwoDBDARBglg
+hkgBhvhCAQEEBAMCAAcwGgYDVR0RBBMwEYEPaXBzQG1haWwuaXBzLmVzMBoGA1Ud
+EgQTMBGBD2lwc0BtYWlsLmlwcy5lczBCBglghkgBhvhCAQ0ENRYzQ0xBU0VBMSBD
+QSBDZXJ0aWZpY2F0ZSBpc3N1ZWQgYnkgaHR0cDovL3d3dy5pcHMuZXMvMCkGCWCG
+SAGG+EIBAgQcFhpodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyLzA7BglghkgBhvhC
+AQQELhYsaHR0cDovL3d3dy5pcHMuZXMvaXBzMjAwMi9pcHMyMDAyQ0xBU0VBMS5j
+cmwwQAYJYIZIAYb4QgEDBDMWMWh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvcmV2
+b2NhdGlvbkNMQVNFQTEuaHRtbD8wPQYJYIZIAYb4QgEHBDAWLmh0dHA6Ly93d3cu
+aXBzLmVzL2lwczIwMDIvcmVuZXdhbENMQVNFQTEuaHRtbD8wOwYJYIZIAYb4QgEI
+BC4WLGh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvcG9saWN5Q0xBU0VBMS5odG1s
+MHUGA1UdHwRuMGwwMqAwoC6GLGh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvaXBz
+MjAwMkNMQVNFQTEuY3JsMDagNKAyhjBodHRwOi8vd3d3YmFjay5pcHMuZXMvaXBz
+MjAwMi9pcHMyMDAyQ0xBU0VBMS5jcmwwLwYIKwYBBQUHAQEEIzAhMB8GCCsGAQUF
+BzABhhNodHRwOi8vb2NzcC5pcHMuZXMvMA0GCSqGSIb3DQEBBQUAA4GBAH66iqyA
+AIQVCtWYUQxkxZwCWINmyq0eB81+atqAB98DNEock8RLWCA1NnHtogo1EqWmZaeF
+aQoO42Hu6r4okzPV7Oi+xNtff6j5YzHIa5biKcJboOeXNp13XjFr/tOn2yrb25aL
+H2betgPAK7N41lUH5Y85UN4HI3LmvSAUS7SG
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIH9zCCB2CgAwIBAgIBADANBgkqhkiG9w0BAQUFADCCARQxCzAJBgNVBAYTAkVT
+MRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UE
+ChMlSVBTIEludGVybmV0IHB1Ymxpc2hpbmcgU2VydmljZXMgcy5sLjErMCkGA1UE
+ChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAgQi02MDkyOTQ1MjEvMC0GA1UECxMm
+SVBTIENBIENMQVNFQTMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxLzAtBgNVBAMT
+JklQUyBDQSBDTEFTRUEzIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MR4wHAYJKoZI
+hvcNAQkBFg9pcHNAbWFpbC5pcHMuZXMwHhcNMDExMjI5MDEwNzUwWhcNMjUxMjI3
+MDEwNzUwWjCCARQxCzAJBgNVBAYTAkVTMRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQ
+BgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UEChMlSVBTIEludGVybmV0IHB1Ymxpc2hp
+bmcgU2VydmljZXMgcy5sLjErMCkGA1UEChQiaXBzQG1haWwuaXBzLmVzIEMuSS5G
+LiAgQi02MDkyOTQ1MjEvMC0GA1UECxMmSVBTIENBIENMQVNFQTMgQ2VydGlmaWNh
+dGlvbiBBdXRob3JpdHkxLzAtBgNVBAMTJklQUyBDQSBDTEFTRUEzIENlcnRpZmlj
+YXRpb24gQXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXMw
+gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAO6AAPYaZC6tasiDsYun7o/ZttvN
+G7uGBiJ2MwwSbUhWYdLcgiViL5/SaTBlA0IjWLxH3GvWdV0XPOH/8lhneaDBgbHU
+VqLyjRGZ/fZ98cfEXgIqmuJKtROKAP2Md4bm15T1IHUuDky/dMQ/gT6DtKM4Ninn
+6Cr1jIhBqoCm42zvAgMBAAGjggRTMIIETzAdBgNVHQ4EFgQUHp9XUEe2YZM50yz8
+2l09BXW3mQIwggFGBgNVHSMEggE9MIIBOYAUHp9XUEe2YZM50yz82l09BXW3mQKh
+ggEcpIIBGDCCARQxCzAJBgNVBAYTAkVTMRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQ
+BgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UEChMlSVBTIEludGVybmV0IHB1Ymxpc2hp
+bmcgU2VydmljZXMgcy5sLjErMCkGA1UEChQiaXBzQG1haWwuaXBzLmVzIEMuSS5G
+LiAgQi02MDkyOTQ1MjEvMC0GA1UECxMmSVBTIENBIENMQVNFQTMgQ2VydGlmaWNh
+dGlvbiBBdXRob3JpdHkxLzAtBgNVBAMTJklQUyBDQSBDTEFTRUEzIENlcnRpZmlj
+YXRpb24gQXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXOC
+AQAwDAYDVR0TBAUwAwEB/zAMBgNVHQ8EBQMDB/+AMGsGA1UdJQRkMGIGCCsGAQUF
+BwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYKKwYB
+BAGCNwIBFQYKKwYBBAGCNwIBFgYKKwYBBAGCNwoDAQYKKwYBBAGCNwoDBDARBglg
+hkgBhvhCAQEEBAMCAAcwGgYDVR0RBBMwEYEPaXBzQG1haWwuaXBzLmVzMBoGA1Ud
+EgQTMBGBD2lwc0BtYWlsLmlwcy5lczBCBglghkgBhvhCAQ0ENRYzQ0xBU0VBMyBD
+QSBDZXJ0aWZpY2F0ZSBpc3N1ZWQgYnkgaHR0cDovL3d3dy5pcHMuZXMvMCkGCWCG
+SAGG+EIBAgQcFhpodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyLzA7BglghkgBhvhC
+AQQELhYsaHR0cDovL3d3dy5pcHMuZXMvaXBzMjAwMi9pcHMyMDAyQ0xBU0VBMy5j
+cmwwQAYJYIZIAYb4QgEDBDMWMWh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvcmV2
+b2NhdGlvbkNMQVNFQTMuaHRtbD8wPQYJYIZIAYb4QgEHBDAWLmh0dHA6Ly93d3cu
+aXBzLmVzL2lwczIwMDIvcmVuZXdhbENMQVNFQTMuaHRtbD8wOwYJYIZIAYb4QgEI
+BC4WLGh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvcG9saWN5Q0xBU0VBMy5odG1s
+MHUGA1UdHwRuMGwwMqAwoC6GLGh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvaXBz
+MjAwMkNMQVNFQTMuY3JsMDagNKAyhjBodHRwOi8vd3d3YmFjay5pcHMuZXMvaXBz
+MjAwMi9pcHMyMDAyQ0xBU0VBMy5jcmwwLwYIKwYBBQUHAQEEIzAhMB8GCCsGAQUF
+BzABhhNodHRwOi8vb2NzcC5pcHMuZXMvMA0GCSqGSIb3DQEBBQUAA4GBAEo9IEca
+2on0eisxeewBwMwB9dbB/MjD81ACUZBYKp/nNQlbMAqBACVHr9QPDp5gJqiVp4MI
+3y2s6Q73nMify5NF8bpqxmdRSmlPa/59Cy9SKcJQrSRE7SOzSMtEQMEDlQwKeAYS
+AfWRMS1Jjbs/RU4s4OjNtckUFQzjB4ObJnXv
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIH9zCCB2CgAwIBAgIBADANBgkqhkiG9w0BAQUFADCCARwxCzAJBgNVBAYTAkVT
+MRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UE
+ChMlSVBTIEludGVybmV0IHB1Ymxpc2hpbmcgU2VydmljZXMgcy5sLjErMCkGA1UE
+ChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAgQi02MDkyOTQ1MjEzMDEGA1UECxMq
+SVBTIENBIENoYWluZWQgQ0FzIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MTMwMQYD
+VQQDEypJUFMgQ0EgQ2hhaW5lZCBDQXMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkx
+HjAcBgkqhkiG9w0BCQEWD2lwc0BtYWlsLmlwcy5lczAeFw0wMTEyMjkwMDUzNTha
+Fw0yNTEyMjcwMDUzNThaMIIBHDELMAkGA1UEBhMCRVMxEjAQBgNVBAgTCUJhcmNl
+bG9uYTESMBAGA1UEBxMJQmFyY2Vsb25hMS4wLAYDVQQKEyVJUFMgSW50ZXJuZXQg
+cHVibGlzaGluZyBTZXJ2aWNlcyBzLmwuMSswKQYDVQQKFCJpcHNAbWFpbC5pcHMu
+ZXMgQy5JLkYuICBCLTYwOTI5NDUyMTMwMQYDVQQLEypJUFMgQ0EgQ2hhaW5lZCBD
+QXMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxMzAxBgNVBAMTKklQUyBDQSBDaGFp
+bmVkIENBcyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEeMBwGCSqGSIb3DQEJARYP
+aXBzQG1haWwuaXBzLmVzMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDcVpJJ
+spQgvJhPUOtopKdJC7/SMejHT8KGC/po/UNaivNgkjWZOLtNA1IhW/A3mTXhQSCB
+hYEFcYGdtJUZqV92NC5jNzVXjrQfQj8VXOF6wV8TGDIxya2+o8eDZh65nAQTy2nB
+Bt4wBrszo7Uf8I9vzv+W6FS+ZoCua9tBhDaiPQIDAQABo4IEQzCCBD8wHQYDVR0O
+BBYEFKGtMbH5PuEXpsirNPxShwkeYlJBMIIBTgYDVR0jBIIBRTCCAUGAFKGtMbH5
+PuEXpsirNPxShwkeYlJBoYIBJKSCASAwggEcMQswCQYDVQQGEwJFUzESMBAGA1UE
+CBMJQmFyY2Vsb25hMRIwEAYDVQQHEwlCYXJjZWxvbmExLjAsBgNVBAoTJUlQUyBJ
+bnRlcm5ldCBwdWJsaXNoaW5nIFNlcnZpY2VzIHMubC4xKzApBgNVBAoUImlwc0Bt
+YWlsLmlwcy5lcyBDLkkuRi4gIEItNjA5Mjk0NTIxMzAxBgNVBAsTKklQUyBDQSBD
+aGFpbmVkIENBcyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEzMDEGA1UEAxMqSVBT
+IENBIENoYWluZWQgQ0FzIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MR4wHAYJKoZI
+hvcNAQkBFg9pcHNAbWFpbC5pcHMuZXOCAQAwDAYDVR0TBAUwAwEB/zAMBgNVHQ8E
+BQMDB/+AMGsGA1UdJQRkMGIGCCsGAQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMG
+CCsGAQUFBwMEBggrBgEFBQcDCAYKKwYBBAGCNwIBFQYKKwYBBAGCNwIBFgYKKwYB
+BAGCNwoDAQYKKwYBBAGCNwoDBDARBglghkgBhvhCAQEEBAMCAAcwGgYDVR0RBBMw
+EYEPaXBzQG1haWwuaXBzLmVzMBoGA1UdEgQTMBGBD2lwc0BtYWlsLmlwcy5lczBC
+BglghkgBhvhCAQ0ENRYzQ2hhaW5lZCBDQSBDZXJ0aWZpY2F0ZSBpc3N1ZWQgYnkg
+aHR0cDovL3d3dy5pcHMuZXMvMCkGCWCGSAGG+EIBAgQcFhpodHRwOi8vd3d3Lmlw
+cy5lcy9pcHMyMDAyLzA3BglghkgBhvhCAQQEKhYoaHR0cDovL3d3dy5pcHMuZXMv
+aXBzMjAwMi9pcHMyMDAyQ0FDLmNybDA8BglghkgBhvhCAQMELxYtaHR0cDovL3d3
+dy5pcHMuZXMvaXBzMjAwMi9yZXZvY2F0aW9uQ0FDLmh0bWw/MDkGCWCGSAGG+EIB
+BwQsFipodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL3JlbmV3YWxDQUMuaHRtbD8w
+NwYJYIZIAYb4QgEIBCoWKGh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvcG9saWN5
+Q0FDLmh0bWwwbQYDVR0fBGYwZDAuoCygKoYoaHR0cDovL3d3dy5pcHMuZXMvaXBz
+MjAwMi9pcHMyMDAyQ0FDLmNybDAyoDCgLoYsaHR0cDovL3d3d2JhY2suaXBzLmVz
+L2lwczIwMDIvaXBzMjAwMkNBQy5jcmwwLwYIKwYBBQUHAQEEIzAhMB8GCCsGAQUF
+BzABhhNodHRwOi8vb2NzcC5pcHMuZXMvMA0GCSqGSIb3DQEBBQUAA4GBAERyMJ1W
+WKJBGyi3leGmGpVfp3hAK+/blkr8THFj2XOVvQLiogbHvpcqk4A0hgP63Ng9HgfN
+HnNDJGD1HWHc3JagvPsd4+cSACczAsDAK1M92GsDgaPb1pOVIO/Tln4mkImcJpvN
+b2ar7QMiRDjMWb2f2/YHogF/JsRj9SVCXmK9
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICtzCCAiACAQAwDQYJKoZIhvcNAQEEBQAwgaMxCzAJBgNVBAYTAkVTMRIwEAYD
+VQQIEwlCQVJDRUxPTkExEjAQBgNVBAcTCUJBUkNFTE9OQTEZMBcGA1UEChMQSVBT
+IFNlZ3VyaWRhZCBDQTEYMBYGA1UECxMPQ2VydGlmaWNhY2lvbmVzMRcwFQYDVQQD
+Ew5JUFMgU0VSVklET1JFUzEeMBwGCSqGSIb3DQEJARYPaXBzQG1haWwuaXBzLmVz
+MB4XDTk4MDEwMTIzMjEwN1oXDTA5MTIyOTIzMjEwN1owgaMxCzAJBgNVBAYTAkVT
+MRIwEAYDVQQIEwlCQVJDRUxPTkExEjAQBgNVBAcTCUJBUkNFTE9OQTEZMBcGA1UE
+ChMQSVBTIFNlZ3VyaWRhZCBDQTEYMBYGA1UECxMPQ2VydGlmaWNhY2lvbmVzMRcw
+FQYDVQQDEw5JUFMgU0VSVklET1JFUzEeMBwGCSqGSIb3DQEJARYPaXBzQG1haWwu
+aXBzLmVzMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCsT1J0nznqjtwlxLyY
+XZhkJAk8IbPMGbWOlI6H0fg3PqHILVikgDVboXVsHUUMH2Fjal5vmwpMwci4YSM1
+gf/+rHhwLWjhOgeYlQJU3c0jt4BT18g3RXIGJBK6E2Ehim51KODFDzT9NthFf+G4
+Nu+z4cYgjui0OLzhPvYR3oydAQIDAQABMA0GCSqGSIb3DQEBBAUAA4GBACzzw3lY
+JN7GO9HgQmm47mSzPWIBubOE3yN93ZjPEKn+ANgilgUTB1RXxafey9m4iEL2mdsU
+dx+2/iU94aI+A6mB0i1sR/WWRowiq8jMDQ6XXotBtDvECgZAHd1G9AHduoIuPD14
+cJ58GNCr+Lh3B0Zx8coLY1xq+XKU1QFPoNtC
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIIODCCB6GgAwIBAgIBADANBgkqhkiG9w0BAQUFADCCAR4xCzAJBgNVBAYTAkVT
+MRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UE
+ChMlSVBTIEludGVybmV0IHB1Ymxpc2hpbmcgU2VydmljZXMgcy5sLjErMCkGA1UE
+ChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAgQi02MDkyOTQ1MjE0MDIGA1UECxMr
+SVBTIENBIFRpbWVzdGFtcGluZyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTE0MDIG
+A1UEAxMrSVBTIENBIFRpbWVzdGFtcGluZyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
+eTEeMBwGCSqGSIb3DQEJARYPaXBzQG1haWwuaXBzLmVzMB4XDTAxMTIyOTAxMTAx
+OFoXDTI1MTIyNzAxMTAxOFowggEeMQswCQYDVQQGEwJFUzESMBAGA1UECBMJQmFy
+Y2Vsb25hMRIwEAYDVQQHEwlCYXJjZWxvbmExLjAsBgNVBAoTJUlQUyBJbnRlcm5l
+dCBwdWJsaXNoaW5nIFNlcnZpY2VzIHMubC4xKzApBgNVBAoUImlwc0BtYWlsLmlw
+cy5lcyBDLkkuRi4gIEItNjA5Mjk0NTIxNDAyBgNVBAsTK0lQUyBDQSBUaW1lc3Rh
+bXBpbmcgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxNDAyBgNVBAMTK0lQUyBDQSBU
+aW1lc3RhbXBpbmcgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxHjAcBgkqhkiG9w0B
+CQEWD2lwc0BtYWlsLmlwcy5lczCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
+vLjuVqWajOY2ycJioGaBjRrVetJznw6EZLqVtJCneK/K/lRhW86yIFcBrkSSQxA4
+Efdo/BdApWgnMjvEp+ZCccWZ73b/K5Uk9UmSGGjKALWkWi9uy9YbLA1UZ2t6KaFY
+q6JaANZbuxjC3/YeE1Z2m6Vo4pjOxgOKNNtMg0GmqaMCAwEAAaOCBIAwggR8MB0G
+A1UdDgQWBBSL0BBQCYHynQnVDmB4AyKiP8jKZjCCAVAGA1UdIwSCAUcwggFDgBSL
+0BBQCYHynQnVDmB4AyKiP8jKZqGCASakggEiMIIBHjELMAkGA1UEBhMCRVMxEjAQ
+BgNVBAgTCUJhcmNlbG9uYTESMBAGA1UEBxMJQmFyY2Vsb25hMS4wLAYDVQQKEyVJ
+UFMgSW50ZXJuZXQgcHVibGlzaGluZyBTZXJ2aWNlcyBzLmwuMSswKQYDVQQKFCJp
+cHNAbWFpbC5pcHMuZXMgQy5JLkYuICBCLTYwOTI5NDUyMTQwMgYDVQQLEytJUFMg
+Q0EgVGltZXN0YW1waW5nIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MTQwMgYDVQQD
+EytJUFMgQ0EgVGltZXN0YW1waW5nIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MR4w
+HAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXOCAQAwDAYDVR0TBAUwAwEB/zAM
+BgNVHQ8EBQMDB/+AMGsGA1UdJQRkMGIGCCsGAQUFBwMBBggrBgEFBQcDAgYIKwYB
+BQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYKKwYBBAGCNwIBFQYKKwYBBAGCNwIB
+FgYKKwYBBAGCNwoDAQYKKwYBBAGCNwoDBDARBglghkgBhvhCAQEEBAMCAAcwGgYD
+VR0RBBMwEYEPaXBzQG1haWwuaXBzLmVzMBoGA1UdEgQTMBGBD2lwc0BtYWlsLmlw
+cy5lczBHBglghkgBhvhCAQ0EOhY4VGltZXN0YW1waW5nIENBIENlcnRpZmljYXRl
+IGlzc3VlZCBieSBodHRwOi8vd3d3Lmlwcy5lcy8wKQYJYIZIAYb4QgECBBwWGmh0
+dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvMEAGCWCGSAGG+EIBBAQzFjFodHRwOi8v
+d3d3Lmlwcy5lcy9pcHMyMDAyL2lwczIwMDJUaW1lc3RhbXBpbmcuY3JsMEUGCWCG
+SAGG+EIBAwQ4FjZodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL3Jldm9jYXRpb25U
+aW1lc3RhbXBpbmcuaHRtbD8wQgYJYIZIAYb4QgEHBDUWM2h0dHA6Ly93d3cuaXBz
+LmVzL2lwczIwMDIvcmVuZXdhbFRpbWVzdGFtcGluZy5odG1sPzBABglghkgBhvhC
+AQgEMxYxaHR0cDovL3d3dy5pcHMuZXMvaXBzMjAwMi9wb2xpY3lUaW1lc3RhbXBp
+bmcuaHRtbDB/BgNVHR8EeDB2MDegNaAzhjFodHRwOi8vd3d3Lmlwcy5lcy9pcHMy
+MDAyL2lwczIwMDJUaW1lc3RhbXBpbmcuY3JsMDugOaA3hjVodHRwOi8vd3d3YmFj
+ay5pcHMuZXMvaXBzMjAwMi9pcHMyMDAyVGltZXN0YW1waW5nLmNybDAvBggrBgEF
+BQcBAQQjMCEwHwYIKwYBBQUHMAGGE2h0dHA6Ly9vY3NwLmlwcy5lcy8wDQYJKoZI
+hvcNAQEFBQADgYEAZbrBzAAalZHK6Ww6vzoeFAh8+4Pua2JR0zORtWB5fgTYXXk3
+6MNbsMRnLWhasl8OCvrNPzpFoeo2zyYepxEoxZSPhExTCMWTs/zif/WN87GphV+I
+3pGW7hdbrqXqcGV4LCFkAZXOzkw+UPS2Wctjjba9GNSHSl/c7+lW8AoM6HU=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFSzCCBLSgAwIBAgIBaTANBgkqhkiG9w0BAQQFADCBmTELMAkGA1UEBhMCSFUx
+ETAPBgNVBAcTCEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0
+b25zYWdpIEtmdC4xGjAYBgNVBAsTEVRhbnVzaXR2YW55a2lhZG9rMTIwMAYDVQQD
+EylOZXRMb2NrIFV6bGV0aSAoQ2xhc3MgQikgVGFudXNpdHZhbnlraWFkbzAeFw05
+OTAyMjUxNDEwMjJaFw0xOTAyMjAxNDEwMjJaMIGZMQswCQYDVQQGEwJIVTERMA8G
+A1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRvbnNh
+Z2kgS2Z0LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxMjAwBgNVBAMTKU5l
+dExvY2sgVXpsZXRpIChDbGFzcyBCKSBUYW51c2l0dmFueWtpYWRvMIGfMA0GCSqG
+SIb3DQEBAQUAA4GNADCBiQKBgQCx6gTsIKAjwo84YM/HRrPVG/77uZmeBNwcf4xK
+gZjupNTKihe5In+DCnVMm8Bp2GQ5o+2So/1bXHQawEfKOml2mrriRBf8TKPV/riX
+iK+IA4kfpPIEPsgHC+b5sy96YhQJRhTKZPWLgLViqNhr1nGTLbO/CVRY7QbrqHvc
+Q7GhaQIDAQABo4ICnzCCApswEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNVHQ8BAf8E
+BAMCAAYwEQYJYIZIAYb4QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaCAk1G
+SUdZRUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFu
+b3MgU3pvbGdhbHRhdGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBh
+bGFwamFuIGtlc3p1bHQuIEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExv
+Y2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2VnLWJpenRvc2l0YXNhIHZlZGkuIEEgZGln
+aXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUgYXogZWxvaXJ0
+IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFzIGxlaXJh
+c2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGph
+biBhIGh0dHBzOi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJo
+ZXRvIGF6IGVsbGVub3J6ZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBP
+UlRBTlQhIFRoZSBpc3N1YW5jZSBhbmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmlj
+YXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sgQ1BTIGF2YWlsYWJsZSBhdCBo
+dHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFpbCBhdCBjcHNA
+bmV0bG9jay5uZXQuMA0GCSqGSIb3DQEBBAUAA4GBAATbrowXr/gOkDFOzT4JwG06
+sPgzTEdM43WIEJessDgVkcYplswhwG08pXTP2IKlOcNl40JwuyKQ433bNXbhoLXa
+n3BukxowOR0w2y7jfLKRstE3Kfq51hdcR0/jHTjrn9V7lagonhVK0dHQKwCXoOKS
+NitjrFgBazMpUIaD8QFI
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFTzCCBLigAwIBAgIBaDANBgkqhkiG9w0BAQQFADCBmzELMAkGA1UEBhMCSFUx
+ETAPBgNVBAcTCEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0
+b25zYWdpIEtmdC4xGjAYBgNVBAsTEVRhbnVzaXR2YW55a2lhZG9rMTQwMgYDVQQD
+EytOZXRMb2NrIEV4cHJlc3N6IChDbGFzcyBDKSBUYW51c2l0dmFueWtpYWRvMB4X
+DTk5MDIyNTE0MDgxMVoXDTE5MDIyMDE0MDgxMVowgZsxCzAJBgNVBAYTAkhVMREw
+DwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6dG9u
+c2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE0MDIGA1UEAxMr
+TmV0TG9jayBFeHByZXNzeiAoQ2xhc3MgQykgVGFudXNpdHZhbnlraWFkbzCBnzAN
+BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA6+ywbGGKIyWvYCDj2Z/8kwvbXY2wobNA
+OoLO/XXgeDIDhlqGlZHtU/qdQPzm6N3ZW3oDvV3zOwzDUXmbrVWg6dADEK8KuhRC
+2VImESLH0iDMgqSaqf64gXadarfSNnU+sYYJ9m5tfk63euyucYT2BDMIJTLrdKwW
+RMbkQJMdf60CAwEAAaOCAp8wggKbMBIGA1UdEwEB/wQIMAYBAf8CAQQwDgYDVR0P
+AQH/BAQDAgAGMBEGCWCGSAGG+EIBAQQEAwIABzCCAmAGCWCGSAGG+EIBDQSCAlEW
+ggJNRklHWUVMRU0hIEV6ZW4gdGFudXNpdHZhbnkgYSBOZXRMb2NrIEtmdC4gQWx0
+YWxhbm9zIFN6b2xnYWx0YXRhc2kgRmVsdGV0ZWxlaWJlbiBsZWlydCBlbGphcmFz
+b2sgYWxhcGphbiBrZXN6dWx0LiBBIGhpdGVsZXNpdGVzIGZvbHlhbWF0YXQgYSBO
+ZXRMb2NrIEtmdC4gdGVybWVrZmVsZWxvc3NlZy1iaXp0b3NpdGFzYSB2ZWRpLiBB
+IGRpZ2l0YWxpcyBhbGFpcmFzIGVsZm9nYWRhc2FuYWsgZmVsdGV0ZWxlIGF6IGVs
+b2lydCBlbGxlbm9yemVzaSBlbGphcmFzIG1lZ3RldGVsZS4gQXogZWxqYXJhcyBs
+ZWlyYXNhIG1lZ3RhbGFsaGF0byBhIE5ldExvY2sgS2Z0LiBJbnRlcm5ldCBob25s
+YXBqYW4gYSBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIGNpbWVuIHZhZ3kg
+a2VyaGV0byBheiBlbGxlbm9yemVzQG5ldGxvY2submV0IGUtbWFpbCBjaW1lbi4g
+SU1QT1JUQU5UISBUaGUgaXNzdWFuY2UgYW5kIHRoZSB1c2Ugb2YgdGhpcyBjZXJ0
+aWZpY2F0ZSBpcyBzdWJqZWN0IHRvIHRoZSBOZXRMb2NrIENQUyBhdmFpbGFibGUg
+YXQgaHR0cHM6Ly93d3cubmV0bG9jay5uZXQvZG9jcyBvciBieSBlLW1haWwgYXQg
+Y3BzQG5ldGxvY2submV0LjANBgkqhkiG9w0BAQQFAAOBgQAQrX/XDDKACtiG8XmY
+ta3UzbM2xJZIwVzNmtkFLp++UOv0JhQQLdRmF/iewSf98e3ke0ugbLWrmldwpu2g
+pO0u9f38vf5NNwgMvOOWgyL1SRt/Syu0VMGAfJlOHdCM7tCs5ZL6dVb+ZKATj7i4
+Fp1hBWeAyNDYpQcCNJgEjTME1A==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIGfTCCBWWgAwIBAgICAQMwDQYJKoZIhvcNAQEEBQAwga8xCzAJBgNVBAYTAkhV
+MRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMe
+TmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0
+dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBLb3pqZWd5em9pIChDbGFzcyBB
+KSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNDIzMTQ0N1oXDTE5MDIxOTIzMTQ0
+N1owga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQHEwhC
+dWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQu
+MRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBL
+b3pqZWd5em9pIChDbGFzcyBBKSBUYW51c2l0dmFueWtpYWRvMIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvHSMD7tM9DceqQWC2ObhbHDqeLVu0ThEDaiD
+zl3S1tWBxdRL51uUcCbbO51qTGL3cfNk1mE7PetzozfZz+qMkjvN9wfcZnSX9EUi
+3fRc4L9t875lM+QVOr/bmJBVOMTtplVjC7B4BPTjbsE/jvxReB+SnoPC/tmwqcm8
+WgD/qaiYdPv2LD4VOQ22BFWoDpggQrOxJa1+mm9dU7GrDPzr4PN6s6iz/0b2Y6LY
+Oph7tqyF/7AlT3Rj5xMHpQqPBffAZG9+pyeAlt7ULoZgx2srXnN7F+eRP2QM2Esi
+NCubMvJIH5+hCoR64sKtlz2O1cH5VqNQ6ca0+pii7pXmKgOM3wIDAQABo4ICnzCC
+ApswDgYDVR0PAQH/BAQDAgAGMBIGA1UdEwEB/wQIMAYBAf8CAQQwEQYJYIZIAYb4
+QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaCAk1GSUdZRUxFTSEgRXplbiB0
+YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pvbGdhbHRhdGFz
+aSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQu
+IEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtm
+ZWxlbG9zc2VnLWJpenRvc2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMg
+ZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUgYXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVs
+amFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFzIGxlaXJhc2EgbWVndGFsYWxoYXRv
+IGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBhIGh0dHBzOi8vd3d3
+Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVub3J6
+ZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1
+YW5jZSBhbmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3Qg
+dG8gdGhlIE5ldExvY2sgQ1BTIGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRs
+b2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFpbCBhdCBjcHNAbmV0bG9jay5uZXQuMA0G
+CSqGSIb3DQEBBAUAA4IBAQBIJEb3ulZv+sgoA0BO5TE5ayZrU3/b39/zcT0mwBQO
+xmd7I6gMc90Bu8bKbjc5VdXHjFYgDigKDtIqpLBJUsY4B/6+CgmM0ZjPytoUMaFP
+0jn8DxEsQ8Pdq5PHVT5HfBgaANzze9jyf1JsIPQLX2lS9O74silg6+NJMSEN1rUQ
+QeJBCWziGppWS3cC9qCbmieH6FUpccKQn0V4GuEVZD3QDtigdp+uxdAu6tYPVuxk
+f1qbFFgBJ34TUMdrKuZoPL9coAob4Q566eKAw+np9v1sEZ7Q5SgnK1QyQhSCdeZK
+8CtmdWOMovsEPoMOmzbwGOQmIMOM8CgHrTwXZoi1/baI
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIG0TCCBbmgAwIBAgIBezANBgkqhkiG9w0BAQUFADCByTELMAkGA1UEBhMCSFUx
+ETAPBgNVBAcTCEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0
+b25zYWdpIEtmdC4xGjAYBgNVBAsTEVRhbnVzaXR2YW55a2lhZG9rMUIwQAYDVQQD
+EzlOZXRMb2NrIE1pbm9zaXRldHQgS296amVneXpvaSAoQ2xhc3MgUUEpIFRhbnVz
+aXR2YW55a2lhZG8xHjAcBgkqhkiG9w0BCQEWD2luZm9AbmV0bG9jay5odTAeFw0w
+MzAzMzAwMTQ3MTFaFw0yMjEyMTUwMTQ3MTFaMIHJMQswCQYDVQQGEwJIVTERMA8G
+A1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRvbnNh
+Z2kgS2Z0LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxQjBABgNVBAMTOU5l
+dExvY2sgTWlub3NpdGV0dCBLb3pqZWd5em9pIChDbGFzcyBRQSkgVGFudXNpdHZh
+bnlraWFkbzEeMBwGCSqGSIb3DQEJARYPaW5mb0BuZXRsb2NrLmh1MIIBIjANBgkq
+hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx1Ilstg91IRVCacbvWy5FPSKAtt2/Goq
+eKvld/Bu4IwjZ9ulZJm53QE+b+8tmjwi8F3JV6BVQX/yQ15YglMxZc4e8ia6AFQe
+r7C8HORSjKAyr7c3sVNnaHRnUPYtLmTeriZ539+Zhqurf4XsoPuAzPS4DB6TRWO5
+3Lhbm+1bOdRfYrCnjnxmOCyqsQhjF2d9zL2z8cM/z1A57dEZgxXbhxInlrfa6uWd
+vLrqOU+L73Sa58XQ0uqGURzk/mQIKAR5BevKxXEOC++r6uwSEaEYBTJp0QwsGj0l
+mT+1fMptsK6ZmfoIYOcZwvK9UdPM0wKswREMgM6r3JSda6M5UzrWhQIDAMV9o4IC
+wDCCArwwEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNVHQ8BAf8EBAMCAQYwggJ1Bglg
+hkgBhvhCAQ0EggJmFoICYkZJR1lFTEVNISBFemVuIHRhbnVzaXR2YW55IGEgTmV0
+TG9jayBLZnQuIE1pbm9zaXRldHQgU3pvbGdhbHRhdGFzaSBTemFiYWx5emF0YWJh
+biBsZWlydCBlbGphcmFzb2sgYWxhcGphbiBrZXN6dWx0LiBBIG1pbm9zaXRldHQg
+ZWxla3Ryb25pa3VzIGFsYWlyYXMgam9naGF0YXMgZXJ2ZW55ZXN1bGVzZW5laywg
+dmFsYW1pbnQgZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUgYSBNaW5vc2l0ZXR0IFN6
+b2xnYWx0YXRhc2kgU3phYmFseXphdGJhbiwgYXogQWx0YWxhbm9zIFN6ZXJ6b2Rl
+c2kgRmVsdGV0ZWxla2JlbiBlbG9pcnQgZWxsZW5vcnplc2kgZWxqYXJhcyBtZWd0
+ZXRlbGUuIEEgZG9rdW1lbnR1bW9rIG1lZ3RhbGFsaGF0b2sgYSBodHRwczovL3d3
+dy5uZXRsb2NrLmh1L2RvY3MvIGNpbWVuIHZhZ3kga2VyaGV0b2sgYXogaW5mb0Bu
+ZXRsb2NrLm5ldCBlLW1haWwgY2ltZW4uIFdBUk5JTkchIFRoZSBpc3N1YW5jZSBh
+bmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGFyZSBzdWJqZWN0IHRvIHRo
+ZSBOZXRMb2NrIFF1YWxpZmllZCBDUFMgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3
+Lm5ldGxvY2suaHUvZG9jcy8gb3IgYnkgZS1tYWlsIGF0IGluZm9AbmV0bG9jay5u
+ZXQwHQYDVR0OBBYEFAlqYhaSsFq7VQ7LdTI6MuWyIckoMA0GCSqGSIb3DQEBBQUA
+A4IBAQCRalCc23iBmz+LQuM7/KbD7kPgz/PigDVJRXYC4uMvBcXxKufAQTPGtpvQ
+MznNwNuhrWw3AkxYQTvyl5LGSKjN5Yo5iWH5Upfpvfb5lHTocQ68d4bDBsxafEp+
+NFAwLvt/MpqNPfMgW/hqyobzMUwsWYACff44yTB1HLdV47yfuqhthCgFdbOLDcCR
+VCHnpgu0mfVRQdzNo0ci2ccBgcTcR08m6h/t280NmPSjnLRzMkqWmf68f8glWPhY
+83ZmiVSkpj7EUFy6iRiCdUgh0k8T6GB+B3bbELVR5qq5aKrN9p2QdRLqOBrKROi3
+macqaJVmlaut74nLYKkGEsaUR+ko
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBi
+MQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu
+MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3Jp
+dHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMxMjM1OTU5WjBiMQswCQYDVQQGEwJV
+UzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydO
+ZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwz
+c7MEL7xxjOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPP
+OCwGJgl6cvf6UDL4wpPTaaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rl
+mGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXTcrA/vGp97Eh/jcOrqnErU2lBUzS1sLnF
+BgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc/Qzpf14Dl847ABSHJ3A4
+qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMBAAGjgZcw
+gZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIB
+BjAPBgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwu
+bmV0c29sc3NsLmNvbS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3Jp
+dHkuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc8
+6fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q4LqILPxFzBiwmZVRDuwduIj/
+h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/GGUsyfJj4akH
+/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv
+wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHN
+pGxlaKFJdlxDydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJC
+TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0
+aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0
+aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAzMTkxODMzMzNaFw0yMTAzMTcxODMz
+MzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUw
+IwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVR
+dW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Yp
+li4kVEAkOPcahdxYTMukJ0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2D
+rOpm2RgbaIr1VxqYuvXtdj182d6UajtLF8HVj71lODqV0D1VNk7feVcxKh7YWWVJ
+WCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeLYzcS19Dsw3sgQUSj7cug
+F+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWenAScOospU
+xbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCC
+Ak4wPQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVv
+dmFkaXNvZmZzaG9yZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREw
+ggENMIIBCQYJKwYBBAG+WAABMIH7MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNl
+IG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBh
+c3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFy
+ZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh
+Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYI
+KwYBBQUHAgEWFmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3T
+KbkGGew5Oanwl4Rqy+/fMIGuBgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rq
+y+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1p
+dGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYD
+VQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6tlCL
+MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSk
+fnIYj9lofFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf8
+7C9TqnN7Az10buYWnuulLsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1R
+cHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2xgI4JVrmcGmD+XcHXetwReNDWXcG31a0y
+mQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi5upZIof4l/UO/erMkqQW
+xFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi5nrQNiOK
+SnQ2+Q==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x
+GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv
+b3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV
+BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W
+YWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCa
+GMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6XJxg
+Fyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55J
+WpzmM+Yklvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bB
+rrcCaoF6qUWD4gXmuVbBlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp
++ARz8un+XJiM9XOva7R+zdRcAitMOeGylZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1
+ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt66/3FsvbzSUr5R/7mp/i
+Ucw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1JdxnwQ5hYIiz
+PtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og
+/zOhD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UH
+oycR7hYQe7xFSkyyBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuI
+yV77zGHcizN300QyNQliBJIWENieJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1Ud
+EwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBQahGK8SEwzJQTU7tD2
+A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGUa6FJpEcwRTEL
+MAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT
+ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2f
+BluornFdLwUvZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzn
+g/iN/Ae42l9NLmeyhP3ZRPx3UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2Bl
+fF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodmVjB3pjd4M1IQWK4/YY7yarHvGH5K
+WWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK+JDSV6IZUaUtl0Ha
+B0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrWIozc
+hLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPR
+TUIZ3Ph1WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWD
+mbA4CD/pXvk1B+TJYm5Xf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0Z
+ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y
+4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza
+8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x
+GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv
+b3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV
+BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W
+YWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM
+V0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNggDhoB
+4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUr
+H556VOijKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd
+8lyyBTNvijbO0BNO/79KDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9Cabwv
+vWhDFlaJKjdhkf2mrk7AyxRllDdLkgbvBNDInIjbC3uBr7E9KsRlOni27tyAsdLT
+mZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwpp5ijJUMv7/FfJuGITfhe
+btfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8nT8KKdjc
+T5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDt
+WAEXMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZ
+c6tsgLjoC2SToJyMGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A
+4iLItLRkT9a6fUg+qGkM17uGcclzuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYD
+VR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHTBgkrBgEEAb5YAAMwgcUwgZMG
+CCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0
+aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0
+aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu
+dC4wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2Nw
+czALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4G
+A1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4ywLQoUmkRzBFMQswCQYDVQQGEwJC
+TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UEAxMSUXVvVmFkaXMg
+Um9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZVqyM0
+7ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSem
+d1o417+shvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd
++LJ2w/w4E6oM3kJpK27zPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B
+4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadN
+t54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp8kokUvd0/bpO5qgdAm6x
+DYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBCbjPsMZ57
+k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6s
+zHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j
+Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT
+mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK
+4SVhM7JZG+Ju1zdXtg2pEto=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0
+IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz
+BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDMgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y
+aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG
+9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMjIzM1oXDTE5MDYy
+NjAwMjIzM1owgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y
+azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
+YXNzIDMgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw
+Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl
+cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDjmFGWHOjVsQaBalfD
+cnWTq8+epvzzFlLWLU2fNUSoLgRNB0mKOCn1dzfnt6td3zZxFJmP3MKS8edgkpfs
+2Ejcv8ECIMYkpChMMFp2bbFc893enhBxoYjHW5tBbcqwuI4V7q0zK89HBFx1cQqY
+JJgpp0lZpd34t0NiYfPT4tBVPwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFa7AliE
+Zwgs3x/be0kz9dNnnfS0ChCzycUs4pJqcXgn8nCDQtM+z6lU9PHYkhaM0QTLS6vJ
+n0WuPIqpsHEzXcjFV9+vqDWzf4mH6eglkrh/hXqu1rweN1gqZ8mRzyqBPu3GOd/A
+PhmcGcwTTYJBtYze4D1gCCAPRX5ron+jjBXu
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICXDCCAcWgAwIBAgIQCgEBAQAAAnwAAAALAAAAAjANBgkqhkiG9w0BAQUFADA6
+MRkwFwYDVQQKExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0EgU2VjdXJp
+dHkgMTAyNCBWMzAeFw0wMTAyMjIyMTAxNDlaFw0yNjAyMjIyMDAxNDlaMDoxGTAX
+BgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAbBgNVBAsTFFJTQSBTZWN1cml0eSAx
+MDI0IFYzMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDV3f5mCc8kPD6ugU5O
+isRpgFtZO9+5TUzKtS3DJy08rwBCbbwoppbPf9dYrIMKo1W1exeQFYRMiu4mmdxY
+78c4pqqv0I5CyGLXq6yp+0p9v+r+Ek3d/yYtbzZUaMjShFbuklNhCbM/OZuoyZu9
+zp9+1BlqFikYvtc6adwlWzMaUQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4G
+A1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBTEwBykB5T9zU0B1FTapQxf3q4FWjAd
+BgNVHQ4EFgQUxMAcpAeU/c1NAdRU2qUMX96uBVowDQYJKoZIhvcNAQEFBQADgYEA
+Py1q4yZDlX2Jl2X7deRyHUZXxGFraZ8SmyzVWujAovBDleMf6XbN3Ou8k6BlCsdN
+T1+nr6JGFLkM88y9am63nd4lQtBU/55oc2PcJOsiv6hy8l4A4Q1OOkNumU4/iXgD
+mMrzVcydro7BqkWY+o8aoI2II/EVQQ2lRj6RP4vr93E=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDYTCCAkmgAwIBAgIQCgEBAQAAAnwAAAAKAAAAAjANBgkqhkiG9w0BAQUFADA6
+MRkwFwYDVQQKExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0EgU2VjdXJp
+dHkgMjA0OCBWMzAeFw0wMTAyMjIyMDM5MjNaFw0yNjAyMjIyMDM5MjNaMDoxGTAX
+BgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAbBgNVBAsTFFJTQSBTZWN1cml0eSAy
+MDQ4IFYzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt49VcdKA3Xtp
+eafwGFAyPGJn9gqVB93mG/Oe2dJBVGutn3y+Gc37RqtBaB4Y6lXIL5F4iSj7Jylg
+/9+PjDvJSZu1pJTOAeo+tWN7fyb9Gd3AIb2E0S1PRsNO3Ng3OTsor8udGuorryGl
+wSMiuLgbWhOHV4PR8CDn6E8jQrAApX2J6elhc5SYcSa8LWrg903w8bYqODGBDSnh
+AMFRD0xS+ARaqn1y07iHKrtjEAMqs6FPDVpeRrc9DvV07Jmf+T0kgYim3WBU6JU2
+PcYJk5qjEoAAVZkZR73QpXzDuvsf9/UP+Ky5tfQ3mBMY3oVbtwyCO4dvlTlYMNpu
+AWgXIszACwIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
+BjAfBgNVHSMEGDAWgBQHw1EwpKrpRa41JPr/JCwz0LGdjDAdBgNVHQ4EFgQUB8NR
+MKSq6UWuNST6/yQsM9CxnYwwDQYJKoZIhvcNAQEFBQADggEBAF8+hnZuuDU8TjYc
+HnmYv/3VEhF5Ug7uMYm83X/50cYVIeiKAVQNOvtUudZj1LGqlk2iQk3UUx+LEN5/
+Zb5gEydxiKRz44Rj0aRV4VCT5hsOedBnvEbIvz8XDZXmxpBp3ue0L96VfdASPz0+
+f00/FGj1EVDVwfSQpQgdMWD/YIwjVAqv/qFuxdF6Kmh4zx6CCiC0H63lhbJqaHVO
+rSU3lIW+vaHU6rcMSzyd6BIA8F+sDeGscGNz9395nzIlQnQFgCi/vcEkllgVsRch
+6YlL2weIZ/QVrXA+L02FO8K32/6YaCOJ4XQP3vTFhGMpG8zLB8kApKnXwiJPZ9d3
+7CAFYd4=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI
+MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x
+FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz
+MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv
+cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN
+AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz
+Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO
+0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao
+wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj
+7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS
+8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT
+BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB
+/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg
+JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC
+NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3
+6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/
+3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm
+D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS
+CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR
+3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK
+MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x
+GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx
+MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg
+Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ
+iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa
+/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ
+jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI
+HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7
+sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w
+gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF
+MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw
+KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG
+AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L
+URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO
+H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm
+I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY
+iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc
+f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEY
+MBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21t
+dW5pY2F0aW9uIFJvb3RDQTEwHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5
+WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYD
+VQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEwggEiMA0GCSqGSIb3
+DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw8yl8
+9f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJ
+DKaVv0uMDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9
+Ms+k2Y7CI9eNqPPYJayX5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/N
+QV3Is00qVUarH9oe4kA92819uZKAnDfdDJZkndwi92SL32HeFZRSFaB9UslLqCHJ
+xrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2JChzAgMBAAGjPzA9MB0G
+A1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYwDwYDVR0T
+AQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vG
+kl3g0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfr
+Uj94nK9NrvjVT8+amCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5
+Bw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJU
+JRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot
+RSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDIDCCAgigAwIBAgIBJDANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP
+MA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MxIENBMB4XDTAx
+MDQwNjEwNDkxM1oXDTIxMDQwNjEwNDkxM1owOTELMAkGA1UEBhMCRkkxDzANBgNV
+BAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMSBDQTCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBALWJHytPZwp5/8Ue+H887dF+2rDNbS82rDTG
+29lkFwhjMDMiikzujrsPDUJVyZ0upe/3p4zDq7mXy47vPxVnqIJyY1MPQYx9EJUk
+oVqlBvqSV536pQHydekfvFYmUk54GWVYVQNYwBSujHxVX3BbdyMGNpfzJLWaRpXk
+3w0LBUXl0fIdgrvGE+D+qnr9aTCU89JFhfzyMlsy3uhsXR/LpCJ0sICOXZT3BgBL
+qdReLjVQCfOAl/QMF6452F/NM8EcyonCIvdFEu1eEpOdY6uCLrnrQkFEy0oaAIIN
+nvmLVz5MxxftLItyM19yejhW1ebZrgUaHXVFsculJRwSVzb9IjcCAwEAAaMzMDEw
+DwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQIR+IMi/ZTiFIwCwYDVR0PBAQDAgEG
+MA0GCSqGSIb3DQEBBQUAA4IBAQCLGrLJXWG04bkruVPRsoWdd44W7hE928Jj2VuX
+ZfsSZ9gqXLar5V7DtxYvyOirHYr9qxp81V9jz9yw3Xe5qObSIjiHBxTZ/75Wtf0H
+DjxVyhbMp6Z3N/vbXB9OWQaHowND9Rart4S9Tu+fMTfwRvFAttEMpWT4Y14h21VO
+TzF2nBBhjrZTOqMRvq9tfB69ri3iDGnHhVNoomG6xT60eVR4ngrHAr5i0RGCS2Uv
+kVrCqIexVmiUefkl98HVrhq4uz2PqYo4Ffdz0Fpg0YCw8NzVUM1O7pJIae2yIx4w
+zMiUyLb1O4Z/P6Yun/Y+LLWSlj7fLJOK/4GMDw9ZIRlXvVWa
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP
+MA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAx
+MDQwNjA3Mjk0MFoXDTIxMDQwNjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNV
+BAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMiBDQTCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3/Ei9vX+ALTU74W+o
+Z6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybTdXnt
+5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s
+3TmVToMGf+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2Ej
+vOr7nQKV0ba5cTppCD8PtOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu
+8nYybieDwnPz3BjotJPqdURrBGAgcVeHnfO+oJAjPYok4doh28MCAwEAAaMzMDEw
+DwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITTXjwwCwYDVR0PBAQDAgEG
+MA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt0jSv9zil
+zqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/
+3DEIcbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvD
+FNr450kkkdAdavphOe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6
+Tk6ezAyNlNzZRZxe7EJQY670XcSxEtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2
+ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLHllpwrN9M
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDujCCAqKgAwIBAgIEAJiWijANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJO
+TDEeMBwGA1UEChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSYwJAYDVQQDEx1TdGFh
+dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQTAeFw0wMjEyMTcwOTIzNDlaFw0xNTEy
+MTYwOTE1MzhaMFUxCzAJBgNVBAYTAk5MMR4wHAYDVQQKExVTdGFhdCBkZXIgTmVk
+ZXJsYW5kZW4xJjAkBgNVBAMTHVN0YWF0IGRlciBOZWRlcmxhbmRlbiBSb290IENB
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmNK1URF6gaYUmHFtvszn
+ExvWJw56s2oYHLZhWtVhCb/ekBPHZ+7d89rFDBKeNVU+LCeIQGv33N0iYfXCxw71
+9tV2U02PjLwYdjeFnejKScfST5gTCaI+Ioicf9byEGW07l8Y1Rfj+MX94p2i71MO
+hXeiD+EwR+4A5zN9RGcaC1Hoi6CeUJhoNFIfLm0B8mBF8jHrqTFoKbt6QZ7GGX+U
+tFE5A3+y3qcym7RHjm+0Sq7lr7HcsBthvJly3uSJt3omXdozSVtSnA71iq3DuD3o
+BmrC1SoLbHuEvVYFy4ZlkuxEK7COudxwC0barbxjiDn622r+I/q85Ej0ZytqERAh
+SQIDAQABo4GRMIGOMAwGA1UdEwQFMAMBAf8wTwYDVR0gBEgwRjBEBgRVHSAAMDww
+OgYIKwYBBQUHAgEWLmh0dHA6Ly93d3cucGtpb3ZlcmhlaWQubmwvcG9saWNpZXMv
+cm9vdC1wb2xpY3kwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSofeu8Y6R0E3QA
+7Jbg0zTBLL9s+DANBgkqhkiG9w0BAQUFAAOCAQEABYSHVXQ2YcG70dTGFagTtJ+k
+/rvuFbQvBgwp8qiSpGEN/KtcCFtREytNwiphyPgJWPwtArI5fZlmgb9uXJVFIGzm
+eafR2Bwp/MIgJ1HI8XxdNGdphREwxgDS1/PTfLbwMVcoEoJz6TMvplW0C5GUR5z6
+u3pCMuiufi3IvKwUv9kP2Vv8wfl6leF9fpb8cbDCTMjfRTTJzg3ynGQI0DvDKcWy
+7ZAEwbEpkcUwb8GpcjPM/l0WFywRaed+/sWDCN+83CI6LiBpIzlWYGeQiy52OfsR
+iJf2fL1LuCAWZwWN4jvBcj+UlTfHXbme2JOhF4//DGYVwSR8MnwDHTuhWEUykw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl
+MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp
+U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw
+NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE
+ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp
+ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3
+DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf
+8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN
++lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0
+X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa
+K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA
+1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G
+A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR
+zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0
+YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD
+bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w
+DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3
+L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D
+eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl
+xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp
+VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY
+WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW
+MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg
+Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh
+dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM2WhcNMzYwOTE3MTk0NjM2WjB9
+MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi
+U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh
+cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA
+A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk
+pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf
+OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C
+Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT
+Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi
+HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM
+Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w
++2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+
+Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3
+Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B
+26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID
+AQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE
+FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9j
+ZXJ0LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3Js
+LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFM
+BgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUHAgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0
+Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRwOi8vY2VydC5zdGFy
+dGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYgU3Rh
+cnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlh
+YmlsaXR5LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2Yg
+dGhlIFN0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFp
+bGFibGUgYXQgaHR0cDovL2NlcnQuc3RhcnRjb20ub3JnL3BvbGljeS5wZGYwEQYJ
+YIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNT
+TCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOCAgEAFmyZ
+9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8
+jhvh3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUW
+FjgKXlf2Ysd6AgXmvB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJz
+ewT4F+irsfMuXGRuczE6Eri8sxHkfY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1
+ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3fsNrarnDy0RLrHiQi+fHLB5L
+EUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZEoalHmdkrQYu
+L6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq
+yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuC
+O3NJo2pXh5Tl1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6V
+um0ABj6y6koQOdjQK/W/7HW/lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkySh
+NOsF/5oirpt9P/FlUQqmMGqz9IgcgA38corog14=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFFjCCBH+gAwIBAgIBADANBgkqhkiG9w0BAQQFADCBsDELMAkGA1UEBhMCSUwx
+DzANBgNVBAgTBklzcmFlbDEOMAwGA1UEBxMFRWlsYXQxFjAUBgNVBAoTDVN0YXJ0
+Q29tIEx0ZC4xGjAYBgNVBAsTEUNBIEF1dGhvcml0eSBEZXAuMSkwJwYDVQQDEyBG
+cmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJARYS
+YWRtaW5Ac3RhcnRjb20ub3JnMB4XDTA1MDMxNzE3Mzc0OFoXDTM1MDMxMDE3Mzc0
+OFowgbAxCzAJBgNVBAYTAklMMQ8wDQYDVQQIEwZJc3JhZWwxDjAMBgNVBAcTBUVp
+bGF0MRYwFAYDVQQKEw1TdGFydENvbSBMdGQuMRowGAYDVQQLExFDQSBBdXRob3Jp
+dHkgRGVwLjEpMCcGA1UEAxMgRnJlZSBTU0wgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
+dHkxITAfBgkqhkiG9w0BCQEWEmFkbWluQHN0YXJ0Y29tLm9yZzCBnzANBgkqhkiG
+9w0BAQEFAAOBjQAwgYkCgYEA7YRgACOeyEpRKSfeOqE5tWmrCbIvNP1h3D3TsM+x
+18LEwrHkllbEvqoUDufMOlDIOmKdw6OsWXuO7lUaHEe+o5c5s7XvIywI6Nivcy+5
+yYPo7QAPyHWlLzRMGOh2iCNJitu27Wjaw7ViKUylS7eYtAkUEKD4/mJ2IhULpNYI
+LzUCAwEAAaOCAjwwggI4MA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgHmMB0G
+A1UdDgQWBBQcicOWzL3+MtUNjIExtpidjShkjTCB3QYDVR0jBIHVMIHSgBQcicOW
+zL3+MtUNjIExtpidjShkjaGBtqSBszCBsDELMAkGA1UEBhMCSUwxDzANBgNVBAgT
+BklzcmFlbDEOMAwGA1UEBxMFRWlsYXQxFjAUBgNVBAoTDVN0YXJ0Q29tIEx0ZC4x
+GjAYBgNVBAsTEUNBIEF1dGhvcml0eSBEZXAuMSkwJwYDVQQDEyBGcmVlIFNTTCBD
+ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJARYSYWRtaW5Ac3Rh
+cnRjb20ub3JnggEAMB0GA1UdEQQWMBSBEmFkbWluQHN0YXJ0Y29tLm9yZzAdBgNV
+HRIEFjAUgRJhZG1pbkBzdGFydGNvbS5vcmcwEQYJYIZIAYb4QgEBBAQDAgAHMC8G
+CWCGSAGG+EIBDQQiFiBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAy
+BglghkgBhvhCAQQEJRYjaHR0cDovL2NlcnQuc3RhcnRjb20ub3JnL2NhLWNybC5j
+cmwwKAYJYIZIAYb4QgECBBsWGWh0dHA6Ly9jZXJ0LnN0YXJ0Y29tLm9yZy8wOQYJ
+YIZIAYb4QgEIBCwWKmh0dHA6Ly9jZXJ0LnN0YXJ0Y29tLm9yZy9pbmRleC5waHA/
+YXBwPTExMTANBgkqhkiG9w0BAQQFAAOBgQBscSXhnjSRIe/bbL0BCFaPiNhBOlP1
+ct8nV0t2hPdopP7rPwl+KLhX6h/BquL/lp9JmeaylXOWxkjHXo0Hclb4g4+fd68p
+00UOpO6wNnQt8M2YI3s3S9r+UZjEHjQ8iP2ZO1CnwYszx8JSFhKVU2Ui77qLzmLb
+cCOxgN8aIDjnfg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
+BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2ln
+biBHb2xkIENBIC0gRzIwHhcNMDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBF
+MQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMR8wHQYDVQQDExZT
+d2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
+CgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUqt2/8
+76LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+
+bbqBHH5CjCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c
+6bM8K8vzARO/Ws/BtQpgvd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqE
+emA8atufK+ze3gE/bk3lUIbLtK/tREDFylqM2tIrfKjuvqblCqoOpd8FUrdVxyJd
+MmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvRAiTysybUa9oEVeXBCsdt
+MDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuendjIj3o02y
+MszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69y
+FGkOpeUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPi
+aG59je883WX0XaxR7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxM
+gI93e2CaHt+28kgeDrpOVG2Y4OGiGqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCB
+qTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUWyV7
+lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64OfPAeGZe6Drn
+8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov
+L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe6
+45R88a7A3hfm5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczO
+UYrHUDFu4Up+GC9pWbY9ZIEr44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5
+O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOfMke6UiI0HTJ6CVanfCU2qT1L2sCC
+bwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6mGu6uLftIdxf+u+yv
+GPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxpmo/a
+77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCC
+hdiDyyJkvC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid3
+92qgQmwLOM7XdVAyksLfKzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEpp
+Ld6leNcG2mqeSz53OiATIgHQv2ieY2BrNU0LbbqhPcCT4H8js1WtciVORvnSFu+w
+ZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6LqjviOvrv1vA+ACOzB2+htt
+Qc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFwTCCA6mgAwIBAgIITrIAZwwDXU8wDQYJKoZIhvcNAQEFBQAwSTELMAkGA1UE
+BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEjMCEGA1UEAxMaU3dpc3NTaWdu
+IFBsYXRpbnVtIENBIC0gRzIwHhcNMDYxMDI1MDgzNjAwWhcNMzYxMDI1MDgzNjAw
+WjBJMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMSMwIQYDVQQD
+ExpTd2lzc1NpZ24gUGxhdGludW0gQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQAD
+ggIPADCCAgoCggIBAMrfogLi2vj8Bxax3mCq3pZcZB/HL37PZ/pEQtZ2Y5Wu669y
+IIpFR4ZieIbWIDkm9K6j/SPnpZy1IiEZtzeTIsBQnIJ71NUERFzLtMKfkr4k2Htn
+IuJpX+UFeNSH2XFwMyVTtIc7KZAoNppVRDBopIOXfw0enHb/FZ1glwCNioUD7IC+
+6ixuEFGSzH7VozPY1kneWCqv9hbrS3uQMpe5up1Y8fhXSQQeol0GcN1x2/ndi5ob
+jM89o03Oy3z2u5yg+gnOI2Ky6Q0f4nIoj5+saCB9bzuohTEJfwvH6GXp43gOCWcw
+izSC+13gzJ2BbWLuCB4ELE6b7P6pT1/9aXjvCR+htL/68++QHkwFix7qepF6w9fl
++zC8bBsQWJj3Gl/QKTIDE0ZNYWqFTFJ0LwYfexHihJfGmfNtf9dng34TaNhxKFrY
+zt3oEBSa/m0jh26OWnA81Y0JAKeqvLAxN23IhBQeW71FYyBrS3SMvds6DsHPWhaP
+pZjydomyExI7C3d3rLvlPClKknLKYRorXkzig3R3+jVIeoVNjZpTxN94ypeRSCtF
+KwH3HBqi7Ri6Cr2D+m+8jVeTO9TUps4e8aCxzqv9KyiaTxvXw3LbpMS/XUz13XuW
+ae5ogObnmLo2t/5u7Su9IPhlGdpVCX4l3P5hYnL5fhgC72O00Puv5TtjjGePAgMB
+AAGjgawwgakwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O
+BBYEFFCvzAeHFUdvOMW0ZdHelarp35zMMB8GA1UdIwQYMBaAFFCvzAeHFUdvOMW0
+ZdHelarp35zMMEYGA1UdIAQ/MD0wOwYJYIV0AVkBAQEBMC4wLAYIKwYBBQUHAgEW
+IGh0dHA6Ly9yZXBvc2l0b3J5LnN3aXNzc2lnbi5jb20vMA0GCSqGSIb3DQEBBQUA
+A4ICAQAIhab1Fgz8RBrBY+D5VUYI/HAcQiiWjrfFwUF1TglxeeVtlspLpYhg0DB0
+uMoI3LQwnkAHFmtllXcBrqS3NQuB2nEVqXQXOHtYyvkv+8Bldo1bAbl93oI9ZLi+
+FHSjClTTLJUYFzX1UWs/j6KWYTl4a0vlpqD4U99REJNi54Av4tHgvI42Rncz7Lj7
+jposiU0xEQ8mngS7twSNC/K5/FqdOxa3L8iYq/6KUFkuozv8KV2LwUvJ4ooTHbG/
+u0IdUt1O2BReEMYxB+9xJ/cbOQncguqLs5WGXv312l0xpuAxtpTmREl0xRbl9x8D
+YSjFyMsSoEJL+WuICI20MhjzdZ/EfwBPBZWcoxcCw7NTm6ogOSkrZvqdr16zktK1
+puEa+S1BaYEUtLS17Yk9zvupnTVCRLEcFHOBzyoBNZox1S2PbYTfgE1X4z/FhHXa
+icYwu+uPyyIIoK6q8QNsOktNCaUOcsZWayFCTiMlFGiudgp8DAdwZPmaL/YFOSbG
+DI8Zf0NebvRbFS/bYV3mZy8/CJT5YLSYMdp08YSTcU1f+2BY0fvEwW2JorsgH51x
+kcsymxM9Pn2SUjWskpSi0xjCfMfqr3YFFt1nJ8J+HAciIfNAChs0B0QTwoRqjt8Z
+Wr9/6x3iGjjRXK9HkmuAtTClyY3YqzGBH9/CZjfTk6mFhnll0g==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UE
+BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWdu
+IFNpbHZlciBDQSAtIEcyMB4XDTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0Nlow
+RzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMY
+U3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
+MIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644N0Mv
+Fz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7br
+YT7QbNHm+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieF
+nbAVlDLaYQ1HTWBCrpJH6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH
+6ATK72oxh9TAtvmUcXtnZLi2kUpCe2UuMGoM9ZDulebyzYLs2aFK7PayS+VFheZt
+eJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5hqAaEuSh6XzjZG6k4sIN/
+c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5FZGkECwJ
+MoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRH
+HTBsROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTf
+jNFusB3hB48IHpmccelM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb6
+5i/4z3GcRm25xBWNOHkDRUjvxF3XCO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOB
+rDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
+F6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRBtjpbO8tFnb0c
+wpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0
+cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIB
+AHPGgeAn0i0P4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShp
+WJHckRE1qTodvBqlYJ7YH39FkWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9
+xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L3XWgwF15kIwb4FDm3jH+mHtwX6WQ
+2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx/uNncqCxv1yL5PqZ
+IseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFaDGi8
+aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2X
+em1ZqSqPe97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQR
+dAtq/gsD/KNVV4n+SsuuWxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/
+OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJDIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+
+hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ubDgEj8Z+7fNzcbBGXJbLy
+tGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF2TCCA8GgAwIBAgIQXAuFXAvnWUHfV8w/f52oNjANBgkqhkiG9w0BAQUFADBk
+MQswCQYDVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0
+YWwgQ2VydGlmaWNhdGUgU2VydmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3Qg
+Q0EgMTAeFw0wNTA4MTgxMjA2MjBaFw0yNTA4MTgyMjA2MjBaMGQxCzAJBgNVBAYT
+AmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZp
+Y2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAxMIICIjAN
+BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0LmwqAzZuz8h+BvVM5OAFmUgdbI9
+m2BtRsiMMW8Xw/qabFbtPMWRV8PNq5ZJkCoZSx6jbVfd8StiKHVFXqrWW/oLJdih
+FvkcxC7mlSpnzNApbjyFNDhhSbEAn9Y6cV9Nbc5fuankiX9qUvrKm/LcqfmdmUc/
+TilftKaNXXsLmREDA/7n29uj/x2lzZAeAR81sH8A25Bvxn570e56eqeqDFdvpG3F
+EzuwpdntMhy0XmeLVNxzh+XTF3xmUHJd1BpYwdnP2IkCb6dJtDZd0KTeByy2dbco
+kdaXvij1mB7qWybJvbCXc9qukSbraMH5ORXWZ0sKbU/Lz7DkQnGMU3nn7uHbHaBu
+HYwadzVcFh4rUx80i9Fs/PJnB3r1re3WmquhsUvhzDdf/X/NTa64H5xD+SpYVUNF
+vJbNcA78yeNmuk6NO4HLFWR7uZToXTNShXEuT46iBhFRyePLoW4xCGQMwtI89Tbo
+19AOeCMgkckkKmUpWyL3Ic6DXqTz3kvTaI9GdVyDCW4pa8RwjPWd1yAv/0bSKzjC
+L3UcPX7ape8eYIVpQtPM+GP+HkM5haa2Y0EQs3MevNP6yn0WR+Kn1dCjigoIlmJW
+bjTb2QK5MHXjBNLnj8KwEUAKrNVxAmKLMb7dxiNYMUJDLXT5xp6mig/p/r+D5kNX
+JLrvRjSq1xIBOO0CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0hBBYw
+FDASBgdghXQBUwABBgdghXQBUwABMBIGA1UdEwEB/wQIMAYBAf8CAQcwHwYDVR0j
+BBgwFoAUAyUv3m+CATpcLNwroWm1Z9SM0/0wHQYDVR0OBBYEFAMlL95vggE6XCzc
+K6FptWfUjNP9MA0GCSqGSIb3DQEBBQUAA4ICAQA1EMvspgQNDQ/NwNurqPKIlwzf
+ky9NfEBWMXrrpA9gzXrzvsMnjgM+pN0S734edAY8PzHyHHuRMSG08NBsl9Tpl7Ik
+Vh5WwzW9iAUPWxAaZOHHgjD5Mq2eUCzneAXQMbFamIp1TpBcahQq4FJHgmDmHtqB
+sfsUC1rxn9KVuj7QG9YVHaO+htXbD8BJZLsuUBlL0iT43R4HVtA4oJVwIHaM190e
+3p9xxCPvgxNcoyQVTSlAPGrEqdi3pkSlDfTgnXceQHAm/NrZNuR55LU/vJtlvrsR
+ls/bxig5OgjOR1tTWsWZ/l2p3e9M1MalrQLmjAcSHm8D0W+go/MpvRLHUKKwf4ip
+mXeascClOS5cfGniLLDqN2qk4Vrh9VDlg++luyqI54zb/W1elxmofmZ1a3Hqv7HH
+b6D0jqTsNFFbjCYDcKF31QESVwA12yPeDooomf2xEG9L/zgtYE4snOtnta1J7ksf
+rK/7DZBaZmBwXarNeNQk7shBoJMBkpxqnvy5JMWzFYJ+vq6VK+uxwNrjAWALXmms
+hFZhvnEX/h0TD/7Gh0Xp/jKgGg0TpJRVcaUWi7rKibCyx/yP2FS1k2Kdzs9Z+z0Y
+zirLNRWCXf9UIltxUvu3yf5gmwBBZPCqKuy2QkPOiWaByIufOVQDJdMWNY6E0F/6
+MBr1mmz0DlP5OlvRHA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDXDCCAsWgAwIBAgICA+owDQYJKoZIhvcNAQEEBQAwgbwxCzAJBgNVBAYTAkRF
+MRAwDgYDVQQIEwdIYW1idXJnMRAwDgYDVQQHEwdIYW1idXJnMTowOAYDVQQKEzFU
+QyBUcnVzdENlbnRlciBmb3IgU2VjdXJpdHkgaW4gRGF0YSBOZXR3b3JrcyBHbWJI
+MSIwIAYDVQQLExlUQyBUcnVzdENlbnRlciBDbGFzcyAyIENBMSkwJwYJKoZIhvcN
+AQkBFhpjZXJ0aWZpY2F0ZUB0cnVzdGNlbnRlci5kZTAeFw05ODAzMDkxMTU5NTla
+Fw0xMTAxMDExMTU5NTlaMIG8MQswCQYDVQQGEwJERTEQMA4GA1UECBMHSGFtYnVy
+ZzEQMA4GA1UEBxMHSGFtYnVyZzE6MDgGA1UEChMxVEMgVHJ1c3RDZW50ZXIgZm9y
+IFNlY3VyaXR5IGluIERhdGEgTmV0d29ya3MgR21iSDEiMCAGA1UECxMZVEMgVHJ1
+c3RDZW50ZXIgQ2xhc3MgMiBDQTEpMCcGCSqGSIb3DQEJARYaY2VydGlmaWNhdGVA
+dHJ1c3RjZW50ZXIuZGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANo46O0y
+AClxgwENv4wB3NrGrTmkqYov1YtcaF9QxmL1Zr3KkSLsqh1R1z2zUbKDTl3LSbDw
+TFXlay3HhQswHJJOgtTKAu33b77c4OMUuAVT8pr0VotanoWT0bSCVq5Nu6hLVxa8
+/vhYnvgpjbB7zXjJT6yLZwzxnPv8V5tXXE8NAgMBAAGjazBpMA8GA1UdEwEB/wQF
+MAMBAf8wDgYDVR0PAQH/BAQDAgGGMDMGCWCGSAGG+EIBCAQmFiRodHRwOi8vd3d3
+LnRydXN0Y2VudGVyLmRlL2d1aWRlbGluZXMwEQYJYIZIAYb4QgEBBAQDAgAHMA0G
+CSqGSIb3DQEBBAUAA4GBAIRS+yjf/x91AbwBvgRWl2p0QiQxg/lGsQaKic+WLDO/
+jLVfenKhhQbOhvgFjuj5Jcrag4wGrOs2bYWRNAQ29ELw+HkuCkhcq8xRT3h2oNms
+Gb0q0WkEKJHKNhAngFdb0lz1wlurZIFjdFH0l7/NEij3TWZ/p/AcASZ4smZHcFFk
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDXDCCAsWgAwIBAgICA+swDQYJKoZIhvcNAQEEBQAwgbwxCzAJBgNVBAYTAkRF
+MRAwDgYDVQQIEwdIYW1idXJnMRAwDgYDVQQHEwdIYW1idXJnMTowOAYDVQQKEzFU
+QyBUcnVzdENlbnRlciBmb3IgU2VjdXJpdHkgaW4gRGF0YSBOZXR3b3JrcyBHbWJI
+MSIwIAYDVQQLExlUQyBUcnVzdENlbnRlciBDbGFzcyAzIENBMSkwJwYJKoZIhvcN
+AQkBFhpjZXJ0aWZpY2F0ZUB0cnVzdGNlbnRlci5kZTAeFw05ODAzMDkxMTU5NTla
+Fw0xMTAxMDExMTU5NTlaMIG8MQswCQYDVQQGEwJERTEQMA4GA1UECBMHSGFtYnVy
+ZzEQMA4GA1UEBxMHSGFtYnVyZzE6MDgGA1UEChMxVEMgVHJ1c3RDZW50ZXIgZm9y
+IFNlY3VyaXR5IGluIERhdGEgTmV0d29ya3MgR21iSDEiMCAGA1UECxMZVEMgVHJ1
+c3RDZW50ZXIgQ2xhc3MgMyBDQTEpMCcGCSqGSIb3DQEJARYaY2VydGlmaWNhdGVA
+dHJ1c3RjZW50ZXIuZGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALa0wTUF
+Lg2N7KBAahwOJ6ZQkmtQGwfeLud2zODa/ISoXoxjaitN2U4CdhHBC/KNecoAtvGw
+Dtf7pBc9r6tpepYnv68zoZoqWarEtTcI8hKlMbZD9TKWcSgoq40oht+77uMMfTDW
+w1Krj10nnGvAo+cFa1dJRLNu6mTP0o56UHd3AgMBAAGjazBpMA8GA1UdEwEB/wQF
+MAMBAf8wDgYDVR0PAQH/BAQDAgGGMDMGCWCGSAGG+EIBCAQmFiRodHRwOi8vd3d3
+LnRydXN0Y2VudGVyLmRlL2d1aWRlbGluZXMwEQYJYIZIAYb4QgEBBAQDAgAHMA0G
+CSqGSIb3DQEBBAUAA4GBABY9xs3Bu4VxhUafPiCPUSiZ7C1FIWMjWwS7TJC4iJIE
+Tb19AaM/9uzO8d7+feXhPrvGq14L3T2WxMup1Pkm5gZOngylerpuw3yCGdHHsbHD
+2w2Om0B8NwvxXej9H5CIpQ5ON2QhqE6NtJ/x3kit1VYYUimLRzQSCdS7kjXvD9s0
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEKzCCAxOgAwIBAgIEOsylTDANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJE
+SzEVMBMGA1UEChMMVERDIEludGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQg
+Um9vdCBDQTAeFw0wMTA0MDUxNjMzMTdaFw0yMTA0MDUxNzAzMTdaMEMxCzAJBgNV
+BAYTAkRLMRUwEwYDVQQKEwxUREMgSW50ZXJuZXQxHTAbBgNVBAsTFFREQyBJbnRl
+cm5ldCBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxLhA
+vJHVYx/XmaCLDEAedLdInUaMArLgJF/wGROnN4NrXceO+YQwzho7+vvOi20jxsNu
+Zp+Jpd/gQlBn+h9sHvTQBda/ytZO5GhgbEaqHF1j4QeGDmUApy6mcca8uYGoOn0a
+0vnRrEvLznWv3Hv6gXPU/Lq9QYjUdLP5Xjg6PEOo0pVOd20TDJ2PeAG3WiAfAzc1
+4izbSysseLlJ28TQx5yc5IogCSEWVmb/Bexb4/DPqyQkXsN/cHoSxNK1EKC2IeGN
+eGlVRGn1ypYcNIUXJXfi9i8nmHj9eQY6otZaQ8H/7AQ77hPv01ha/5Lr7K7a8jcD
+R0G2l8ktCkEiu7vmpwIDAQABo4IBJTCCASEwEQYJYIZIAYb4QgEBBAQDAgAHMGUG
+A1UdHwReMFwwWqBYoFakVDBSMQswCQYDVQQGEwJESzEVMBMGA1UEChMMVERDIElu
+dGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQgUm9vdCBDQTENMAsGA1UEAxME
+Q1JMMTArBgNVHRAEJDAigA8yMDAxMDQwNTE2MzMxN1qBDzIwMjEwNDA1MTcwMzE3
+WjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUbGQBx/2FbazI2p5QCIUItTxWqFAw
+HQYDVR0OBBYEFGxkAcf9hW2syNqeUAiFCLU8VqhQMAwGA1UdEwQFMAMBAf8wHQYJ
+KoZIhvZ9B0EABBAwDhsIVjUuMDo0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4IBAQBO
+Q8zR3R0QGwZ/t6T609lN+yOfI1Rb5osvBCiLtSdtiaHsmGnc540mgwV5dOy0uaOX
+wTUA/RXaOYE6lTGQ3pfphqiZdwzlWqCE/xIWrG64jcN7ksKsLtB9KOy282A4aW8+
+2ARVPp7MVdK6/rtHBNcK2RYKNCn1WBPVT8+PVkuzHu7TmHnaCB4Mb7j4Fifvwm89
+9qNLPg7kbWzbO0ESm70NRyN/PErQr8Cv9u8btRXE64PECV90i9kR+8JWsTz4cMo0
+jUNAE4z9mQNUecYu6oah9jrUCbz0vGbMPVjQV0kK7iXiQe4T+Zs4NNEA9X7nlB38
+aQNiuJkFBT1reBK9sG9l
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFGTCCBAGgAwIBAgIEPki9xDANBgkqhkiG9w0BAQUFADAxMQswCQYDVQQGEwJE
+SzEMMAoGA1UEChMDVERDMRQwEgYDVQQDEwtUREMgT0NFUyBDQTAeFw0wMzAyMTEw
+ODM5MzBaFw0zNzAyMTEwOTA5MzBaMDExCzAJBgNVBAYTAkRLMQwwCgYDVQQKEwNU
+REMxFDASBgNVBAMTC1REQyBPQ0VTIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
+MIIBCgKCAQEArGL2YSCyz8DGhdfjeebM7fI5kqSXLmSjhFuHnEz9pPPEXyG9VhDr
+2y5h7JNp46PMvZnDBfwGuMo2HP6QjklMxFaaL1a8z3sM8W9Hpg1DTeLpHTk0zY0s
+2RKY+ePhwUp8hjjEqcRhiNJerxomTdXkoCJHhNlktxmW/OwZ5LKXJk5KTMuPJItU
+GBxIYXvViGjaXbXqzRowwYCDdlCqT9HU3Tjw7xb04QxQBr/q+3pJoSgrHPb8FTKj
+dGqPqcNiKXEx5TukYBdedObaE+3pHx8b0bJoc8YQNHVGEBDjkAB2QMuLt0MJIf+r
+TpPGWOmlgtt3xDqZsXKVSQTwtyv6e1mO3QIDAQABo4ICNzCCAjMwDwYDVR0TAQH/
+BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwgewGA1UdIASB5DCB4TCB3gYIKoFQgSkB
+AQEwgdEwLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuY2VydGlmaWthdC5kay9yZXBv
+c2l0b3J5MIGdBggrBgEFBQcCAjCBkDAKFgNUREMwAwIBARqBgUNlcnRpZmlrYXRl
+ciBmcmEgZGVubmUgQ0EgdWRzdGVkZXMgdW5kZXIgT0lEIDEuMi4yMDguMTY5LjEu
+MS4xLiBDZXJ0aWZpY2F0ZXMgZnJvbSB0aGlzIENBIGFyZSBpc3N1ZWQgdW5kZXIg
+T0lEIDEuMi4yMDguMTY5LjEuMS4xLjARBglghkgBhvhCAQEEBAMCAAcwgYEGA1Ud
+HwR6MHgwSKBGoESkQjBAMQswCQYDVQQGEwJESzEMMAoGA1UEChMDVERDMRQwEgYD
+VQQDEwtUREMgT0NFUyBDQTENMAsGA1UEAxMEQ1JMMTAsoCqgKIYmaHR0cDovL2Ny
+bC5vY2VzLmNlcnRpZmlrYXQuZGsvb2Nlcy5jcmwwKwYDVR0QBCQwIoAPMjAwMzAy
+MTEwODM5MzBagQ8yMDM3MDIxMTA5MDkzMFowHwYDVR0jBBgwFoAUYLWF7FZkfhIZ
+J2cdUBVLc647+RIwHQYDVR0OBBYEFGC1hexWZH4SGSdnHVAVS3OuO/kSMB0GCSqG
+SIb2fQdBAAQQMA4bCFY2LjA6NC4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEACrom
+JkbTc6gJ82sLMJn9iuFXehHTuJTXCRBuo7E4A9G28kNBKWKnctj7fAXmMXAnVBhO
+inxO5dHKjHiIzxvTkIvmI/gLDjNDfZziChmPyQE+dF10yYscA+UYyAFMP8uXBV2Y
+caaYb7Z8vTd/vuGTJW1v8AqtFxjhA7wHKcitJuj4YfD9IQl+mo6paH1IYnK9AOoB
+mbgGglGBTvH1tJFUuSN6AJqfXY3gPGS5GhKSKseCRHI53OI8xthV9RVOyAUO28bQ
+YqbsFbS1AoLbrIyigfCbmTH1ICCoiGEKB5+U/NDXG8wuF/MEJ3Zn61SD/aSQfgY9
+BKNDLdr8C2LqL19iUw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIID+zCCAuOgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBtzE/MD0GA1UEAww2VMOc
+UktUUlVTVCBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx
+c8SxMQswCQYDVQQGDAJUUjEPMA0GA1UEBwwGQU5LQVJBMVYwVAYDVQQKDE0oYykg
+MjAwNSBUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8
+dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjAeFw0wNTA1MTMxMDI3MTdaFw0xNTAz
+MjIxMDI3MTdaMIG3MT8wPQYDVQQDDDZUw5xSS1RSVVNUIEVsZWt0cm9uaWsgU2Vy
+dGlmaWthIEhpem1ldCBTYcSfbGF5xLFjxLFzxLExCzAJBgNVBAYMAlRSMQ8wDQYD
+VQQHDAZBTktBUkExVjBUBgNVBAoMTShjKSAyMDA1IFTDnFJLVFJVU1QgQmlsZ2kg
+xLBsZXRpxZ9pbSB2ZSBCaWxpxZ9pbSBHw7x2ZW5sacSfaSBIaXptZXRsZXJpIEEu
+xZ4uMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAylIF1mMD2Bxf3dJ7
+XfIMYGFbazt0K3gNfUW9InTojAPBxhEqPZW8qZSwu5GXyGl8hMW0kWxsE2qkVa2k
+heiVfrMArwDCBRj1cJ02i67L5BuBf5OI+2pVu32Fks66WJ/bMsW9Xe8iSi9BB35J
+YbOG7E6mQW6EvAPs9TscyB/C7qju6hJKjRTP8wrgUDn5CDX4EVmt5yLqS8oUBt5C
+urKZ8y1UiBAG6uEaPj1nH/vO+3yC6BFdSsG5FOpU2WabfIl9BJpiyelSPJ6c79L1
+JuTm5Rh8i27fbMx4W09ysstcP4wFjdFMjK2Sx+F4f2VsSQZQLJ4ywtdKxnWKWU51
+b0dewQIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAV
+9VX/N5aAWSGk/KEVTCD21F/aAyT8z5Aa9CEKmu46sWrv7/hg0Uw2ZkUd82YCdAR7
+kjCo3gp2D++Vbr3JN+YaDayJSFvMgzbC9UZcWYJWtNX+I7TYVBxEq8Sn5RTOPEFh
+fEPmzcSBCYsk+1Ql1haolgxnB2+zUEfjHCQo3SqYpGH+2+oSN7wBGjSFvW5P55Fy
+B0SFHljKVETd96y5y4khctuPwGkplyqjrhgjlxxBKot8KsF8kOipKMDTkcatKIdA
+aLX/7KfS0zgYnNN9aV3wxqUeJBujR/xpB2jn5Jq07Q+hh4cCzofSSE7hvP/L8XKS
+RGQDJereW26fyfJOrN3H
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEPDCCAySgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvjE/MD0GA1UEAww2VMOc
+UktUUlVTVCBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx
+c8SxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xS
+S1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kg
+SGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwHhcNMDUxMTA3MTAwNzU3
+WhcNMTUwOTE2MTAwNzU3WjCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBFbGVrdHJv
+bmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJU
+UjEPMA0GA1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSw
+bGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWe
+LiAoYykgS2FzxLFtIDIwMDUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
+AQCpNn7DkUNMwxmYCMjHWHtPFoylzkkBH3MOrHUTpvqeLCDe2JAOCtFp0if7qnef
+J1Il4std2NiDUBd9irWCPwSOtNXwSadktx4uXyCcUHVPr+G1QRT0mJKIx+XlZEdh
+R3n9wFHxwZnn3M5q+6+1ATDcRhzviuyV79z/rxAc653YsKpqhRgNF8k+v/Gb0AmJ
+Qv2gQrSdiVFVKc8bcLyEVK3BEx+Y9C52YItdP5qtygy/p1Zbj3e41Z55SZI/4PGX
+JHpsmxcPbe9TmJEr5A++WXkHeLuXlfSfadRYhwqp48y2WBmfJiGxxFmNskF1wK1p
+zpwACPI2/z7woQ8arBT9pmAPAgMBAAGjQzBBMB0GA1UdDgQWBBTZN7NOBf3Zz58S
+Fq62iS/rJTqIHDAPBgNVHQ8BAf8EBQMDBwYAMA8GA1UdEwEB/wQFMAMBAf8wDQYJ
+KoZIhvcNAQEFBQADggEBAHJglrfJ3NgpXiOFX7KzLXb7iNcX/nttRbj2hWyfIvwq
+ECLsqrkw9qtY1jkQMZkpAL2JZkH7dN6RwRgLn7Vhy506vvWolKMiVW4XSf/SKfE4
+Jl3vpao6+XF75tpYHdN0wgH6PmlYX63LaL4ULptswLbcoCb6dxriJNoaN+BnrdFz
+gw2lGh1uEpJ+hGIAF728JRhX8tepb1mIvDS3LoV4nZbcFMMsilKbloxSZj2GFotH
+uFEJjOp9zYhys2AzsfAKRO8P9Qk3iCQOLGsgOqL6EfJANZxEaGM7rDNvY7wsu/LS
+y3Z9fYjYHcgFHW68lKlmjHdxx/qR+i9Rnuk5UrbnBEI=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/
+MQswCQYDVQQGEwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmlj
+YXRpb24gQXV0aG9yaXR5MB4XDTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1ow
+PzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dvdmVybm1lbnQgUm9vdCBDZXJ0aWZp
+Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
+AJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qNw8XR
+IePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1q
+gQdW8or5BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKy
+yhwOeYHWtXBiCAEuTk8O1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAts
+F/tnyMKtsc2AtJfcdgEWFelq16TheEfOhtX7MfP6Mb40qij7cEwdScevLJ1tZqa2
+jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wovJ5pGfaENda1UhhXcSTvx
+ls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7Q3hub/FC
+VGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHK
+YS1tB6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoH
+EgKXTiCQ8P8NHuJBO9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThN
+Xo+EHWbNxWCWtFJaBYmOlXqYwZE8lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1Ud
+DgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNVHRMEBTADAQH/MDkGBGcqBwAE
+MTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg209yewDL7MTqK
+UWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ
+TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyf
+qzvS/3WXy6TjZwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaK
+ZEk9GhiHkASfQlK3T8v+R0F2Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFE
+JPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlUD7gsL0u8qV1bYH+Mh6XgUmMqvtg7
+hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6QzDxARvBMB1uUO07+1
+EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+HbkZ6Mm
+nD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WX
+udpVBrkk7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44Vbnz
+ssQwmSNOXfJIoRIM3BKQCZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDe
+LMDDav7v3Aun+kbfYNucpllQdSNpc5Oy+fwC00fmcc4QAu4njIT/rEUNE1yDMuAl
+pYYsfPQS
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDITCCAoqgAwIBAgIBADANBgkqhkiG9w0BAQQFADCByzELMAkGA1UEBhMCWkEx
+FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMRowGAYD
+VQQKExFUaGF3dGUgQ29uc3VsdGluZzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBT
+ZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3RlIFBlcnNvbmFsIEJhc2lj
+IENBMSgwJgYJKoZIhvcNAQkBFhlwZXJzb25hbC1iYXNpY0B0aGF3dGUuY29tMB4X
+DTk2MDEwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgcsxCzAJBgNVBAYTAlpBMRUw
+EwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEaMBgGA1UE
+ChMRVGhhd3RlIENvbnN1bHRpbmcxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2Vy
+dmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQZXJzb25hbCBCYXNpYyBD
+QTEoMCYGCSqGSIb3DQEJARYZcGVyc29uYWwtYmFzaWNAdGhhd3RlLmNvbTCBnzAN
+BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAvLyTU23AUE+CFeZIlDWmWr5vQvoPR+53
+dXLdjUmbllegeNTKP1GzaQuRdhciB5dqxFGTS+CN7zeVoQxN2jSQHReJl+A1OFdK
+wPQIcOk8RHtQfmGakOMj04gRRif1CwcOu93RfyAKiLlWCy4cgNrx454p7xS9CkT7
+G1sY0b8jkyECAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQQF
+AAOBgQAt4plrsD16iddZopQBHyvdEktTwq1/qqcAXJFAVyVKOKqEcLnZgA+le1z7
+c8a914phXAPjLSeoF+CEhULcXpvGt7Jtu3Sv5D/Lp7ew4F2+eIMllNLbgQ95B21P
+9DkVWlIBe94y1k049hJcBlDfBVu9FEuh3ym6O0GN92NWod8isQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDLTCCApagAwIBAgIBADANBgkqhkiG9w0BAQQFADCB0TELMAkGA1UEBhMCWkEx
+FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMRowGAYD
+VQQKExFUaGF3dGUgQ29uc3VsdGluZzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBT
+ZXJ2aWNlcyBEaXZpc2lvbjEkMCIGA1UEAxMbVGhhd3RlIFBlcnNvbmFsIEZyZWVt
+YWlsIENBMSswKQYJKoZIhvcNAQkBFhxwZXJzb25hbC1mcmVlbWFpbEB0aGF3dGUu
+Y29tMB4XDTk2MDEwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgdExCzAJBgNVBAYT
+AlpBMRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEa
+MBgGA1UEChMRVGhhd3RlIENvbnN1bHRpbmcxKDAmBgNVBAsTH0NlcnRpZmljYXRp
+b24gU2VydmljZXMgRGl2aXNpb24xJDAiBgNVBAMTG1RoYXd0ZSBQZXJzb25hbCBG
+cmVlbWFpbCBDQTErMCkGCSqGSIb3DQEJARYccGVyc29uYWwtZnJlZW1haWxAdGhh
+d3RlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1GnX1LCUZFtx6UfY
+DFG26nKRsIRefS0Nj3sS34UldSh0OkIsYyeflXtL734Zhx2G6qPduc6WZBrCFG5E
+rHzmj+hND3EfQDimAKOHePb5lIZererAXnbr2RSjXW56fAylS1V/Bhkpf56aJtVq
+uzgkCGqYx7Hao5iR/Xnb5VrEHLkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zAN
+BgkqhkiG9w0BAQQFAAOBgQDH7JJ+Tvj1lqVnYiqk8E0RYNBvjWBYYawmu1I1XAjP
+MPuoSpaKH2JCI4wXD/S6ZJwXrEcp352YXtJsYHFcoqzceePnbgBHH7UNKOgCneSa
+/RP0ptl8sfjcXyMmCZGAc9AUG95DqYMl8uacLxXK/qarigd1iwzdUYRr5PjRznei
+gQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDKTCCApKgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBzzELMAkGA1UEBhMCWkEx
+FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMRowGAYD
+VQQKExFUaGF3dGUgQ29uc3VsdGluZzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBT
+ZXJ2aWNlcyBEaXZpc2lvbjEjMCEGA1UEAxMaVGhhd3RlIFBlcnNvbmFsIFByZW1p
+dW0gQ0ExKjAoBgkqhkiG9w0BCQEWG3BlcnNvbmFsLXByZW1pdW1AdGhhd3RlLmNv
+bTAeFw05NjAxMDEwMDAwMDBaFw0yMDEyMzEyMzU5NTlaMIHPMQswCQYDVQQGEwJa
+QTEVMBMGA1UECBMMV2VzdGVybiBDYXBlMRIwEAYDVQQHEwlDYXBlIFRvd24xGjAY
+BgNVBAoTEVRoYXd0ZSBDb25zdWx0aW5nMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9u
+IFNlcnZpY2VzIERpdmlzaW9uMSMwIQYDVQQDExpUaGF3dGUgUGVyc29uYWwgUHJl
+bWl1bSBDQTEqMCgGCSqGSIb3DQEJARYbcGVyc29uYWwtcHJlbWl1bUB0aGF3dGUu
+Y29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJZtn4B0TPuYwu8KHvE0Vs
+Bd/eJxZRNkERbGw77f4QfRKe5ZtCmv5gMcNmt3M6SK5O0DI3lIi1DbbZ8/JE2dWI
+Et12TfIa/G8jHnrx2JhFTgcQ7xZC0EN1bUre4qrJMf8fAHB8Zs8QJQi6+u4A6UYD
+ZicRFTuqW/KY3TZCstqIdQIDAQABoxMwETAPBgNVHRMBAf8EBTADAQH/MA0GCSqG
+SIb3DQEBBAUAA4GBAGk2ifc0KjNyL2071CKyuG+axTZmDhs8obF1Wub9NdP4qPIH
+b4Vnjt4rueIXsDqg8A6iAJrf8xQVbrvIhVqYgPn/vnQdPfP+MCXRNzRn+qVxeTBh
+KXLA4CxM+1bkOqhv5TJZUtt1KFBZDPgLGeSs2a+WjS9Q2wfD6h+rM+D1KzGJ
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkEx
+FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD
+VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv
+biBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3RlIFByZW1pdW0gU2Vy
+dmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZlckB0aGF3dGUuY29t
+MB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYTAlpB
+MRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsG
+A1UEChMUVGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRp
+b24gU2VydmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNl
+cnZlciBDQTEoMCYGCSqGSIb3DQEJARYZcHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNv
+bTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2aovXwlue2oFBYo847kkE
+VdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIhUdib0GfQ
+ug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMR
+uHM/qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG
+9w0BAQQFAAOBgQAmSCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUI
+hfzJATj/Tb7yFkJD57taRvvBxhEf8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JM
+pAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7tUCemDaYj+bvLpgcUQg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDEzCCAnygAwIBAgIBATANBgkqhkiG9w0BAQQFADCBxDELMAkGA1UEBhMCWkEx
+FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD
+VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv
+biBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3RlIFNlcnZlciBDQTEm
+MCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5jb20wHhcNOTYwODAx
+MDAwMDAwWhcNMjAxMjMxMjM1OTU5WjCBxDELMAkGA1UEBhMCWkExFTATBgNVBAgT
+DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3
+dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNl
+cyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3
+DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQAD
+gY0AMIGJAoGBANOkUG7I/1Zr5s9dtuoMaHVHoqrC2oQl/Kj0R1HahbUgdJSGHg91
+yekIYfUGbTBuFRkC6VLAYttNmZ7iagxEOM3+vuNkCXDF/rFrKbYvScg71CcEJRCX
+L+eQbcAoQpnXTEPew/UhbVSfXcNY4cDk2VuwuNy0e982OsK1ZiIS1ocNAgMBAAGj
+EzARMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAB/pMaVz7lcxG
+7oWDTSEwjsrZqG9JGubaUeNgcGyEYRGhGshIPllDfU+VPaGLtwtimHp1it2ITk6e
+QNuozDJ0uW8NxuOzRAvZim+aKZuZGCg70eNAKJpaPNW15yAbi8qkq43pUdniTCxZ
+qdq5snUb9kLy78fyGPmJvKP/iiMucEc=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICoTCCAgqgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBizELMAkGA1UEBhMCWkEx
+FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTEUMBIGA1UEBxMLRHVyYmFudmlsbGUxDzAN
+BgNVBAoTBlRoYXd0ZTEdMBsGA1UECxMUVGhhd3RlIENlcnRpZmljYXRpb24xHzAd
+BgNVBAMTFlRoYXd0ZSBUaW1lc3RhbXBpbmcgQ0EwHhcNOTcwMTAxMDAwMDAwWhcN
+MjAxMjMxMjM1OTU5WjCBizELMAkGA1UEBhMCWkExFTATBgNVBAgTDFdlc3Rlcm4g
+Q2FwZTEUMBIGA1UEBxMLRHVyYmFudmlsbGUxDzANBgNVBAoTBlRoYXd0ZTEdMBsG
+A1UECxMUVGhhd3RlIENlcnRpZmljYXRpb24xHzAdBgNVBAMTFlRoYXd0ZSBUaW1l
+c3RhbXBpbmcgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANYrWHhhRYZT
+6jR7UZztsOYuGA7+4F+oJ9O0yeB8WU4WDnNUYMF/9p8u6TqFJBU820cEY8OexJQa
+Wt9MevPZQx08EHp5JduQ/vBR5zDWQQD9nyjfeb6Uu522FOMjhdepQeBMpHmwKxqL
+8vg7ij5FrHGSALSQQZj7X+36ty6K+Ig3AgMBAAGjEzARMA8GA1UdEwEB/wQFMAMB
+Af8wDQYJKoZIhvcNAQEEBQADgYEAZ9viwuaHPUCDhjc1fR/OmsMMZiCouqoEiYbC
+9RAIDb/LogWK0E02PvTX72nGXuSwlG9KuefeW4i2e9vjJ+V2w/A1wcu1J5szedyQ
+pgCed/r8zSeUQhac0xxo7L9c3eWpexAKMnRUEzGLhQOEkbdYATAUOK8oyvyxUBkZ
+CayJSdM=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEZDCCA0ygAwIBAgIQRL4Mi1AAJLQR0zYwS8AzdzANBgkqhkiG9w0BAQUFADCB
+ozELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug
+Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho
+dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xKzApBgNVBAMTIlVUTi1VU0VSRmlyc3Qt
+TmV0d29yayBBcHBsaWNhdGlvbnMwHhcNOTkwNzA5MTg0ODM5WhcNMTkwNzA5MTg1
+NzQ5WjCBozELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0
+IExha2UgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYD
+VQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xKzApBgNVBAMTIlVUTi1VU0VS
+Rmlyc3QtTmV0d29yayBBcHBsaWNhdGlvbnMwggEiMA0GCSqGSIb3DQEBAQUAA4IB
+DwAwggEKAoIBAQCz+5Gh5DZVhawGNFugmliy+LUPBXeDrjKxdpJo7CNKyXY/45y2
+N3kDuatpjQclthln5LAbGHNhSuh+zdMvZOOmfAz6F4CjDUeJT1FxL+78P/m4FoCH
+iZMlIJpDgmkkdihZNaEdwH+DBmQWICzTSaSFtMBhf1EI+GgVkYDLpdXuOzr0hARe
+YFmnjDRy7rh4xdE7EkpvfmUnuaRVxblvQ6TFHSyZwFKkeEwVs0CYCGtDxgGwenv1
+axwiP8vv/6jQOkt2FZ7S0cYu49tXGzKiuG/ohqY/cKvlcJKrRB5AUPuco2LkbG6g
+yN7igEL66S/ozjIEj3yNtxyjNTwV3Z7DrpelAgMBAAGjgZEwgY4wCwYDVR0PBAQD
+AgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFPqGydvguul49Uuo1hXf8NPh
+ahQ8ME8GA1UdHwRIMEYwRKBCoECGPmh0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9V
+VE4tVVNFUkZpcnN0LU5ldHdvcmtBcHBsaWNhdGlvbnMuY3JsMA0GCSqGSIb3DQEB
+BQUAA4IBAQCk8yXM0dSRgyLQzDKrm5ZONJFUICU0YV8qAhXhi6r/fWRRzwr/vH3Y
+IWp4yy9Rb/hCHTO967V7lMPDqaAt39EpHx3+jz+7qEUqf9FuVSTiuwL7MT++6Lzs
+QCv4AdRWOOTKRIK1YSAhZ2X28AvnNPilwpyjXEAfhZOVBt5P1CeptqX8Fs1zMT+4
+ZSfP1FMa8Kxun08FDAOBp4QpxFq9ZFdyrTvPNximmMatBrTcCKME1SmklpoSZ0qM
+YEWd8SOasACcaLWYUNPvji6SZbFIPiG+FTAqDbUMo2s/rn9X9R+WfN9v3YIwLGUb
+QErNaLly7HF27FSOH4UMAWr6pjisH8SE
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEXjCCA0agAwIBAgIQRL4Mi1AAIbQR0ypoBqmtaTANBgkqhkiG9w0BAQUFADCB
+kzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug
+Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho
+dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZBgNVBAMTElVUTiAtIERBVEFDb3Jw
+IFNHQzAeFw05OTA2MjQxODU3MjFaFw0xOTA2MjQxOTA2MzBaMIGTMQswCQYDVQQG
+EwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYD
+VQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cu
+dXNlcnRydXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dDMIIBIjAN
+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3+5YEKIrblXEjr8uRgnn4AgPLit6
+E5Qbvfa2gI5lBZMAHryv4g+OGQ0SR+ysraP6LnD43m77VkIVni5c7yPeIbkFdicZ
+D0/Ww5y0vpQZY/KmEQrrU0icvvIpOxboGqBMpsn0GFlowHDyUwDAXlCCpVZvNvlK
+4ESGoE1O1kduSUrLZ9emxAW5jh70/P/N5zbgnAVssjMiFdC04MwXwLLA9P4yPykq
+lXvY8qdOD1R8oQ2AswkDwf9c3V6aPryuvEeKaq5xyh+xKrhfQgUL7EYw0XILyulW
+bfXv33i+Ybqypa4ETLyorGkVl73v67SMvzX41MPRKA5cOp9wGDMgd8SirwIDAQAB
+o4GrMIGoMAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRT
+MtGzz3/64PGgXYVOktKeRR20TzA9BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3Js
+LnVzZXJ0cnVzdC5jb20vVVROLURBVEFDb3JwU0dDLmNybDAqBgNVHSUEIzAhBggr
+BgEFBQcDAQYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GCSqGSIb3DQEBBQUAA4IB
+AQAnNZcAiosovcYzMB4p/OL31ZjUQLtgyr+rFywJNn9Q+kHcrpY6CiM+iVnJowft
+Gzet/Hy+UUla3joKVAgWRcKZsYfNjGjgaQPpxE6YsjuMFrMOoAyYUJuTqXAJyCyj
+j98C5OBxOvG0I3KgqgHf35g+FFCgMSa9KOlaMCZ1+XtgHI3zzVAmbQQnmt/VDUVH
+KWss5nbZqSl9Mt3JNjy9rjXxEZ4du5A/EkdOjtd+D2JzHVImOBwYSf0wdJrE5SIv
+2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jFVkwPDPafepE39peC4N1xaf92P2BNPM/3
+mfnGV/TJVTl4uix5yaaIK/QI
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEojCCA4qgAwIBAgIQRL4Mi1AAJLQR0zYlJWfJiTANBgkqhkiG9w0BAQUFADCB
+rjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug
+Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho
+dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xNjA0BgNVBAMTLVVUTi1VU0VSRmlyc3Qt
+Q2xpZW50IEF1dGhlbnRpY2F0aW9uIGFuZCBFbWFpbDAeFw05OTA3MDkxNzI4NTBa
+Fw0xOTA3MDkxNzM2NThaMIGuMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAV
+BgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5l
+dHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTE2MDQGA1UE
+AxMtVVROLVVTRVJGaXJzdC1DbGllbnQgQXV0aGVudGljYXRpb24gYW5kIEVtYWls
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsjmFpPJ9q0E7YkY3rs3B
+YHW8OWX5ShpHornMSMxqmNVNNRm5pELlzkniii8efNIxB8dOtINknS4p1aJkxIW9
+hVE1eaROaJB7HHqkkqgX8pgV8pPMyaQylbsMTzC9mKALi+VuG6JG+ni8om+rWV6l
+L8/K2m2qL+usobNqqrcuZzWLeeEeaYji5kbNoKXqvgvOdjp6Dpvq/NonWz1zHyLm
+SGHGTPNpsaguG7bUMSAsvIKKjqQOpdeJQ/wWWq8dcdcRWdq6hw2v+vPhwvCkxWeM
+1tZUOt4KpLoDd7NlyP0e03RiqhjKaJMeoYV+9Udly/hNVyh00jT/MLbu9mIwFIws
+6wIDAQABo4G5MIG2MAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud
+DgQWBBSJgmd9xJ0mcABLtFBIfN49rgRufTBYBgNVHR8EUTBPME2gS6BJhkdodHRw
+Oi8vY3JsLnVzZXJ0cnVzdC5jb20vVVROLVVTRVJGaXJzdC1DbGllbnRBdXRoZW50
+aWNhdGlvbmFuZEVtYWlsLmNybDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUH
+AwQwDQYJKoZIhvcNAQEFBQADggEBALFtYV2mGn98q0rkMPxTbyUkxsrt4jFcKw7u
+7mFVbwQ+zznexRtJlOTrIEy05p5QLnLZjfWqo7NK2lYcYJeA3IKirUq9iiv/Cwm0
+xtcgBEXkzYABurorbs6q15L+5K/r9CYdFip/bDCVNy8zEqx/3cfREYxRmLLQo5HQ
+rfafnoOTHh1CuEava2bwm3/q4wMC5QJRwarVNZ1yQAOJujEdxRBoUp7fooXFXAim
+eOZTT7Hot9MUnpOmw2TjrH5xzbyf6QMbzPvprDHBr3wVdAKZw7JHpsIyYdfHb0gk
+USeh1YdV8nuPmD0Wnu51tvjQjvLzxq4oW6fw8zYX/MMF08oDSlQ=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCB
+lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug
+Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho
+dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt
+SGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgxOTIyWjCBlzELMAkG
+A1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEe
+MBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8v
+d3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdh
+cmUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn
+0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlIwrthdBKWHTxqctU8EGc6Oe0rE81m65UJ
+M6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFdtqdt++BxF2uiiPsA3/4a
+MXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8i4fDidNd
+oI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqI
+DsjfPe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9Ksy
+oUhbAgMBAAGjgbkwgbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYD
+VR0OBBYEFKFyXyYbKJhDlV0HN9WFlp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0
+dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZpcnN0LUhhcmR3YXJlLmNy
+bDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEF
+BQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM
+//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28Gpgoiskli
+CE7/yMgUsogWXecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gE
+CJChicsZUN/KHAG8HQQZexB2lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t
+3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kniCrVWFCVH/A7HFe7fRQ5YiuayZSS
+KqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67nfhmqA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0
+IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz
+BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y
+aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG
+9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNTIyMjM0OFoXDTE5MDYy
+NTIyMjM0OFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y
+azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
+YXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw
+Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl
+cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDYWYJ6ibiWuqYvaG9Y
+LqdUHAZu9OqNSLwxlBfw8068srg1knaw0KWlAdcAAxIiGQj4/xEjm84H9b9pGib+
+TunRf50sQB1ZaG6m+FiwnRqP0z/x3BkGgagO4DrdyFNFCQbmD3DD+kCmDuJWBQ8Y
+TfwggtFzVXSNdnKgHZ0dwN0/cQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFBoPUn0
+LBwGlN+VYH+Wexf+T3GtZMjdd9LvWVXoP+iOBSoh8gfStadS/pyxtuJbdxdA6nLW
+I8sogTLDAHkY7FkXicnGah5xyf23dKUlRWnFSKsZ4UWKJWsZ7uW7EvV/96aNUcPw
+nXS3qT6gpf+2SQMT2iLM7XGCK5nPOrf1LXLI
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0
+IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz
+BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y
+aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG
+9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMTk1NFoXDTE5MDYy
+NjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y
+azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
+YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw
+Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl
+cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOOnHK5avIWZJV16vY
+dA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVCCSRrCl6zfN1SLUzm1NZ9
+WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7RfZHM047QS
+v4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9v
+UJSZSWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTu
+IYEZoDJJKPTEjlbVUjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwC
+W/POuZ6lcg5Ktz885hZo+L7tdEy8W9ViH0Pd
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB
+yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
+ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
+U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
+ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
+aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL
+MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
+ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln
+biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp
+U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
+aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1
+nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex
+t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz
+SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG
+BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+
+rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/
+NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E
+BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH
+BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy
+aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv
+MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE
+p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y
+5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK
+WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ
+4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N
+hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICPTCCAaYCEQDNun9W8N/kvFT+IqyzcqpVMA0GCSqGSIb3DQEBAgUAMF8xCzAJ
+BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xh
+c3MgMSBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05
+NjAxMjkwMDAwMDBaFw0yODA4MDEyMzU5NTlaMF8xCzAJBgNVBAYTAlVTMRcwFQYD
+VQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xhc3MgMSBQdWJsaWMgUHJp
+bWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCBnzANBgkqhkiG9w0BAQEFAAOB
+jQAwgYkCgYEA5Rm/baNWYS2ZSHH2Z965jeu3noaACpEO+jglr0aIguVzqKCbJF0N
+H8xlbgyw0FaEGIeaBpsQoXPftFg5a27B9hXVqKg/qhIGjTGsf7A01480Z4gJzRQR
+4k5FVmkfeAKA2txHkSm7NsljXMXg1y2He6G3MrB7MLoqLzGq7qNn2tsCAwEAATAN
+BgkqhkiG9w0BAQIFAAOBgQBMP7iLxmjf7kMzDl3ppssHhE16M/+SG/Q2rdiVIjZo
+EWx8QszznC7EBz8UsA9P/5CSdvnivErpj82ggAr3xSnxgiJduLHdgSOjeyUVRjB5
+FvjqBUuUfx3CHMjjt/QQQDwTw18fU+hI5Ia0e6E1sHslurjTjqs/OJ0ANACY89Fx
+lA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDAjCCAmsCEEzH6qqYPnHTkxD4PTqJkZIwDQYJKoZIhvcNAQEFBQAwgcExCzAJ
+BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh
+c3MgMSBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy
+MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp
+emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X
+DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw
+FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMSBQdWJsaWMg
+UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo
+YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5
+MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB
+AQUAA4GNADCBiQKBgQCq0Lq+Fi24g9TK0g+8djHKlNgdk4xWArzZbxpvUjZudVYK
+VdPfQ4chEWWKfo+9Id5rMj8bhDSVBZ1BNeuS65bdqlk/AVNtmU/t5eIqWpDBucSm
+Fc/IReumXY6cPvBkJHalzasab7bYe1FhbqZ/h8jit+U03EGI6glAvnOSPWvndQID
+AQABMA0GCSqGSIb3DQEBBQUAA4GBAKlPww3HZ74sy9mozS11534Vnjty637rXC0J
+h9ZrbWB85a7FkCMMXErQr7Fd88e2CtvgFZMN3QO8x3aKtd1Pw5sTdbgBwObJW2ul
+uIncrKTdcu1OofdPvAbT6shkdHvClUGcZXNY8ZCaPGqxmMnEh7zPRW1F4m4iP/68
+DzFc6PLZ
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEGjCCAwICEQCLW3VWhFSFCwDPrzhIzrGkMA0GCSqGSIb3DQEBBQUAMIHKMQsw
+CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl
+cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu
+LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT
+aWduIENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
+dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD
+VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT
+aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ
+bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu
+IENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
+LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN2E1Lm0+afY8wR4
+nN493GwTFtl63SRRZsDHJlkNrAYIwpTRMx/wgzUfbhvI3qpuFU5UJ+/EbRrsC+MO
+8ESlV8dAWB6jRx9x7GD2bZTIGDnt/kIYVt/kTEkQeE4BdjVjEjbdZrwBBDajVWjV
+ojYJrKshJlQGrT/KFOCsyq0GHZXi+J3x4GD/wn91K0zM2v6HmSHquv4+VNfSWXjb
+PG7PoBMAGrgnoeS+Z5bKoMWznN3JdZ7rMJpfo83ZrngZPyPpXNspva1VyBtUjGP2
+6KbqxzcSXKMpHgLZ2x87tNcPVkeBFQRKr4Mn0cVYiMHd9qqnoxjaaKptEVHhv2Vr
+n5Z20T0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAq2aN17O6x5q25lXQBfGfMY1a
+qtmqRiYPce2lrVNWYgFHKkTp/j90CxObufRNG7LRX7K20ohcs5/Ny9Sn2WCVhDr4
+wTcdYcrnsMXlkdpUpqwxga6X3s0IrLjAl4B/bnKk52kTlWUfxJM8/XmPBNQ+T+r3
+ns7NZ3xPZQL/kYVUc8f/NveGLezQXk//EZ9yBta4GvFMDSZl4kSAHsef493oCtrs
+pSCAaWihT37ha88HQfqDjrw43bAuEbFrskLMmrz5SCJ5ShkPshw+IHTZasO+8ih4
+E1Z5T21Q6huwtVexN2ZYI/PcD98Kh8TvhgXVOBRgmaNL3gaWcSzy27YfpO8/7g==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICPDCCAaUCEC0b/EoXjaOR6+f/9YtFvgswDQYJKoZIhvcNAQECBQAwXzELMAkG
+A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz
+cyAyIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2
+MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV
+BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAyIFB1YmxpYyBQcmlt
+YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN
+ADCBiQKBgQC2WoujDWojg4BrzzmH9CETMwZMJaLtVRKXxaeAufqDwSCg+i8VDXyh
+YGt+eSz6Bg86rvYbb7HS/y8oUl+DfUvEerf4Zh+AVPy3wo5ZShRXRtGak75BkQO7
+FYCTXOvnzAhsPz6zSvz/S2wj1VCCJkQZjiPDceoZJEcEnnW/yKYAHwIDAQABMA0G
+CSqGSIb3DQEBAgUAA4GBAIobK/o5wXTXXtgZZKJYSi034DNHD6zt96rbHuSLBlxg
+J8pFUs4W7z8GZOeUaHxgMxURaa+dYo2jA1Rrpr7l7gUYYAS/QoD90KioHgE796Nc
+r6Pc5iaAIzy4RHT3Cq5Ji2F4zCS/iIqnDupzGUH9TQPwiNHleI2lKk/2lw0Xd8rY
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDAzCCAmwCEQC5L2DMiJ+hekYJuFtwbIqvMA0GCSqGSIb3DQEBBQUAMIHBMQsw
+CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0Ns
+YXNzIDIgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH
+MjE6MDgGA1UECxMxKGMpIDE5OTggVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9y
+aXplZCB1c2Ugb25seTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazAe
+Fw05ODA1MTgwMDAwMDBaFw0yODA4MDEyMzU5NTlaMIHBMQswCQYDVQQGEwJVUzEX
+MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0NsYXNzIDIgUHVibGlj
+IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjE6MDgGA1UECxMx
+KGMpIDE5OTggVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s
+eTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazCBnzANBgkqhkiG9w0B
+AQEFAAOBjQAwgYkCgYEAp4gBIXQs5xoD8JjhlzwPIQjxnNuX6Zr8wgQGE75fUsjM
+HiwSViy4AWkszJkfrbCWrnkE8hM5wXuYuggs6MKEEyyqaekJ9MepAqRCwiNPStjw
+DqL7MWzJ5m+ZJwf15vRMeJ5t60aG+rmGyVTyssSv1EYcWskVMP8NbPUtDm3Of3cC
+AwEAATANBgkqhkiG9w0BAQUFAAOBgQByLvl/0fFx+8Se9sVeUYpAmLho+Jscg9ji
+nb3/7aHmZuovCfTK1+qlK5X2JGCGTUQug6XELaDTrnhpb3LabK4I8GOSN+a7xDAX
+rXfMSTWqz9iP0b63GJZHc2pUIjRkLbYWm1lbtFFZOrMLFPQS32eg9K0yZF6xRnIn
+jBJ7xUS0rg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEGTCCAwECEGFwy0mMX5hFKeewptlQW3owDQYJKoZIhvcNAQEFBQAwgcoxCzAJ
+BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVy
+aVNpZ24gVHJ1c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24s
+IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNp
+Z24gQ2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
+eSAtIEczMB4XDTk5MTAwMTAwMDAwMFoXDTM2MDcxNjIzNTk1OVowgcoxCzAJBgNV
+BAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNp
+Z24gVHJ1c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24sIElu
+Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNpZ24g
+Q2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAt
+IEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArwoNwtUs22e5LeWU
+J92lvuCwTY+zYVY81nzD9M0+hsuiiOLh2KRpxbXiv8GmR1BeRjmL1Za6tW8UvxDO
+JxOeBUebMXoT2B/Z0wI3i60sR/COgQanDTAM6/c8DyAd3HJG7qUCyFvDyVZpTMUY
+wZF7C9UTAJu878NIPkZgIIUq1ZC2zYugzDLdt/1AVbJQHFauzI13TccgTacxdu9o
+koqQHgiBVrKtaaNS0MscxCM9H5n+TOgWY47GCI72MfbS+uV23bUckqNJzc0BzWjN
+qWm6o+sdDZykIKbBoMXRRkwXbdKsZj+WjOCE1Db/IlnF+RFgqF8EffIa9iVCYQ/E
+Srg+iQIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQA0JhU8wI1NQ0kdvekhktdmnLfe
+xbjQ5F1fdiLAJvmEOjr5jLX77GDx6M4EsMjdpwOPMPOY36TmpDHf0xwLRtxyID+u
+7gU8pDM/CzmscHhzS5kr3zDCVLCoO1Wh/hYozUK9dG6A2ydEp85EXdQbkJgNHkKU
+sQAsBNB0owIFImNjzYO1+8FtYmtpdf1dcEG59b98377BMnMiIYtYgXsVkXq642RI
+sH/7NiXaldDxJBQX3RiAa0YjOVT1jmIJBB2UkKab5iXiQkWquJCtvgiPqQtCGJTP
+cjnhsUPgKM+351psE2tJs//jGHyJizNdrDPXp/naOlXJWBD5qu9ats9LS98q
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkG
+A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz
+cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2
+MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV
+BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt
+YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN
+ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE
+BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is
+I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G
+CSqGSIb3DQEBAgUAA4GBALtMEivPLCYATxQT3ab7/AoRhIzzKBxnki98tsX63/Do
+lbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59AhWM1pF+NEHJwZRDmJXNyc
+AA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2OmufTqj/ZA1k
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcExCzAJ
+BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh
+c3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy
+MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp
+emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X
+DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw
+FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMg
+UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo
+YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5
+MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB
+AQUAA4GNADCBiQKBgQDMXtERXVxp0KvTuWpMmR9ZmDCOFoUgRm1HP9SFIIThbbP4
+pO0M8RcPO/mn+SXXwc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71lSk8UOg0
+13gfqLptQ5GVj0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwID
+AQABMA0GCSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSk
+U01UbSuvDV1Ai2TT1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7i
+F6YM40AIOw7n60RzKprxaZLvcRTDOaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo1KpY
+oJ2daZH9
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQsw
+CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl
+cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu
+LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT
+aWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
+dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD
+VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT
+aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ
+bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu
+IENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
+LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMu6nFL8eB8aHm8b
+N3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1EUGO+i2t
+KmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGu
+kxUccLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBm
+CC+Vk7+qRy+oRpfwEuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJ
+Xwzw3sJ2zq/3avL6QaaiMxTJ5Xpj055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWu
+imi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAERSWwauSCPc/L8my/uRan2Te
+2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5fj267Cz3qWhMe
+DGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC
+/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565p
+F4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt
+TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDAjCCAmsCEDKIjprS9esTR/h/xCA3JfgwDQYJKoZIhvcNAQEFBQAwgcExCzAJ
+BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh
+c3MgNCBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy
+MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp
+emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X
+DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw
+FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgNCBQdWJsaWMg
+UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo
+YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5
+MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB
+AQUAA4GNADCBiQKBgQC68OTP+cSuhVS5B1f5j8V/aBH4xBewRNzjMHPVKmIquNDM
+HO0oW369atyzkSTKQWI8/AIBvxwWMZQFl3Zuoq29YRdsTjCG8FE3KlDHqGKB3FtK
+qsGgtG7rL+VXxbErQHDbWk2hjh+9Ax/YA9SPTJlxvOKCzFjomDqG04Y48wApHwID
+AQABMA0GCSqGSIb3DQEBBQUAA4GBAIWMEsGnuVAVess+rLhDityq3RS6iYF+ATwj
+cSGIL4LcY/oCRaxFWdcqWERbt5+BO5JoPeI3JPV7bI92NZYJqFmduc4jq3TWg/0y
+cyfYaT5DdPauxYma51N86Xv2S/PBZYPejYqcPIiNOVn8qj8ijaHBZlCBckztImRP
+T8qAkbYp
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEGjCCAwICEQDsoKeLbnVqAc/EfMwvlF7XMA0GCSqGSIb3DQEBBQUAMIHKMQsw
+CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl
+cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu
+LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT
+aWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
+dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD
+VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT
+aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ
+bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu
+IENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
+LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK3LpRFpxlmr8Y+1
+GQ9Wzsy1HyDkniYlS+BzZYlZ3tCD5PUPtbut8XzoIfzk6AzufEUiGXaStBO3IFsJ
++mGuqPKljYXCKtbeZjbSmwL0qJJgfJxptI8kHtCGUvYynEFYHiK9zUVilQhu0Gbd
+U6LM8BDcVHOLBKFGMzNcF0C5nk3T875Vg+ixiY5afJqWIpA7iCXy0lOIAgwLePLm
+NxdLMEYH5IBtptiWLugs+BGzOA1mppvqySNb247i8xOOGlktqgLw7KSHZtzBP/XY
+ufTsgsbSPZUd5cBPhMnZo0QoBmrXRazwa2rvTl/4EYIeOGM0ZlDUPpNz+jDDZq3/
+ky2X7wMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAj/ola09b5KROJ1WrIhVZPMq1
+CtRK26vdoV9TxaBXOcLORyu+OshWv8LZJxA6sQU8wHcxuzrTBXttmhwwjIDLk5Mq
+g6sFUYICABFna/OIYUdfA5PVWw3g8dShMjWFsjrbsIKr0csKvE+MW8VLADsfKoKm
+fjaF3H48ZwC15DtS4KjrXRX5xm3wrR0OhbepmnMUWluPQSjA1egtTaRezarZ7c7c
+2NU8Qh0XwRJdRTjDOPP8hS6DRkiy1yBfkjaP53kPmF6Z6PDQpLv1U70qzlmwr25/
+bLvSHgCwIe34QWKCudiyxLtGUPMxxY8BqHTr9Xgn2uf3ZkPznoM+IKrDNWCRzg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICNDCCAaECEAKtZn5ORf5eV288mBle3cAwDQYJKoZIhvcNAQECBQAwXzELMAkG
+A1UEBhMCVVMxIDAeBgNVBAoTF1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYD
+VQQLEyVTZWN1cmUgU2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk0
+MTEwOTAwMDAwMFoXDTEwMDEwNzIzNTk1OVowXzELMAkGA1UEBhMCVVMxIDAeBgNV
+BAoTF1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYDVQQLEyVTZWN1cmUgU2Vy
+dmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGbMA0GCSqGSIb3DQEBAQUAA4GJ
+ADCBhQJ+AJLOesGugz5aqomDV6wlAXYMra6OLDfO6zV4ZFQD5YRAUcm/jwjiioII
+0haGN1XpsSECrXZogZoFokvJSyVmIlZsiAeP94FZbYQHZXATcXY+m3dM41CJVphI
+uR2nKRoTLkoRWZweFdVJVCxzOmmCsZc5nG1wZ0jl3S3WyB57AgMBAAEwDQYJKoZI
+hvcNAQECBQADfgBl3X7hsuyw4jrg7HFGmhkRuNPHoLQDQCYCPgmc4RKz0Vr2N6W3
+YQO2WxZpO8ZECAyIUwxrl0nHPjXcbLm7qt9cuzovk2C2qUtN8iD3zV9/ZHuO3ABc
+1/p3yjkWWW8O6tO1g39NTUJWdrTJXwT4OPjr0l91X817/OWOgHz8UA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDzTCCAzagAwIBAgIQU2GyYK7bcY6nlLMTM/QHCTANBgkqhkiG9w0BAQUFADCB
+wTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTwwOgYDVQQL
+EzNDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5
+IC0gRzIxOjA4BgNVBAsTMShjKSAxOTk4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1
+dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv
+cmswHhcNMDAwOTI2MDAwMDAwWhcNMTAwOTI1MjM1OTU5WjCBpTEXMBUGA1UEChMO
+VmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsx
+OzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5j
+b20vcnBhIChjKTAwMSwwKgYDVQQDEyNWZXJpU2lnbiBUaW1lIFN0YW1waW5nIEF1
+dGhvcml0eSBDQTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0hmdZ8IAIVli
+zrQJIkRpivglWtvtDbc2fk7gu5Q+kCWHwmFHKdm9VLhjzCx9abQzNvQ3B5rB3UBU
+/OB4naCTuQk9I1F/RMIUdNsKvsvJMDRAmD7Q1yUQgZS9B0+c1lQn3y6ov8uQjI11
+S7zi6ESHzeZBCiVu6PQkAsVSD27smHUCAwEAAaOB3zCB3DAPBgNVHRMECDAGAQH/
+AgEAMEUGA1UdIAQ+MDwwOgYMYIZIAYb4RQEHFwEDMCowKAYIKwYBBQUHAgEWHGh0
+dHBzOi8vd3d3LnZlcmlzaWduLmNvbS9ycGEwMQYDVR0fBCowKDAmoCSgIoYgaHR0
+cDovL2NybC52ZXJpc2lnbi5jb20vcGNhMy5jcmwwCwYDVR0PBAQDAgEGMEIGCCsG
+AQUFBwEBBDYwNDAyBggrBgEFBQcwAaYmFiRodHRwOi8vb2NzcC52ZXJpc2lnbi5j
+b20vb2NzcC9zdGF0dXMwDQYJKoZIhvcNAQEFBQADgYEAgnBold+2DcIBcBlK0lRW
+HqzyRUyHuPU163hLBanInTsZIS5wNEqi9YngFXVF5yg3ADQnKeg3S/LvRJdrF1Ea
+w1adPBqK9kpGRjeM+sv1ZFo4aC4cw+9wzrhGBha/937ntag+RaypJXUie28/sJyU
+58dzq6wf7iWbwBbtt8pb8BQ=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDgDCCAmigAwIBAgICAx4wDQYJKoZIhvcNAQEFBQAwYTELMAkGA1UEBhMCVVMx
+DTALBgNVBAoTBFZJU0ExLzAtBgNVBAsTJlZpc2EgSW50ZXJuYXRpb25hbCBTZXJ2
+aWNlIEFzc29jaWF0aW9uMRIwEAYDVQQDEwlHUCBSb290IDIwHhcNMDAwODE2MjI1
+MTAwWhcNMjAwODE1MjM1OTAwWjBhMQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklT
+QTEvMC0GA1UECxMmVmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRp
+b24xEjAQBgNVBAMTCUdQIFJvb3QgMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
+AQoCggEBAKkBcLWqxEDwq2omYXkZAPy/mzdZDK9vZBv42pWUJGkzEXDK41Z0ohdX
+ZFwgBuHW73G3O/erwWnQSaSxBNf0V2KJXLB1LRckaeNCYOTudNargFbYiCjh+20i
+/SN8RnNPflRzHqgsVVh1t0zzWkWlAhr62p3DRcMiXvOL8WAp0sdftAw6UYPvMPjU
+58fy+pmjIlC++QU3o63tmsPm7IgbthknGziLgE3sucfFicv8GjLtI/C1AVj59o/g
+halMCXI5Etuz9c9OYmTaxhkVOmMd6RdVoUwiPDQyRvhlV7or7zaMavrZ2UT0qt2E
+1w0cslSsMoW0ZA3eQbuxNMYBhjJk1Z8CAwEAAaNCMEAwHQYDVR0OBBYEFJ59SzS/
+ca3CBfYDdYDOqU8axCRMMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEG
+MA0GCSqGSIb3DQEBBQUAA4IBAQAhpXYUVfmtJ3CPPPTVbMjMCqujmAuKBiPFyWHb
+mQdpNSYx/scuhMKZYdQN6X0uEyt8joW2hcdLzzW2LEc9zikv2G+fiRxkk78IvXbQ
+kIqUs38oW26sTTMs7WXcFsziza6kPWKSBpUmv9+55CCmc2rBvveURNZNbyoLaxhN
+dBA2aGpawWqn3TYpjLgwi08hPwAuVDAHOrqK5MOeyti12HvOdUVmB/RtLdh6yumJ
+ivIj2C/LbgA2T/vwLwHMD8AiZfSr4k5hLQOCfZEWtTDVFN5ex5D8ofyrEK9ca3Cn
+B+8phuiyJccg/ybdd+95RBTEvd07xQObdyPsoOy7Wjm1zK0G
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBr
+MQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRl
+cm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv
+bW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2WhcNMjIwNjI0MDAxNjEyWjBrMQsw
+CQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5h
+dGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1l
+cmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h
+2mCxlCfLF9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4E
+lpF7sDPwsRROEW+1QK8bRaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdV
+ZqW1LS7YgFmypw23RuwhY/81q6UCzyr0TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq
+299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI/k4+oKsGGelT84ATB+0t
+vz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzsGHxBvfaL
+dXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD
+AgEGMB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUF
+AAOCAQEAX/FBfXxcCLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcR
+zCSs00Rsca4BIGsDoo8Ytyk6feUWYFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3
+LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pzzkWKsKZJ/0x9nXGIxHYdkFsd
+7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBuYQa7FkKMcPcw
+++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt
+398znM/jra6O1I7mT1GvFpLgXPYHDw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEvTCCA6WgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBhTELMAkGA1UEBhMCVVMx
+IDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxs
+cyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9v
+dCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDcxMjEzMTcwNzU0WhcNMjIxMjE0
+MDAwNzU0WjCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdl
+bGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQD
+DC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkw
+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDub7S9eeKPCCGeOARBJe+r
+WxxTkqxtnt3CxC5FlAM1iGd0V+PfjLindo8796jE2yljDpFoNoqXjopxaAkH5OjU
+Dk/41itMpBb570OYj7OeUt9tkTmPOL13i0Nj67eT/DBMHAGTthP796EfvyXhdDcs
+HqRePGj4S78NuR4uNuip5Kf4D8uCdXw1LSLWwr8L87T8bJVhHlfXBIEyg1J55oNj
+z7fLY4sR4r1e6/aN7ZVyKLSsEmLpSjPmgzKuBXWVvYSV2ypcm44uDLiBK0HmOFaf
+SZtsdvqKXfcBeYF8wYNABf5x/Qw/zE5gCQ5lRxAvAcAFP4/4s0HvWkJ+We/Slwxl
+AgMBAAGjggE0MIIBMDAPBgNVHRMBAf8EBTADAQH/MDkGA1UdHwQyMDAwLqAsoCqG
+KGh0dHA6Ly9jcmwucGtpLndlbGxzZmFyZ28uY29tL3dzcHJjYS5jcmwwDgYDVR0P
+AQH/BAQDAgHGMB0GA1UdDgQWBBQmlRkQ2eihl5H/3BnZtQQ+0nMKajCBsgYDVR0j
+BIGqMIGngBQmlRkQ2eihl5H/3BnZtQQ+0nMKaqGBi6SBiDCBhTELMAkGA1UEBhMC
+VVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNX
+ZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMg
+Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHmCAQEwDQYJKoZIhvcNAQEFBQADggEB
+ALkVsUSRzCPIK0134/iaeycNzXK7mQDKfGYZUMbVmO2rvwNa5U3lHshPcZeG1eMd
+/ZDJPHV3V3p9+N701NX3leZ0bh08rnyd2wIDBSxxSyU+B+NemvVmFymIGjifz6pB
+A4SXa5M4esowRBskRDPQ5NHcKDj0E0M1NSljqHyita04pO2t/caaH/+Xc/77szWn
+k4bGdpEA5qxRFsQnMlzbc9qlk1eOPm01JghZ1edE13YgY+esE2fDbbFwRnzVlhE9
+iW9dqKHrjQrawx0zbKPqZxmamX9LPYNRKh3KL4YMon4QLSvUFpULB6ouFJJJtylv
+2G0xffX8oRAHh84vWdw+WNs=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIID5TCCAs2gAwIBAgIEOeSXnjANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UEBhMC
+VVMxFDASBgNVBAoTC1dlbGxzIEZhcmdvMSwwKgYDVQQLEyNXZWxscyBGYXJnbyBD
+ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEvMC0GA1UEAxMmV2VsbHMgRmFyZ28gUm9v
+dCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDAxMDExMTY0MTI4WhcNMjEwMTE0
+MTY0MTI4WjCBgjELMAkGA1UEBhMCVVMxFDASBgNVBAoTC1dlbGxzIEZhcmdvMSww
+KgYDVQQLEyNXZWxscyBGYXJnbyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEvMC0G
+A1UEAxMmV2VsbHMgRmFyZ28gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVqDM7Jvk0/82bfuUER84A4n13
+5zHCLielTWi5MbqNQ1mXx3Oqfz1cQJ4F5aHiidlMuD+b+Qy0yGIZLEWukR5zcUHE
+SxP9cMIlrCL1dQu3U+SlK93OvRw6esP3E48mVJwWa2uv+9iWsWCaSOAlIiR5NM4O
+JgALTqv9i86C1y8IcGjBqAr5dE8Hq6T54oN+J3N0Prj5OEL8pahbSCOz6+MlsoCu
+ltQKnMJ4msZoGK43YjdeUXWoWGPAUe5AeH6orxqg4bB4nVCMe+ez/I4jsNtlAHCE
+AQgAFG5Uhpq6zPk3EPbg3oQtnaSFN9OH4xXQwReQfhkhahKpdv0SAulPIV4XAgMB
+AAGjYTBfMA8GA1UdEwEB/wQFMAMBAf8wTAYDVR0gBEUwQzBBBgtghkgBhvt7hwcB
+CzAyMDAGCCsGAQUFBwIBFiRodHRwOi8vd3d3LndlbGxzZmFyZ28uY29tL2NlcnRw
+b2xpY3kwDQYJKoZIhvcNAQEFBQADggEBANIn3ZwKdyu7IvICtUpKkfnRLb7kuxpo
+7w6kAOnu5+/u9vnldKTC2FJYxHT7zmu1Oyl5GFrvm+0fazbuSCUlFLZWohDo7qd/
+0D+j0MNdJu4HzMPBJCGHHt8qElNvQRbn7a6U+oxy+hNH8Dx+rn0ROhPs7fpvcmR7
+nX1/Jv16+yWt6j4pf0zjAFcysLPp7VMX2YuyFA4w6OXVE8Zkr8QA1dhYJPz1j+zx
+x32l2w8n0cbyQIjmH/ZhqPRCyLk306m+LFZ4wnKbWV01QIroTmMatukgalHizqSQ
+33ZwmVxwQ023tqcZZE6St8WRPH9IFmV7Fv3L/PvZ1dZPIWU7Sn9Ho/s=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB
+gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk
+MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY
+UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx
+NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3
+dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy
+dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB
+dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6
+38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP
+KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q
+DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4
+qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa
+JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi
+PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P
+BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs
+jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0
+eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD
+ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR
+vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt
+qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa
+IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy
+i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ
+O+7ETPTsJ3xCwnR8gooJybQDJbw=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFajCCBFKgAwIBAgIEPLU9RjANBgkqhkiG9w0BAQUFADBmMRIwEAYDVQQKEwli
+ZVRSVVNUZWQxGzAZBgNVBAsTEmJlVFJVU1RlZCBSb290IENBczEzMDEGA1UEAxMq
+YmVUUlVTVGVkIFJvb3QgQ0EtQmFsdGltb3JlIEltcGxlbWVudGF0aW9uMB4XDTAy
+MDQxMTA3Mzg1MVoXDTIyMDQxMTA3Mzg1MVowZjESMBAGA1UEChMJYmVUUlVTVGVk
+MRswGQYDVQQLExJiZVRSVVNUZWQgUm9vdCBDQXMxMzAxBgNVBAMTKmJlVFJVU1Rl
+ZCBSb290IENBLUJhbHRpbW9yZSBJbXBsZW1lbnRhdGlvbjCCASIwDQYJKoZIhvcN
+AQEBBQADggEPADCCAQoCggEBALx+xDmcjOPWHIb/ymKt4H8wRXqOGrO4x/nRNv8i
+805qX4QQ+2aBw5R5MdKR4XeOGCrDFN5R9U+jK7wYFuK13XneIviCfsuBH/0nLI/6
+l2Qijvj/YaOcGx6Sj8CoCd8JEey3fTGaGuqDIQY8n7pc/5TqarjDa1U0Tz0yH92B
+FODEPM2dMPgwqZfT7syj0B9fHBOB1BirlNFjw55/NZKeX0Tq7PQiXLfoPX2k+Ymp
+kbIq2eszh+6l/ePazIjmiSZuxyuC0F6dWdsU7JGDBcNeDsYq0ATdcT0gTlgn/FP7
+eHgZFLL8kFKJOGJgB7Sg7KxrUNb9uShr71ItOrL/8QFArDcCAwEAAaOCAh4wggIa
+MA8GA1UdEwEB/wQFMAMBAf8wggG1BgNVHSAEggGsMIIBqDCCAaQGDysGAQQBsT4A
+AAEJKIORMTCCAY8wggFIBggrBgEFBQcCAjCCAToaggE2UmVsaWFuY2Ugb24gb3Ig
+dXNlIG9mIHRoaXMgQ2VydGlmaWNhdGUgY3JlYXRlcyBhbiBhY2tub3dsZWRnbWVu
+dCBhbmQgYWNjZXB0YW5jZSBvZiB0aGUgdGhlbiBhcHBsaWNhYmxlIHN0YW5kYXJk
+IHRlcm1zIGFuZCBjb25kaXRpb25zIG9mIHVzZSwgdGhlIENlcnRpZmljYXRpb24g
+UHJhY3RpY2UgU3RhdGVtZW50IGFuZCB0aGUgUmVseWluZyBQYXJ0eSBBZ3JlZW1l
+bnQsIHdoaWNoIGNhbiBiZSBmb3VuZCBhdCB0aGUgYmVUUlVTVGVkIHdlYiBzaXRl
+LCBodHRwOi8vd3d3LmJldHJ1c3RlZC5jb20vcHJvZHVjdHNfc2VydmljZXMvaW5k
+ZXguaHRtbDBBBggrBgEFBQcCARY1aHR0cDovL3d3dy5iZXRydXN0ZWQuY29tL3By
+b2R1Y3RzX3NlcnZpY2VzL2luZGV4Lmh0bWwwHQYDVR0OBBYEFEU9w6nR3D8kVpgc
+cxiIav+DR+22MB8GA1UdIwQYMBaAFEU9w6nR3D8kVpgccxiIav+DR+22MA4GA1Ud
+DwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEASZK8o+6svfoNyYt5hhwjdrCA
+WXf82n+0S9/DZEtqTg6t8n1ZdwWtColzsPq8y9yNAIiPpqCy6qxSJ7+hSHyXEHu6
+7RMdmgduyzFiEuhjA6p9beP4G3YheBufS0OM00mG9htc9i5gFdPp43t1P9ACg9AY
+gkHNZTfqjjJ+vWuZXTARyNtIVBw74acT02pIk/c9jH8F6M7ziCpjBLjqflh8AXtb
+4cV97yHgjQ5dUX2xZ/2jvTg2xvI4hocalmhgRvsoFEdV4aeADGvi6t9NfJBIoDa9
+CReJf8Py05yc493EG931t3GzUwWJBtDLSoDByFOQtTwxiBdQn8nEDovYqAJjDQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFLDCCBBSgAwIBAgIEOU99hzANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJX
+VzESMBAGA1UEChMJYmVUUlVTVGVkMRswGQYDVQQDExJiZVRSVVNUZWQgUm9vdCBD
+QXMxGjAYBgNVBAMTEWJlVFJVU1RlZCBSb290IENBMB4XDTAwMDYyMDE0MjEwNFoX
+DTEwMDYyMDEzMjEwNFowWjELMAkGA1UEBhMCV1cxEjAQBgNVBAoTCWJlVFJVU1Rl
+ZDEbMBkGA1UEAxMSYmVUUlVTVGVkIFJvb3QgQ0FzMRowGAYDVQQDExFiZVRSVVNU
+ZWQgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANS0c3oT
+CjhVAb6JVuGUntS+WutKNHUbYSnE4a0IYCF4SP+00PpeQY1hRIfo7clY+vyTmt9P
+6j41ffgzeubx181vSUs9Ty1uDoM6GHh3o8/n9E1z2Jo7Gh2+lVPPIJfCzz4kUmwM
+jmVZxXH/YgmPqsWPzGCgc0rXOD8Vcr+il7dw6K/ifhYGTPWqZCZyByWtNfwYsSbX
+2P8ZDoMbjNx4RWc0PfSvHI3kbWvtILNnmrRhyxdviTX/507AMhLn7uzf/5cwdO2N
+R47rtMNE5qdMf1ZD6Li8tr76g5fmu/vEtpO+GRg+jIG5c4gW9JZDnGdzF5DYCW5j
+rEq2I8QBoa2k5MUCAwEAAaOCAfgwggH0MA8GA1UdEwEB/wQFMAMBAf8wggFZBgNV
+HSAEggFQMIIBTDCCAUgGCisGAQQBsT4BAAAwggE4MIIBAQYIKwYBBQUHAgIwgfQa
+gfFSZWxpYW5jZSBvbiB0aGlzIGNlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBhc3N1
+bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFyZCB0
+ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGFuZCBjZXJ0aWZpY2F0aW9uIHBy
+YWN0aWNlIHN0YXRlbWVudCwgd2hpY2ggY2FuIGJlIGZvdW5kIGF0IGJlVFJVU1Rl
+ZCdzIHdlYiBzaXRlLCBodHRwczovL3d3dy5iZVRSVVNUZWQuY29tL3ZhdWx0L3Rl
+cm1zMDEGCCsGAQUFBwIBFiVodHRwczovL3d3dy5iZVRSVVNUZWQuY29tL3ZhdWx0
+L3Rlcm1zMDQGA1UdHwQtMCswKaAnoCWkIzAhMRIwEAYDVQQKEwliZVRSVVNUZWQx
+CzAJBgNVBAYTAldXMB0GA1UdDgQWBBQquZtpLjub2M3eKjEENGvKBxirZzAfBgNV
+HSMEGDAWgBQquZtpLjub2M3eKjEENGvKBxirZzAOBgNVHQ8BAf8EBAMCAf4wDQYJ
+KoZIhvcNAQEFBQADggEBAHlh26Nebhax6nZR+csVm8tpvuaBa58oH2U+3RGFktTo
+Qb9+M70j5/Egv6S0phkBxoyNNXxlpE8JpNbYIxUFE6dDea/bow6be3ga8wSGWsb2
+jCBHOElQBp1yZzrwmAOtlmdE/D8QDYZN5AA7KXvOOzuZhmElQITcE2K3+spZ1gMe
+1lMBzW1MaFVA4e5rxyoAAEiCswoBw2AqDPeCNe5IhpbkdNQ96gFxugR1QKepfzk5
+mlWXKWWuGVUlBXJH0+gY3Ljpr0NzARJ0o+FcXxVdJPP55PS2Z2cS52QiivalQaYc
+tmBjRYoQtLpGEK5BV2VsPyMQPyEQWbfkQN0mDCP2qq4=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIGUTCCBTmgAwIBAgIEPLVPQDANBgkqhkiG9w0BAQUFADBmMRIwEAYDVQQKEwli
+ZVRSVVNUZWQxGzAZBgNVBAsTEmJlVFJVU1RlZCBSb290IENBczEzMDEGA1UEAxMq
+YmVUUlVTVGVkIFJvb3QgQ0EgLSBFbnRydXN0IEltcGxlbWVudGF0aW9uMB4XDTAy
+MDQxMTA4MjQyN1oXDTIyMDQxMTA4NTQyN1owZjESMBAGA1UEChMJYmVUUlVTVGVk
+MRswGQYDVQQLExJiZVRSVVNUZWQgUm9vdCBDQXMxMzAxBgNVBAMTKmJlVFJVU1Rl
+ZCBSb290IENBIC0gRW50cnVzdCBJbXBsZW1lbnRhdGlvbjCCASIwDQYJKoZIhvcN
+AQEBBQADggEPADCCAQoCggEBALr0RAOqEmq1Q+xVkrYwfTVXDNvzDSduTPdQqJtO
+K2/b9a0cS12zqcH+e0TrW6MFDR/FNCswACnxeECypP869AGIF37m1CbTukzqMvtD
+d5eHI8XbQ6P1KqNRXuE70mVpflUVm3rnafdE4Fe1FehmYA8NA/uCjqPoEXtsvsdj
+DheT389Lrm5zdeDzqrmkwAkbhepxKYhBMvnwKg5sCfJ0a2ZsUhMfGLzUPvfYbiCe
+yv78IZTuEyhL11xeDGbu6bsPwTSxfwh28z0mcMmLJR1iJAzqHHVOwBLkuhMdMCkt
+VjMFu5dZfsZJT4nXLySotohAtWSSU1Yk5KKghbNekLQSM80CAwEAAaOCAwUwggMB
+MIIBtwYDVR0gBIIBrjCCAaowggGmBg8rBgEEAbE+AAACCSiDkTEwggGRMIIBSQYI
+KwYBBQUHAgIwggE7GoIBN1JlbGlhbmNlIG9uIG9yIHVzZSBvZiB0aGlzIENlcnRp
+ZmljYXRlIGNyZWF0ZXMgYW4gYWNrbm93bGVkZ21lbnQgYW5kIGFjY2VwdGFuY2Ug
+b2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0
+aW9ucyBvZiB1c2UsIHRoZSBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu
+dCBhbmQgdGhlIFJlbHlpbmcgUGFydHkgQWdyZWVtZW50LCB3aGljaCBjYW4gYmUg
+Zm91bmQgYXQgdGhlIGJlVFJVU1RlZCB3ZWIgc2l0ZSwgaHR0cHM6Ly93d3cuYmV0
+cnVzdGVkLmNvbS9wcm9kdWN0c19zZXJ2aWNlcy9pbmRleC5odG1sMEIGCCsGAQUF
+BwIBFjZodHRwczovL3d3dy5iZXRydXN0ZWQuY29tL3Byb2R1Y3RzX3NlcnZpY2Vz
+L2luZGV4Lmh0bWwwEQYJYIZIAYb4QgEBBAQDAgAHMIGJBgNVHR8EgYEwfzB9oHug
+eaR3MHUxEjAQBgNVBAoTCWJlVFJVU1RlZDEbMBkGA1UECxMSYmVUUlVTVGVkIFJv
+b3QgQ0FzMTMwMQYDVQQDEypiZVRSVVNUZWQgUm9vdCBDQSAtIEVudHJ1c3QgSW1w
+bGVtZW50YXRpb24xDTALBgNVBAMTBENSTDEwKwYDVR0QBCQwIoAPMjAwMjA0MTEw
+ODI0MjdagQ8yMDIyMDQxMTA4NTQyN1owCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaA
+FH1w5a44iwY/qhwaj/nPJDCqhIQWMB0GA1UdDgQWBBR9cOWuOIsGP6ocGo/5zyQw
+qoSEFjAMBgNVHRMEBTADAQH/MB0GCSqGSIb2fQdBAAQQMA4bCFY2LjA6NC4wAwIE
+kDANBgkqhkiG9w0BAQUFAAOCAQEAKrgXzh8QlOu4mre5X+za95IkrNySO8cgjfKZ
+5V04ocI07cUTWVwFtStPYZuR+0H8/NU8TZh2BvWBfevdkObRVlTa4y0MnxEylCIB
+evZsLHRnBMylj44ss0O1lKLQfelifwa+JwGDnjr9iu6YQ0pr17WXOzq/T220Y/oz
+ADQuLW2WyXvKmWO6vvT2MKAtmJbpVkQFqUSjYRDrgqFnXbxdJ3Wqiig2KjiS2d2k
+XgClzMx8KSreKJCrt+G2/30lC0DYqjSjLd4H61/OCt3Kfjp9JsFiaDrmLzfzgYYh
+xKlkqu9FNtEaZnz46TfW1mG+oq1I59/mdP7TbX3SJdysYlep9w==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFaDCCBFCgAwIBAgIQO1nHe81bV569N1KsdrSqGjANBgkqhkiG9w0BAQUFADBi
+MRIwEAYDVQQKEwliZVRSVVNUZWQxGzAZBgNVBAsTEmJlVFJVU1RlZCBSb290IENB
+czEvMC0GA1UEAxMmYmVUUlVTVGVkIFJvb3QgQ0EgLSBSU0EgSW1wbGVtZW50YXRp
+b24wHhcNMDIwNDExMTExODEzWhcNMjIwNDEyMTEwNzI1WjBiMRIwEAYDVQQKEwli
+ZVRSVVNUZWQxGzAZBgNVBAsTEmJlVFJVU1RlZCBSb290IENBczEvMC0GA1UEAxMm
+YmVUUlVTVGVkIFJvb3QgQ0EgLSBSU0EgSW1wbGVtZW50YXRpb24wggEiMA0GCSqG
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkujQwCY5X0LkGLG9uJIAiv11DpvpPrILn
+HGhwhRujbrWqeNluB0s/6d/16uhUoWGKDi9pdRi3DOUUjXFumLhV/AyV0Jtu4S2I
+1DpAa5LxmZZk3tv/ePTulh1HiXzUvrmIdyM6CeYEnm2qXtLIvZpOGd+J6lsOfsPk
+tPDgaTuID0GQ+NRxQyTBjyZLO1bp/4xsN+lFrYWMU8NghpBKlsmzVLC7F/AcRdnU
+GxlkVgoZ98zh/4avflherHqQH8koOUV7orbHnB/ahdQhhlkwk75TMzf270HPM8er
+cmsl9fNTGwxMLvF1S++gh/f+ihXQbNXL+WhTuXAVE8L1LvtDNXUtAgMBAAGjggIY
+MIICFDAMBgNVHRMEBTADAQH/MIIBtQYDVR0gBIIBrDCCAagwggGkBg8rBgEEAbE+
+AAADCSiDkTEwggGPMEEGCCsGAQUFBwIBFjVodHRwOi8vd3d3LmJldHJ1c3RlZC5j
+b20vcHJvZHVjdHNfc2VydmljZXMvaW5kZXguaHRtbDCCAUgGCCsGAQUFBwICMIIB
+OhqCATZSZWxpYW5jZSBvbiBvciB1c2Ugb2YgdGhpcyBDZXJ0aWZpY2F0ZSBjcmVh
+dGVzIGFuIGFja25vd2xlZGdtZW50IGFuZCBhY2NlcHRhbmNlIG9mIHRoZSB0aGVu
+IGFwcGxpY2FibGUgc3RhbmRhcmQgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YgdXNl
+LCB0aGUgQ2VydGlmaWNhdGlvbiBQcmFjdGljZSBTdGF0ZW1lbnQgYW5kIHRoZSBS
+ZWx5aW5nIFBhcnR5IEFncmVlbWVudCwgd2hpY2ggY2FuIGJlIGZvdW5kIGF0IHRo
+ZSBiZVRSVVNUZWQgd2ViIHNpdGUsIGh0dHA6Ly93d3cuYmV0cnVzdGVkLmNvbS9w
+cm9kdWN0c19zZXJ2aWNlcy9pbmRleC5odG1sMAsGA1UdDwQEAwIBBjAfBgNVHSME
+GDAWgBSp7BR++dlDzFMrFK3P9/BZiUHNGTAdBgNVHQ4EFgQUqewUfvnZQ8xTKxSt
+z/fwWYlBzRkwDQYJKoZIhvcNAQEFBQADggEBANuXsHXqDMTBmMpWBcCorSZIry0g
+6IHHtt9DwSwddUvUQo3neqh03GZCWYez9Wlt2ames30cMcH1VOJZJEnl7r05pmuK
+mET7m9cqg5c0Lcd9NUwtNLg+DcTsiCevnpL9UGGCqGAHFFPMZRPB9kdEadIxyKbd
+LrML3kqNWz2rDcI1UqJWN8wyiyiFQpyRQHpwKzg21eFzGh/l+n5f3NacOzDq28Bb
+J1zTcwfBwvNMm2+fG8oeqqg4MwlYsq78B+g23FW6L09A/nq9BqaBwZMifIYRCgZ3
+SK41ty8ymmFei74pnykkiFY5LKjSq5YDWtRIn7lAhAuYaPsBQ9Yb4gmxlxw=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB
+qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
+Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
+MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV
+BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw
+NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j
+LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG
+A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
+IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs
+W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta
+3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk
+6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6
+Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J
+NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA
+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP
+r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU
+DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz
+YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX
+xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2
+/qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/
+LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7
+jVaMaA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIETzCCAzegAwIBAgIEO63vKTANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJQTDEfMB0GA1UE
+ChMWVFAgSW50ZXJuZXQgU3AuIHogby5vLjEkMCIGA1UECxMbQ2VudHJ1bSBDZXJ0eWZpa2Fjamkg
+U2lnbmV0MRswGQYDVQQDExJDQyBTaWduZXQgLSBSb290Q0EwHhcNMDEwOTIzMTQxODE3WhcNMTEw
+OTIzMTMxODE3WjB1MQswCQYDVQQGEwJQTDEfMB0GA1UEChMWVFAgSW50ZXJuZXQgU3AuIHogby5v
+LjEkMCIGA1UECxMbQ2VudHJ1bSBDZXJ0eWZpa2FjamkgU2lnbmV0MR8wHQYDVQQDExZDQyBTaWdu
+ZXQgLSBDQSBLbGFzYSAxMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4SRW9Q58g5DY1Hw7h
+gCRKBEdPdGn0MFHsfw7rlu/oQm7IChI/uWd9q5wwo77YojtTDjRnpgZsjqBeynX8T90vFILqsY2K
+5CF1OESalwvVr3sZiQX79lisuFKat92u6hBFikFIVxfHHB67Af+g7u0dEHdDW7lwy81MwFYxBTRy
+9wIDAQABo4IBbTCCAWkwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwggEEBgNVHSAE
+gfwwgfkwgfYGDSsGAQQBvj8CAQoBAQAwgeQwgZoGCCsGAQUFBwICMIGNGoGKQ2VydHlmaWthdCB3
+eXN0YXdpb255IHpnb2RuaWUgeiBkb2t1bWVudGVtOiAiUG9saXR5a2EgQ2VydHlmaWthY2ppIGRs
+YSBSb290Q0EiLiBDZXJ0eWZpa2F0IHd5c3Rhd2lvbnkgcHJ6ZXogUm9vdENBIHcgaGllcmFyY2hp
+aSBDQyBTaWduZXQuMEUGCCsGAQUFBwIBFjlodHRwOi8vd3d3LnNpZ25ldC5wbC9yZXBvenl0b3Jp
+dW0vZG9rdW1lbnR5L3BjX3Jvb3RjYS50eHQwHwYDVR0jBBgwFoAUwJvFIw0C4aZOSGsfAOnjmhQb
+sa8wHQYDVR0OBBYEFMODHtVZd1T7TftXR/nEI1zR54njMA0GCSqGSIb3DQEBBQUAA4IBAQBRIHQB
+FIGh8Jpxt87AgSLwIEEk4+oGy769u3NtoaR0R3WNMdmt7fXTi0tyTQ9V4AIszxVjhnUPaKnF1KYy
+f8Tl+YTzk9ZfFkZ3kCdSaILZAOIrmqWNLPmjUQ5/JiMGho0e1YmWUcMci84+pIisTsytFzVP32/W
++sz2H4FQAvOIMmxB7EJX9AdbnXn9EXZ+4nCqi0ft5z96ZqOJJiCB3vSaoYg+wdkcvb6souMJzuc2
+uptXtR1Xf3ihlHaGW+hmnpcwFA6AoNrom6Vgzk6U1ienx0Cw28BhRSKqzKkyXkuK8gRflZUx84uf
+tXncwKJrMiE3lvgOOBITRzcahirLer4c
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIE9zCCA9+gAwIBAgIEPL/xoTANBgkqhkiG9w0BAQUFADB2MQswCQYDVQQGEwJQTDEfMB0GA1UE
+ChMWVFAgSW50ZXJuZXQgU3AuIHogby5vLjEkMCIGA1UECxMbQ2VudHJ1bSBDZXJ0eWZpa2Fjamkg
+U2lnbmV0MSAwHgYDVQQDExdDQyBTaWduZXQgLSBQQ0EgS2xhc2EgMjAeFw0wMjA0MTkxMDI5NTNa
+Fw0xNzA0MTgxMjUzMDdaMHUxCzAJBgNVBAYTAlBMMR8wHQYDVQQKExZUUCBJbnRlcm5ldCBTcC4g
+eiBvLm8uMSQwIgYDVQQLExtDZW50cnVtIENlcnR5ZmlrYWNqaSBTaWduZXQxHzAdBgNVBAMTFkND
+IFNpZ25ldCAtIENBIEtsYXNhIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqgLJu
+QqY4yavbSgHg8CyfKTx4BokNSDOVz4eD9vptUr11Kqd06ED1hlH7Sg0goBFAfntNU/QTKwSBaNui
+me7C4sSEdgsKrPoAhGb4Mq8y7Ty7RqZz7mkzNMqzL2L2U4yQ2QjvpH8MH0IBqOWEcpSkpwnrCDIm
+RoTfd+YlZWKi2JceQixUUYIQ45Ox8+x8hHbvvZdgqtcvo8PW27qoHkp/7hMuJ44kDAGrmxffBXl/
+OBRZp0uO1CSLcMcVJzyr2phKhy406MYdWrtNPEluGs0GFDzd0nrIctiWAO4cmct4S72S9Q6e//0G
+O9f3/Ca5Kb2I1xYLj/xE+HgjHX9aD2MhAgMBAAGjggGMMIIBiDAPBgNVHRMBAf8EBTADAQH/MA4G
+A1UdDwEB/wQEAwIBBjCB4wYDVR0gBIHbMIHYMIHVBg0rBgEEAb4/AhQKAQEAMIHDMHUGCCsGAQUF
+BwICMGkaZ0NlcnR5ZmlrYXQgd3lzdGF3aW9ueSB6Z29kbmllIHogZG9rdW1lbnRlbTogIlBvbGl0
+eWthIENlcnR5ZmlrYWNqaSBQQ0EyIC0gQ2VydHlmaWthdHkgVXJ6ZWRvdyBLbGFzeSAyIi4wSgYI
+KwYBBQUHAgEWPmh0dHA6Ly93d3cuc2lnbmV0LnBsL3JlcG96eXRvcml1bS9kb2t1bWVudHkva2xh
+c2EyL3BjX3BjYTIudHh0MD8GA1UdHwQ4MDYwNKAyoDCGLmh0dHA6Ly93d3cuc2lnbmV0LnBsL3Jl
+cG96eXRvcml1bS9jcmwvcGNhMi5jcmwwHwYDVR0jBBgwFoAUwGxGyl2CfpYHRonE82AVXO08kMIw
+HQYDVR0OBBYEFLtFBlILy4HNKVSzvHxBTM0HDowlMA0GCSqGSIb3DQEBBQUAA4IBAQBWTsCbqXrX
+hBBev5v5cIuc6gJM8ww7oR0uMQRZoFSqvQUPWBYM2/TLI/f8UM9hSShUVj3zEsSj/vFHagUVmzuV
+Xo5u0WK8iaqATSyEVBhADHrPG6wYcLKJlagge/ILA0m+SieyP2sjYD9MUB9KZIEyBKv0429UuDTw
+6P7pslxMWJBSNyQxaLIs0SRKsqZZWkc7ZYAj2apSkBMX2Is1oHA+PwkF6jQMwCao/+CndXPUzfCF
+6caa9WwW31W26MlXCvSmJgfiTPwGvm4PkPmOnmWZ3CczzhHl4q7ztHFzshJH3sZWDnrWwBFjzz5e
+Pr3WHV1wA7EY6oT4zBx+2gT9XBTB
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEUzCCAzugAwIBAgIEPq+qjzANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQGEwJQTDE3MDUGA1UE
+ChMuQ1ppQyBDZW50cmFzdCBTQSB3IGltaWVuaXUgTWluaXN0cmEgR29zcG9kYXJraTEZMBcGA1UE
+AxMQQ1ppQyBDZW50cmFzdCBTQTAeFw0wMzA0MzAxMDUwNTVaFw0wODA0MjgxMDUwNTVaMGgxCzAJ
+BgNVBAYTAlBMMR8wHQYDVQQKExZUUCBJbnRlcm5ldCBTcC4geiBvLm8uMR8wHQYDVQQDExZDQyBT
+aWduZXQgLSBDQSBLbGFzYSAzMRcwFQYDVQQFEw5OdW1lciB3cGlzdTogNDCCASIwDQYJKoZIhvcN
+AQEBBQADggEPADCCAQoCggEBALVdeOM62cPH2NERFxbS5FIp/HSv3fgesdVsTUFxZbGtE+/E0RMl
+KZQJHH9emx7vRYubsi4EOLCjYsCOTFvgGRIpZzx7R7T5c0Di5XFkRU4gjBl7aHJoKb5SLzGlWdoX
+GsekVtl6keEACrizV2EafqjI8cnBWY7OxQ1ooLQp5AeFjXg+5PT0lO6TUZAubqjFbhVbxSWjqvdj
+93RGfyYE76MnNn4c2xWySD07n7uno06TC0IJe6+3WSX1h+76VsIFouWBXOoM7cxxiLjoqdBVu24+
+P8e81SukE7qEvOwDPmk9ZJFtt1nBNg8a1kaixcljrA/43XwOPz6qnJ+cIj/xywECAwEAAaOCAQow
+ggEGMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMDMGA1UdIAEB/wQpMCcwJQYEVR0g
+ADAdMBsGCCsGAQUFBwIBFg93d3cuY2VudHJhc3QucGwwgY4GA1UdIwSBhjCBg4AU2a7r85Cp1iJN
+W0Ca1LR6VG3996ShZaRjMGExCzAJBgNVBAYTAlBMMTcwNQYDVQQKEy5DWmlDIENlbnRyYXN0IFNB
+IHcgaW1pZW5pdSBNaW5pc3RyYSBHb3Nwb2RhcmtpMRkwFwYDVQQDExBDWmlDIENlbnRyYXN0IFNB
+ggQ9/0sQMB0GA1UdDgQWBBR7Y8wZkHq0zrY7nn1tFSdQ0PlJuTANBgkqhkiG9w0BAQUFAAOCAQEA
+ldt/svO5c1MU08FKgrOXCGEbEPbQxhpM0xcd6Iv3dCo6qugEgjEs9Qm5CwUNKMnFsvR27cJWUvZb
+MVcvwlwCwclOdwF6u/QRS8bC2HYErhYo9bp9yuxxzuow2A94c5fPqfVrjXy+vDouchAm6+A5Wjzv
+J8wxVFDCs+9iGACmyUWr/JGXCYiQIbQkwlkRKHHlan9ymKf1NvIej/3EpeT8fKr6ywxGuhAfqofW
+pg3WJY/RCB4lTzD8vZGNwfMFGkWhJkypad3i9w3lGmDVpsHaWtCgGfd0H7tUtWPkP+t7EjIRCD9J
+HYnTR+wbbewc5vOI+UobR15ynGfFIaSIiMTVtQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEejCCA2KgAwIBAgIEP4vk6TANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJQ
+TDEfMB0GA1UEChMWVFAgSW50ZXJuZXQgU3AuIHogby5vLjEkMCIGA1UECxMbQ2Vu
+dHJ1bSBDZXJ0eWZpa2FjamkgU2lnbmV0MR8wHQYDVQQDExZDQyBTaWduZXQgLSBD
+QSBLbGFzYSAyMB4XDTAzMTAxNDExNTgyMloXDTE3MDQxODEyNTMwN1owdzELMAkG
+A1UEBhMCUEwxHzAdBgNVBAoTFlRQIEludGVybmV0IFNwLiB6IG8uby4xJDAiBgNV
+BAsTG0NlbnRydW0gQ2VydHlmaWthY2ppIFNpZ25ldDEhMB8GA1UEAxMYQ0MgU2ln
+bmV0IC0gT0NTUCBLbGFzYSAyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCo
+VCsaBStblXQYVNthe3dvaCrfvKpPXngh4almm988iIlEv9CVTaAdCfaJNihvA+Vs
+Qw8++ix1VqteMQE474/MV/YaXigP0Zr0QB+g+/7PWVlv+5U9Gzp9+Xx4DJay8AoI
+iB7Iy5Qf9iZiHm5BiPRIuUXT4ZRbZRYPh0/76vgRsQIDAQABo4IBkjCCAY4wDgYD
+VR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMJMEEGA1UdHwQ6MDgwNqA0
+oDKGMGh0dHA6Ly93d3cuc2lnbmV0LnBsL3JlcG96eXRvcml1bS9jcmwva2xhc2Ey
+LmNybDCB2AYDVR0gBIHQMIHNMIHKBg4rBgEEAb4/AoFICgwBADCBtzBsBggrBgEF
+BQcCAjBgGl5DZXJ0eWZpa2F0IHd5ZGFueSB6Z29kbmllIHogZG9rdW1lbnRlbSAi
+UG9saXR5a2EgQ2VydHlmaWthY2ppIC0gQ2VydHlmaWthdHkgcmVzcG9uZGVyb3cg
+T0NTUCIuMEcGCCsGAQUFBwIBFjtodHRwOi8vd3d3LnNpZ25ldC5wbC9yZXBvenl0
+b3JpdW0vZG9rdW1lbnR5L3BjX29jc3BfMV8wLnBkZjAfBgNVHSMEGDAWgBS7RQZS
+C8uBzSlUs7x8QUzNBw6MJTAdBgNVHQ4EFgQUKEVrOY7cEHvsVgvoyZdytlbtgwEw
+CQYDVR0TBAIwADANBgkqhkiG9w0BAQUFAAOCAQEAQrRg5MV6dxr0HU2IsLInxhvt
+iUVmSFkIUsBCjzLoewOXA16d2oDyHhI/eE+VgAsp+2ANjZu4xRteHIHoYMsN218M
+eD2MLRsYS0U9xxAFK9gDj/KscPbrrdoqLvtPSMhUb4adJS9HLhvUe6BicvBf3A71
+iCNe431axGNDWKnpuj2KUpj4CFHYsWCXky847YtTXDjri9NIwJJauazsrSjK+oXp
+ngRS506mdQ7vWrtApkh8zhhWp7duCkjcCo1O8JxqYr2qEW1fXmgOISe010v2mmuv
+hHxPyVwoAU4KkOw0nbXZn53yak0is5+XmAjh0wWue44AssHrjC9nUh3mkLt6eQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEezCCA2OgAwIBAgIEP4vnLzANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJQ
+TDEfMB0GA1UEChMWVFAgSW50ZXJuZXQgU3AuIHogby5vLjEfMB0GA1UEAxMWQ0Mg
+U2lnbmV0IC0gQ0EgS2xhc2EgMzEXMBUGA1UEBRMOTnVtZXIgd3Bpc3U6IDQwHhcN
+MDMxMDE0MTIwODAwWhcNMDgwNDI4MTA1MDU1WjB3MQswCQYDVQQGEwJQTDEfMB0G
+A1UEChMWVFAgSW50ZXJuZXQgU3AuIHogby5vLjEkMCIGA1UECxMbQ2VudHJ1bSBD
+ZXJ0eWZpa2FjamkgU2lnbmV0MSEwHwYDVQQDExhDQyBTaWduZXQgLSBPQ1NQIEts
+YXNhIDMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM/9GwvARNuCVN+PqZmO
+4FqH8vTqhenUyqRkmAVT4YhLu0a9AXeLAYVDu+NTkYzsAUMAfu55rIKHNLlm6WbF
+KvLiKKz4p4pbUr+ToPcwl/TDotidloUdBAxDg0SL+PmQqACZDe3seJho2IYf2vDL
+/G4TLMbKmNB0mlWFuN0f4fJNAgMBAAGjggGgMIIBnDAOBgNVHQ8BAf8EBAMCB4Aw
+EwYDVR0lBAwwCgYIKwYBBQUHAwkwTwYDVR0fBEgwRjBEoEKgQIY+aHR0cDovL3d3
+dy5zaWduZXQucGwva3dhbGlmaWtvd2FuZS9yZXBvenl0b3JpdW0vY3JsL2tsYXNh
+My5jcmwwgdgGA1UdIASB0DCBzTCBygYOKwYBBAG+PwKCLAoCAQAwgbcwbAYIKwYB
+BQUHAgIwYBpeQ2VydHlmaWthdCB3eWRhbnkgemdvZG5pZSB6IGRva3VtZW50ZW0g
+IlBvbGl0eWthIENlcnR5ZmlrYWNqaSAtIENlcnR5ZmlrYXR5IHJlc3BvbmRlcm93
+IE9DU1AiLjBHBggrBgEFBQcCARY7aHR0cDovL3d3dy5zaWduZXQucGwvcmVwb3p5
+dG9yaXVtL2Rva3VtZW50eS9wY19vY3NwXzFfMC5wZGYwHwYDVR0jBBgwFoAUe2PM
+GZB6tM62O559bRUnUND5SbkwHQYDVR0OBBYEFG4jnCMvBALRQXtmDn9TyXQ/EKP+
+MAkGA1UdEwQCMAAwDQYJKoZIhvcNAQEFBQADggEBACXrKG5Def5lpRwmZom3UEDq
+bl7y4U3qomG4B+ok2FVZGgPZti+ZgvrenPj7PtbYCUBPsCSTNrznKinoT3gD9lQQ
+xkEHwdc6VD1GlFp+qI64u0+wS9Epatrdf7aBnizrOIB4LJd4E2TWQ6trspetjMIU
+upyWls1BmYUxB91R7QkTiAUSNZ87s3auhZuG4f0V0JLVCcg2rn7AN1rfMkgxCbHk
+GxiQbYWFljl6aatxR3odnnzVUe1I8uoY2JXpmmUcOG4dNGuQYziyKG3mtXCQWvug
+5qi9Mf3KUh1oSTKx6HfLjjNl1+wMB5Mdb8LF0XyZLdJM9yIZh7SBRsYm9QiXevY=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFGjCCBAKgAwIBAgIEPL7eEDANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJQTDEfMB0GA1UE
+ChMWVFAgSW50ZXJuZXQgU3AuIHogby5vLjEkMCIGA1UECxMbQ2VudHJ1bSBDZXJ0eWZpa2Fjamkg
+U2lnbmV0MRswGQYDVQQDExJDQyBTaWduZXQgLSBSb290Q0EwHhcNMDIwNDE4MTQ1NDA4WhcNMjYw
+OTIxMTU0MjE5WjB2MQswCQYDVQQGEwJQTDEfMB0GA1UEChMWVFAgSW50ZXJuZXQgU3AuIHogby5v
+LjEkMCIGA1UECxMbQ2VudHJ1bSBDZXJ0eWZpa2FjamkgU2lnbmV0MSAwHgYDVQQDExdDQyBTaWdu
+ZXQgLSBQQ0EgS2xhc2EgMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM7BrBlbN5ma
+M5eg0BOTqoZ+9NBDvU8Lm5rTdrMswFTCathzpVVLK/JD4K3+4oCZ9SRAspEXE4gvwb08ASY6w5s+
+HpRkeJw8YzMFR5kDZD5adgnCAy4vDfIXYZgppXPaTQ8wnfUZ7BZ7Zfa7QBemUIcJIzJBB0UqgtxW
+Ceol9IekpBRVmuuSA6QG0Jkm+pGDJ05yj2eQG8jTcBENM7sVA8rGRMyFA4skSZ+D0OG6FS2xC1i9
+JyN0ag1yII/LPx8HK5J4W9MaPRNjAEeaa2qI9EpchwrOxnyVbQfSedCG1VRJfAsE/9tT9CMUPZ3x
+W20QjQcSZJqVcmGW9gVsXKQOVLsCAwEAAaOCAbMwggGvMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P
+AQH/BAQDAgEGMIIBBAYDVR0gBIH8MIH5MIH2Bg0rBgEEAb4/AgEKAQEBMIHkMIGaBggrBgEFBQcC
+AjCBjRqBikNlcnR5ZmlrYXQgd3lzdGF3aW9ueSB6Z29kbmllIHogZG9rdW1lbnRlbTogIlBvbGl0
+eWthIENlcnR5ZmlrYWNqaSBkbGEgUm9vdENBIi4gQ2VydHlmaWthdCB3eXN0YXdpb255IHByemV6
+IFJvb3RDQSB3IGhpZXJhcmNoaWkgQ0MgU2lnbmV0LjBFBggrBgEFBQcCARY5aHR0cDovL3d3dy5z
+aWduZXQucGwvcmVwb3p5dG9yaXVtL2Rva3VtZW50eS9wY19yb290Y2EudHh0MEQGA1UdHwQ9MDsw
+OaA3oDWGM2h0dHA6Ly93d3cuc2lnbmV0LnBsL3JlcG96eXRvcml1bS9yb290Y2Evcm9vdGNhLmNy
+bDAfBgNVHSMEGDAWgBTAm8UjDQLhpk5Iax8A6eOaFBuxrzAdBgNVHQ4EFgQUwGxGyl2CfpYHRonE
+82AVXO08kMIwDQYJKoZIhvcNAQEFBQADggEBABp1TAUsa+BeVWg4cjowc8yTJ5XN3GvN96GObMkx
+UGY7U9kVrLI71xBgoNVyzXTiMNDBvjh7vdPWjpl5SDiRpnnKiOFXA43HvNWzUaOkTu1mxjJsZsan
+ot1Xt6j0ZDC+03FjLHdYMyM9kSWp6afb4980EPYZCcSzgM5TOGfJmNii5Tq468VFKrX+52Aou1G2
+2Ohu+EEOlOrG7ylKv1hHUJJCjwN0ZVEIn1nDbrU9FeGCz8J9ihVUvnENEBbBkU37PWqWuHitKQDV
+tcwTwJJdR8cmKq3NmkwAm9fPacidQLpaw0WkuGrS+fEDhu1Nhy9xELP6NA9GRTCNxm/dXlcwnmY=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFGjCCBAKgAwIBAgIEPV0tNDANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJQTDEfMB0GA1UE
+ChMWVFAgSW50ZXJuZXQgU3AuIHogby5vLjEkMCIGA1UECxMbQ2VudHJ1bSBDZXJ0eWZpa2Fjamkg
+U2lnbmV0MRswGQYDVQQDExJDQyBTaWduZXQgLSBSb290Q0EwHhcNMDIwODE2MTY0OTU2WhcNMjYw
+OTIxMTU0MjE5WjB2MQswCQYDVQQGEwJQTDEfMB0GA1UEChMWVFAgSW50ZXJuZXQgU3AuIHogby5v
+LjEkMCIGA1UECxMbQ2VudHJ1bSBDZXJ0eWZpa2FjamkgU2lnbmV0MSAwHgYDVQQDExdDQyBTaWdu
+ZXQgLSBQQ0EgS2xhc2EgMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALN3LanJtdue
+Ne6geWUTFENa+lEuzqELcoqhYB+a/tJcPEkc6TX/bYPzalRRjqs+quMP6KZTU0DixOrV+K7iWaqA
+iQ913HX5IBLmKDCrTVW/ZvSDpiBKbxlHfSNuJxAuVT6HdbzK7yAW38ssX+yS2tZYHZ5FhZcfqzPE
+OpO94mAKcBUhk6T/ki0evXX/ZvvktwmF3hKattzwtM4JMLurAEl8SInyEYULw5JdlfcBez2Tg6Db
+w34hA1A+ckTwhxzecrB8TUe2BnQKOs9vr2cCACpFFcOmPkM0Drtjctr1QHm1tYSqRFRf9VcV5tfC
+3P8QqoK4ONjtLPHc9x5NE1uK/FMCAwEAAaOCAbMwggGvMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P
+AQH/BAQDAgEGMIIBBAYDVR0gBIH8MIH5MIH2Bg0rBgEEAb4/AgEKAQECMIHkMIGaBggrBgEFBQcC
+AjCBjRqBikNlcnR5ZmlrYXQgd3lzdGF3aW9ueSB6Z29kbmllIHogZG9rdW1lbnRlbTogIlBvbGl0
+eWthIENlcnR5ZmlrYWNqaSBkbGEgUm9vdENBIi4gQ2VydHlmaWthdCB3eXN0YXdpb255IHByemV6
+IFJvb3RDQSB3IGhpZXJhcmNoaWkgQ0MgU2lnbmV0LjBFBggrBgEFBQcCARY5aHR0cDovL3d3dy5z
+aWduZXQucGwvcmVwb3p5dG9yaXVtL2Rva3VtZW50eS9wY19yb290Y2EudHh0MEQGA1UdHwQ9MDsw
+OaA3oDWGM2h0dHA6Ly93d3cuc2lnbmV0LnBsL3JlcG96eXRvcml1bS9yb290Y2Evcm9vdGNhLmNy
+bDAfBgNVHSMEGDAWgBTAm8UjDQLhpk5Iax8A6eOaFBuxrzAdBgNVHQ4EFgQUXvthcPHlH5BgGhlM
+ErJNXWlhlgAwDQYJKoZIhvcNAQEFBQADggEBACIce95Mvn710KCAISA0CuHD4aznTU6pLoCDShW4
+7OR+GTpJUm1coTcUqlBHV9mra4VFrBcBuOkHZoBLq/jmE0QJWnpSEULDcH9J3mF0nqO9SM+mWyJG
+dsJF/XU/7smummgjMNQXwzQTtWORF+6v5KUbWX85anO2wR+M6YTBWC55zWpWi4RG3vkHFs5Ze2oF
+JTlpuxw9ZgxTnWlwI9QR2MvEhYIUMKMOWxw1nt0kKj+5TCNQQGh/VJJ1dsiroGh/io1DOcePEhKz
+1Ag52y6Wf0nJJB9yk0sFakqZH18F7eQecQImgZyyeRtsG95leNugB3BXWCW+KxwiBrtQTXv4dTE=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEzzCCA7egAwIBAgIEO6ocGTANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJQTDEfMB0GA1UE
+ChMWVFAgSW50ZXJuZXQgU3AuIHogby5vLjEkMCIGA1UECxMbQ2VudHJ1bSBDZXJ0eWZpa2Fjamkg
+U2lnbmV0MRswGQYDVQQDExJDQyBTaWduZXQgLSBSb290Q0EwHhcNMDEwOTIwMTY0MjE5WhcNMjYw
+OTIxMTU0MjE5WjBxMQswCQYDVQQGEwJQTDEfMB0GA1UEChMWVFAgSW50ZXJuZXQgU3AuIHogby5v
+LjEkMCIGA1UECxMbQ2VudHJ1bSBDZXJ0eWZpa2FjamkgU2lnbmV0MRswGQYDVQQDExJDQyBTaWdu
+ZXQgLSBSb290Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrr2vydnNpELfGW3Ks
+ARiDhJvwDtUe4AbWev+OfMc3+vA29nX8ZmIwno3gmItjo5DbUCCRiCMq5c9epcGu+kg4a3BJChVX
+REl8gVh0ST15rr3RKrSc4VgsvQzl0ZUraeQLl8JoRT5PLsUj3qwF78jUCQVckiiLVcnGfZtFCm+D
+CJXliQBDMB9XFAUEiO/DtEBs0B7wJGx7lgJeJpQUcGiaOPjcJDYOk7rNAYmmD2gWeSlepufO8luU
+YG/YDxTC4mqhRqfa4MnVO5dqy+ICj2UvUpHbZDB0KfGRibgBYeQP1kuqgIzJN4UqknVAJb0aMBSP
+l+9k2fAUdchx1njlbdcbAgMBAAGjggFtMIIBaTAPBgNVHRMBAf8EBTADAQH/MIIBBAYDVR0gBIH8
+MIH5MIH2Bg0rBgEEAb4/AgEKAQEAMIHkMIGaBggrBgEFBQcCAjCBjRqBikNlcnR5ZmlrYXQgd3lz
+dGF3aW9ueSB6Z29kbmllIHogZG9rdW1lbnRlbTogIlBvbGl0eWthIENlcnR5ZmlrYWNqaSBkbGEg
+Um9vdENBIi4gQ2VydHlmaWthdCB3eXN0YXdpb255IHByemV6IFJvb3RDQSB3IGhpZXJhcmNoaWkg
+Q0MgU2lnbmV0LjBFBggrBgEFBQcCARY5aHR0cDovL3d3dy5zaWduZXQucGwvcmVwb3p5dG9yaXVt
+L2Rva3VtZW50eS9wY19yb290Y2EudHh0MB0GA1UdDgQWBBTAm8UjDQLhpk5Iax8A6eOaFBuxrzAf
+BgNVHSMEGDAWgBTAm8UjDQLhpk5Iax8A6eOaFBuxrzAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcN
+AQEFBQADggEBAGnY5QmYqnnO9OqFOWZxxb25UHRnaRF6IV9aaGit5BZufZj2Tq3v8L3SgE34GOoI
+cdRMMG5JEpEU4mN/Ef3oY6Eo+7HfqaPHI4KFmbDSPiK5s+wmf+bQSm0Yq5/h4ZOdcAESlLQeLSt1
+CQk2JoKQJ6pyAf6xJBgWEIlm4RXE4J3324PUiOp83kW6MDvaa1xY976WyInr4rwoLgxVl11LZeKW
+ha0RJJxJgw/NyWpKG7LWCm1fglF8JH51vZNndGYq1iKtfnrIOvLZq6bzaCiZm1EurD8HE6P7pmAB
+KK6o3C2OXlNfNIgwkDN/cDqk5TYsTkrpfriJPdxXBH8hQOkW89g=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIID/TCCA2agAwIBAgIEP4/gkTANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJQTDEfMB0GA1UE
+ChMWVFAgSW50ZXJuZXQgU3AuIHogby5vLjEkMCIGA1UECxMbQ2VudHJ1bSBDZXJ0eWZpa2Fjamkg
+U2lnbmV0MR8wHQYDVQQDExZDQyBTaWduZXQgLSBDQSBLbGFzYSAxMB4XDTAzMTAxNzEyMjkwMloX
+DTExMDkyMzExMTgxN1owdjELMAkGA1UEBhMCUEwxHzAdBgNVBAoTFlRQIEludGVybmV0IFNwLiB6
+IG8uby4xJDAiBgNVBAsTG0NlbnRydW0gQ2VydHlmaWthY2ppIFNpZ25ldDEgMB4GA1UEAxMXQ0Mg
+U2lnbmV0IC0gVFNBIEtsYXNhIDEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOJYrISEtSsd
+uHajROh5/n7NGrkpYTT9NEaPe9+ucuQ37KxIbfJwXJjgUc1dw4wCkcQ12FJarD1X6mSQ4cfN/60v
+LfKI5ZD4nhJTMKlAj1pX9ScQ/MuyvKStCbn5WTkjPhjRAM0tdwXSnzuTEunfw0Oup559y3Iqxg1c
+ExflB6cfAgMBAAGjggGXMIIBkzBBBgNVHR8EOjA4MDagNKAyhjBodHRwOi8vd3d3LnNpZ25ldC5w
+bC9yZXBvenl0b3JpdW0vY3JsL2tsYXNhMS5jcmwwDgYDVR0PAQH/BAQDAgeAMBYGA1UdJQEB/wQM
+MAoGCCsGAQUFBwMIMIHaBgNVHSAEgdIwgc8wgcwGDSsGAQQBvj8CZAoRAgEwgbowbwYIKwYBBQUH
+AgIwYxphQ2VydHlmaWthdCB3eXN0YXdpb255IHpnb2RuaWUgeiBkb2t1bWVudGVtICJQb2xpdHlr
+YSBDZXJ0eWZpa2FjamkgQ0MgU2lnbmV0IC0gWm5ha293YW5pZSBjemFzZW0iLjBHBggrBgEFBQcC
+ARY7aHR0cDovL3d3dy5zaWduZXQucGwvcmVwb3p5dG9yaXVtL2Rva3VtZW50eS9wY190c2ExXzJf
+MS5wZGYwHwYDVR0jBBgwFoAUw4Me1Vl3VPtN+1dH+cQjXNHnieMwHQYDVR0OBBYEFJdDwEqtcavO
+Yd9u9tej53vWXwNBMAkGA1UdEwQCMAAwDQYJKoZIhvcNAQEFBQADgYEAnpiQkqLCJQYXUrqMHUEz
++z3rOqS0XzSFnVVLhkVssvXc8S3FkJIiQTUrkScjI4CToCzujj3EyfNxH6yiLlMbskF8I31JxIeB
+vueqV+s+o76CZm3ycu9hb0I4lswuxoT+q5ZzPR8Irrb51rZXlolR+7KtwMg4sFDJZ8RNgOf7tbA=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEFTCCA36gAwIBAgIBADANBgkqhkiG9w0BAQQFADCBvjELMAkGA1UEBhMCVVMx
+EDAOBgNVBAgTB0luZGlhbmExFTATBgNVBAcTDEluZGlhbmFwb2xpczEoMCYGA1UE
+ChMfU29mdHdhcmUgaW4gdGhlIFB1YmxpYyBJbnRlcmVzdDETMBEGA1UECxMKaG9z
+dG1hc3RlcjEgMB4GA1UEAxMXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxJTAjBgkq
+hkiG9w0BCQEWFmhvc3RtYXN0ZXJAc3BpLWluYy5vcmcwHhcNMDMwMTE1MTYyOTE3
+WhcNMDcwMTE0MTYyOTE3WjCBvjELMAkGA1UEBhMCVVMxEDAOBgNVBAgTB0luZGlh
+bmExFTATBgNVBAcTDEluZGlhbmFwb2xpczEoMCYGA1UEChMfU29mdHdhcmUgaW4g
+dGhlIFB1YmxpYyBJbnRlcmVzdDETMBEGA1UECxMKaG9zdG1hc3RlcjEgMB4GA1UE
+AxMXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxJTAjBgkqhkiG9w0BCQEWFmhvc3Rt
+YXN0ZXJAc3BpLWluYy5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPB6
+rdoiLR3RodtM22LMcfwfqb5OrJNl7fwmvskgF7yP6sdD2bOfDIXhg9852jhY8/kL
+VOFe1ELAL2OyN4RAxk0rliZQVgeTgqvgkOVIBbNwgnjN6mqtuWzFiPL+NXQExq40
+I3whM+4lEiwSHaV+MYxWanMdhc+kImT50LKfkxcdAgMBAAGjggEfMIIBGzAdBgNV
+HQ4EFgQUB63oQR1/vda/G4F6P4xLiN4E0vowgesGA1UdIwSB4zCB4IAUB63oQR1/
+vda/G4F6P4xLiN4E0vqhgcSkgcEwgb4xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdJ
+bmRpYW5hMRUwEwYDVQQHEwxJbmRpYW5hcG9saXMxKDAmBgNVBAoTH1NvZnR3YXJl
+IGluIHRoZSBQdWJsaWMgSW50ZXJlc3QxEzARBgNVBAsTCmhvc3RtYXN0ZXIxIDAe
+BgNVBAMTF0NlcnRpZmljYXRpb24gQXV0aG9yaXR5MSUwIwYJKoZIhvcNAQkBFhZo
+b3N0bWFzdGVyQHNwaS1pbmMub3JnggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcN
+AQEEBQADgYEAm/Abn8c2y1nO3fgpAIslxvi9iNBZDhQtJ0VQZY6wgSfANyDOR4DW
+iexO/AlorB49KnkFS7TjCAoLOZhcg5FaNiKnlstMI5krQmau1Qnb/vGSNsE/UGms
+1ts+QYPUs0KmGEAFUri2XzLy+aQo9Kw74VBvqnxvaaMeY5yMcKNOieY=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIIDjCCBfagAwIBAgIJAOiOtsn4KhQoMA0GCSqGSIb3DQEBBQUAMIG8MQswCQYD
+VQQGEwJVUzEQMA4GA1UECBMHSW5kaWFuYTEVMBMGA1UEBxMMSW5kaWFuYXBvbGlz
+MSgwJgYDVQQKEx9Tb2Z0d2FyZSBpbiB0aGUgUHVibGljIEludGVyZXN0MRMwEQYD
+VQQLEwpob3N0bWFzdGVyMR4wHAYDVQQDExVDZXJ0aWZpY2F0ZSBBdXRob3JpdHkx
+JTAjBgkqhkiG9w0BCQEWFmhvc3RtYXN0ZXJAc3BpLWluYy5vcmcwHhcNMDgwNTEz
+MDgwNzU2WhcNMTgwNTExMDgwNzU2WjCBvDELMAkGA1UEBhMCVVMxEDAOBgNVBAgT
+B0luZGlhbmExFTATBgNVBAcTDEluZGlhbmFwb2xpczEoMCYGA1UEChMfU29mdHdh
+cmUgaW4gdGhlIFB1YmxpYyBJbnRlcmVzdDETMBEGA1UECxMKaG9zdG1hc3RlcjEe
+MBwGA1UEAxMVQ2VydGlmaWNhdGUgQXV0aG9yaXR5MSUwIwYJKoZIhvcNAQkBFhZo
+b3N0bWFzdGVyQHNwaS1pbmMub3JnMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
+CgKCAgEA3DbmR0LCxFF1KYdAw9iOIQbSGE7r7yC9kDyFEBOMKVuUY/b0LfEGQpG5
+GcRCaQi/izZF6igFM0lIoCdDkzWKQdh4s/Dvs24t3dHLfer0dSbTPpA67tfnLAS1
+fOH1fMVO73e9XKKTM5LOfYFIz2u1IiwIg/3T1c87Lf21SZBb9q1NE8re06adU1Fx
+Y0b4ShZcmO4tbZoWoXaQ4mBDmdaJ1mwuepiyCwMs43pPx93jzONKao15Uvr0wa8u
+jyoIyxspgpJyQ7zOiKmqp4pRQ1WFmjcDeJPI8L20QcgHQprLNZd6ioFl3h1UCAHx
+ZFy3FxpRvB7DWYd2GBaY7r/2Z4GLBjXFS21ZGcfSxki+bhQog0oQnBv1b7ypjvVp
+/rLBVcznFMn5WxRTUQfqzj3kTygfPGEJ1zPSbqdu1McTCW9rXRTunYkbpWry9vjQ
+co7qch8vNGopCsUK7BxAhRL3pqXTT63AhYxMfHMgzFMY8bJYTAH1v+pk1Vw5xc5s
+zFNaVrpBDyXfa1C2x4qgvQLCxTtVpbJkIoRRKFauMe5e+wsWTUYFkYBE7axt8Feo
++uthSKDLG7Mfjs3FIXcDhB78rKNDCGOM7fkn77SwXWfWT+3Qiz5dW8mRvZYChD3F
+TbxCP3T9PF2sXEg2XocxLxhsxGjuoYvJWdAY4wCAs1QnLpnwFVMCAwEAAaOCAg8w
+ggILMB0GA1UdDgQWBBQ0cdE41xU2g0dr1zdkQjuOjVKdqzCB8QYDVR0jBIHpMIHm
+gBQ0cdE41xU2g0dr1zdkQjuOjVKdq6GBwqSBvzCBvDELMAkGA1UEBhMCVVMxEDAO
+BgNVBAgTB0luZGlhbmExFTATBgNVBAcTDEluZGlhbmFwb2xpczEoMCYGA1UEChMf
+U29mdHdhcmUgaW4gdGhlIFB1YmxpYyBJbnRlcmVzdDETMBEGA1UECxMKaG9zdG1h
+c3RlcjEeMBwGA1UEAxMVQ2VydGlmaWNhdGUgQXV0aG9yaXR5MSUwIwYJKoZIhvcN
+AQkBFhZob3N0bWFzdGVyQHNwaS1pbmMub3JnggkA6I62yfgqFCgwDwYDVR0TAQH/
+BAUwAwEB/zARBglghkgBhvhCAQEEBAMCAAcwCQYDVR0SBAIwADAuBglghkgBhvhC
+AQ0EIRYfU29mdHdhcmUgaW4gdGhlIFB1YmxpYyBJbnRlcmVzdDAwBglghkgBhvhC
+AQQEIxYhaHR0cHM6Ly9jYS5zcGktaW5jLm9yZy9jYS1jcmwucGVtMDIGCWCGSAGG
++EIBAwQlFiNodHRwczovL2NhLnNwaS1pbmMub3JnL2NlcnQtY3JsLnBlbTAhBgNV
+HREEGjAYgRZob3N0bWFzdGVyQHNwaS1pbmMub3JnMA4GA1UdDwEB/wQEAwIBBjAN
+BgkqhkiG9w0BAQUFAAOCAgEAtM294LnqsgMrfjLp3nI/yUuCXp3ir1UJogxU6M8Y
+PCggHam7AwIvUjki+RfPrWeQswN/2BXja367m1YBrzXU2rnHZxeb1NUON7MgQS4M
+AcRb+WU+wmHo0vBqlXDDxm/VNaSsWXLhid+hoJ0kvSl56WEq2dMeyUakCHhBknIP
+qxR17QnwovBc78MKYiC3wihmrkwvLo9FYyaW8O4x5otVm6o6+YI5HYg84gd1GuEP
+sTC8cTLSOv76oYnzQyzWcsR5pxVIBcDYLXIC48s9Fmq6ybgREOJJhcyWR2AFJS7v
+dVkz9UcZFu/abF8HyKZQth3LZjQl/GaD68W2MEH4RkRiqMEMVObqTFoo5q7Gt/5/
+O5aoLu7HaD7dAD0prypjq1/uSSotxdz70cbT0ZdWUoa2lOvUYFG3/B6bzAKb1B+P
++UqPti4oOxfMxaYF49LTtcYDyeFIQpvLP+QX4P4NAZUJurgNceQJcHdC2E3hQqlg
+g9cXiUPS1N2nGLar1CQlh7XU4vwuImm9rWgs/3K1mKoGnOcqarihk3bOsPN/nOHg
+T7jYhkalMwIsJWE3KpLIrIF0aGOHM3a9BX9e1dUCbb2v/ypaqknsmHlHU5H2DjRa
+yaXG67Ljxay2oHA1u8hRadDytaIybrw/oDc5fHE2pgXfDBLkFqfF1stjo5VwP+YE
+o2A=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEc
+MBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2Vj
+IFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENB
+IDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5MjM1OTAwWjBxMQswCQYDVQQGEwJE
+RTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxl
+U2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290
+IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEU
+ha88EOQ5bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhC
+QN/Po7qCWWqSG6wcmtoIKyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1Mjwr
+rFDa1sPeg5TKqAyZMg4ISFZbavva4VhYAUlfckE8FQYBjl2tqriTtM2e66foai1S
+NNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aKSe5TBY8ZTNXeWHmb0moc
+QqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTVjlsB9WoH
+txa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAP
+BgNVHRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOC
+AQEAlGRZrTlk5ynrE/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756Abrsp
+tJh6sTtU6zkXR34ajgv8HzFZMQSyzhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpa
+IzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8rZ7/gFnkm0W09juwzTkZmDLl
+6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4Gdyd1Lx+4ivn+
+xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU
+Cm26OWMohpLzGITY+9HPBVZkVw==
+-----END CERTIFICATE-----
+
+-----BEGIN CERTIFICATE-----
+MIIE3jCCA8agAwIBAgICAwEwDQYJKoZIhvcNAQEFBQAwYzELMAkGA1UEBhMCVVMx
+ITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g
+RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMTYw
+MTU0MzdaFw0yNjExMTYwMTU0MzdaMIHKMQswCQYDVQQGEwJVUzEQMA4GA1UECBMH
+QXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTEaMBgGA1UEChMRR29EYWRkeS5j
+b20sIEluYy4xMzAxBgNVBAsTKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5j
+b20vcmVwb3NpdG9yeTEwMC4GA1UEAxMnR28gRGFkZHkgU2VjdXJlIENlcnRpZmlj
+YXRpb24gQXV0aG9yaXR5MREwDwYDVQQFEwgwNzk2OTI4NzCCASIwDQYJKoZIhvcN
+AQEBBQADggEPADCCAQoCggEBAMQt1RWMnCZM7DI161+4WQFapmGBWTtwY6vj3D3H
+KrjJM9N55DrtPDAjhI6zMBS2sofDPZVUBJ7fmd0LJR4h3mUpfjWoqVTr9vcyOdQm
+VZWt7/v+WIbXnvQAjYwqDL1CBM6nPwT27oDyqu9SoWlm2r4arV3aLGbqGmu75RpR
+SgAvSMeYddi5Kcju+GZtCpyz8/x4fKL4o/K1w/O5epHBp+YlLpyo7RJlbmr2EkRT
+cDCVw5wrWCs9CHRK8r5RsL+H0EwnWGu1NcWdrxcx+AuP7q2BNgWJCJjPOq8lh8BJ
+6qf9Z/dFjpfMFDniNoW1fho3/Rb2cRGadDAW/hOUoz+EDU8CAwEAAaOCATIwggEu
+MB0GA1UdDgQWBBT9rGEyk2xF1uLuhV+auud2mWjM5zAfBgNVHSMEGDAWgBTSxLDS
+kdRMEXGzYcs9of7dqGrU4zASBgNVHRMBAf8ECDAGAQH/AgEAMDMGCCsGAQUFBwEB
+BCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZ29kYWRkeS5jb20wRgYDVR0f
+BD8wPTA7oDmgN4Y1aHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNvbS9yZXBv
+c2l0b3J5L2dkcm9vdC5jcmwwSwYDVR0gBEQwQjBABgRVHSAAMDgwNgYIKwYBBQUH
+AgEWKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeTAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBANKGwOy9+aG2Z+5mC6IG
+OgRQjhVyrEp0lVPLN8tESe8HkGsz2ZbwlFalEzAFPIUyIXvJxwqoJKSQ3kbTJSMU
+A2fCENZvD117esyfxVgqwcSeIaha86ykRvOe5GPLL5CkKSkB2XIsKd83ASe8T+5o
+0yGPwLPk9Qnt0hCqU7S+8MxZC9Y7lhyVJEnfzuz9p0iRFEUOOjZv2kWzRaJBydTX
+RE4+uXR21aITVSzGh6O1mawGhId/dQb8vxRMDsxuxN89txJx9OjxUUAiKEngHUuH
+qDTMBqLdElrRhjZkAzVvb3du6/KFUJheqwNTrZEjYx8WnM25sgVjOuH0aBsXBTWV
+U+4=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIE+zCCBGSgAwIBAgICAQ0wDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1Zh
+bGlDZXJ0IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIElu
+Yy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24g
+QXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAe
+BgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTA0MDYyOTE3MDYyMFoX
+DTI0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBE
+YWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3MgMiBDZXJ0
+aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggENADCCAQgC
+ggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv
+2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+q
+N1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiO
+r18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lN
+f4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+YihfukEH
+U1jPEX44dMX4/7VpkI+EdOqXG68CAQOjggHhMIIB3TAdBgNVHQ4EFgQU0sSw0pHU
+TBFxs2HLPaH+3ahq1OMwgdIGA1UdIwSByjCBx6GBwaSBvjCBuzEkMCIGA1UEBxMb
+VmFsaUNlcnQgVmFsaWRhdGlvbiBOZXR3b3JrMRcwFQYDVQQKEw5WYWxpQ2VydCwg
+SW5jLjE1MDMGA1UECxMsVmFsaUNlcnQgQ2xhc3MgMiBQb2xpY3kgVmFsaWRhdGlv
+biBBdXRob3JpdHkxITAfBgNVBAMTGGh0dHA6Ly93d3cudmFsaWNlcnQuY29tLzEg
+MB4GCSqGSIb3DQEJARYRaW5mb0B2YWxpY2VydC5jb22CAQEwDwYDVR0TAQH/BAUw
+AwEB/zAzBggrBgEFBQcBAQQnMCUwIwYIKwYBBQUHMAGGF2h0dHA6Ly9vY3NwLmdv
+ZGFkZHkuY29tMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9jZXJ0aWZpY2F0ZXMu
+Z29kYWRkeS5jb20vcmVwb3NpdG9yeS9yb290LmNybDBLBgNVHSAERDBCMEAGBFUd
+IAAwODA2BggrBgEFBQcCARYqaHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNv
+bS9yZXBvc2l0b3J5MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOBgQC1
+QPmnHfbq/qQaQlpE9xXUhUaJwL6e4+PrxeNYiY+Sn1eocSxI0YGyeR+sBjUZsE4O
+WBsUs5iB0QQeyAfJg594RAoYC5jcdnplDQ1tgMQLARzLrUc+cb53S8wGd9D0Vmsf
+SxOaFIqII6hR8INMqzW/Rn453HWkrugp++85j09VZw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----\r
+MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0\r
+IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz\r
+BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y\r
+aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG\r
+9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMTk1NFoXDTE5MDYy\r
+NjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y\r
+azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs\r
+YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw\r
+Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl\r
+cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOOnHK5avIWZJV16vY\r
+dA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVCCSRrCl6zfN1SLUzm1NZ9\r
+WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7RfZHM047QS\r
+v4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9v\r
+UJSZSWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTu\r
+IYEZoDJJKPTEjlbVUjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwC\r
+W/POuZ6lcg5Ktz885hZo+L7tdEy8W9ViH0Pd\r
+-----END CERTIFICATE-----\r
--- /dev/null
+This directory contains certificate/public keys/private keys used to create unittests.
+Passwort to private keys is "1234" or "secret".
\ No newline at end of file
--- /dev/null
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ c7:4a:82:f6:9d:1b:f6:7e
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=PL, ST=Maz, O=Samsung, OU=SPRC, CN=Samsung/emailAddress=samsung@samsung.com
+ Validity
+ Not Before: Oct 5 12:00:51 2011 GMT
+ Not After : Oct 2 12:00:51 2021 GMT
+ Subject: C=PL, ST=MAZ, L=Leg, O=Sam, OU=SPRC, CN=Filip/emailAddress=filip@samsung.com
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public Key: (1024 bit)
+ Modulus (1024 bit):
+ 00:d2:fe:c4:b4:c1:74:82:6f:7e:28:8c:df:1b:58:
+ 57:78:3e:5f:5e:4c:b1:e1:d7:c5:0d:1a:c3:e9:2e:
+ 9a:78:8a:d7:5f:b9:cf:ce:83:2a:9a:4a:80:f0:07:
+ 35:61:11:60:15:2c:24:f1:7b:15:1a:e0:d7:2f:6b:
+ ee:35:35:b9:16:e1:10:ac:17:37:86:b3:49:2d:a6:
+ ed:7e:f1:0f:af:d1:01:0e:1a:a5:45:da:b4:24:82:
+ 29:73:0c:5f:e8:3b:9e:85:c7:0f:6f:1b:53:80:fa:
+ a7:50:77:7c:8e:01:5d:84:a8:b3:41:3e:b1:18:07:
+ d2:b9:18:5c:9f:7e:b6:a4:49
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ Netscape Comment:
+ OpenSSL Generated Certificate
+ X509v3 Subject Key Identifier:
+ 7B:2C:B7:89:5E:F9:2A:D3:A4:A4:F1:5D:EA:69:D1:F5:D1:46:64:CC
+ X509v3 Authority Key Identifier:
+ keyid:82:08:7F:DB:00:02:86:E8:53:2A:A5:FA:58:AE:67:7F:14:38:C8:60
+
+ Signature Algorithm: sha1WithRSAEncryption
+ 0e:db:f4:08:1a:d0:d5:00:8c:1f:d8:ca:16:3a:52:a6:ae:f3:
+ 14:a3:17:41:e5:6d:6f:f6:62:7b:cd:b7:ff:fc:28:89:c8:3c:
+ 93:19:cf:e6:c4:b8:74:95:8d:5c:d6:f5:88:c2:dd:86:05:7c:
+ d2:0d:72:b7:78:13:58:fc:53:b4:5c:e9:ad:0c:8d:88:91:d3:
+ 9a:b6:cd:59:72:d7:d6:ba:11:54:65:04:fc:8f:10:e3:17:b1:
+ aa:96:cd:94:92:16:d8:98:e6:fe:4a:a8:29:f9:ca:c4:e4:46:
+ e8:73:4f:5d:95:76:f4:d6:36:7c:34:4f:3c:e2:18:a0:54:33:
+ ad:72
+-----BEGIN CERTIFICATE-----
+MIIC4zCCAkygAwIBAgIJAMdKgvadG/Z+MA0GCSqGSIb3DQEBBQUAMHIxCzAJBgNV
+BAYTAlBMMQwwCgYDVQQIEwNNYXoxEDAOBgNVBAoTB1NhbXN1bmcxDTALBgNVBAsT
+BFNQUkMxEDAOBgNVBAMTB1NhbXN1bmcxIjAgBgkqhkiG9w0BCQEWE3NhbXN1bmdA
+c2Ftc3VuZy5jb20wHhcNMTExMDA1MTIwMDUxWhcNMjExMDAyMTIwMDUxWjB4MQsw
+CQYDVQQGEwJQTDEMMAoGA1UECBMDTUFaMQwwCgYDVQQHEwNMZWcxDDAKBgNVBAoT
+A1NhbTENMAsGA1UECxMEU1BSQzEOMAwGA1UEAxMFRmlsaXAxIDAeBgkqhkiG9w0B
+CQEWEWZpbGlwQHNhbXN1bmcuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
+gQDS/sS0wXSCb34ojN8bWFd4Pl9eTLHh18UNGsPpLpp4itdfuc/OgyqaSoDwBzVh
+EWAVLCTxexUa4Ncva+41NbkW4RCsFzeGs0ktpu1+8Q+v0QEOGqVF2rQkgilzDF/o
+O56Fxw9vG1OA+qdQd3yOAV2EqLNBPrEYB9K5GFyffrakSQIDAQABo3sweTAJBgNV
+HRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZp
+Y2F0ZTAdBgNVHQ4EFgQUeyy3iV75KtOkpPFd6mnR9dFGZMwwHwYDVR0jBBgwFoAU
+ggh/2wAChuhTKqX6WK5nfxQ4yGAwDQYJKoZIhvcNAQEFBQADgYEADtv0CBrQ1QCM
+H9jKFjpSpq7zFKMXQeVtb/Zie823//woicg8kxnP5sS4dJWNXNb1iMLdhgV80g1y
+t3gTWPxTtFzprQyNiJHTmrbNWXLX1roRVGUE/I8Q4xexqpbNlJIW2Jjm/kqoKfnK
+xORG6HNPXZV29NY2fDRPPOIYoFQzrXI=
+-----END CERTIFICATE-----
--- /dev/null
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: DES-EDE3-CBC,FDE9F633EA955697
+
+ASWLPmOFfKlo46nJXTJLCkhvD/q1MsHXPaaSByVzaavXxwMxOc2g7VkIR2D0yViQ
+mxQFhJLVeq/1UI9pXL2+zk0awptHogwjTw81r2I+R6qkHsSjGjl4Ds6hOX3J211K
+UqO4+3kf6JJOizXbH/y6WWbj9jEJeE7zzmhuyq8k6Kp47leZsle5y13usii323tz
+OgAzZGsQBSkrlBNKKM58O7TkCO6UbZLjVEoBqcJU+p+UiKoGKdUV/MxkbGEKTEPN
+wrFiqIxSk9KuV5iDAjnYCPz6iQIE+Q3NOW+MTw0yjWoMb7uXJexGM6VYkYFZUffe
+16nAzJpYbG+CsJ5XTiGoiodazloVYdnDFnbDLDGS2kLgiuuHzF/DL1lFlbXwgpGj
+sXFp6CemJ+KnMz4aIfC63Wuav+jvAVw26pl/cYxbhboSkl+H9ZKbk+KcIeMN1Rb7
+LD35tsjO5rnQ1QlG0WP6qT6O1SPG/4GgJTyzTwuw6i8jQw62ahKB5hTri/Z8Fmrn
+kFh8F7gTJ+YnxrQuTK8r9QrZrXsE/YqUbHtVEI/m/6uydWdFHNWzJxe6oavuwks2
+3mumh1101mBEuEClzOzHP925oeXW+N8R+jFnA/7NkIjeOo+J9Z+QzBiq6DVJcuEY
+5aqXcCIS9AciUoh3/ovtT637r25nhYwCruZLZ+4+Vkpv9n/gPSipHXgHt2cynaID
+6O7xyoADa+zY1zTRd+A4aA+SWd/bxvKe+6sc/6iBlKA8bKwfPJcwg7il4bX4g5dk
+dI8gTyM9puDoHrdTaLwY8+JL0MCguEvkk7LDttNfN0gxYvxXTpZ+Tg==
+-----END RSA PRIVATE KEY-----
--- /dev/null
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ c7:4a:82:f6:9d:1b:f6:7f
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=PL, ST=Maz, O=Samsung, OU=SPRC, CN=Samsung/emailAddress=samsung@samsung.com
+ Validity
+ Not Before: Oct 5 12:11:33 2011 GMT
+ Not After : Oct 2 12:11:33 2021 GMT
+ Subject: C=PL, ST=Mazowieckie, L=legionowo, O=samsung, OU=sprc, CN=magda/emailAddress=magda@samsung.com
+ Subject Public Key Info:
+ Public Key Algorithm: dsaEncryption
+ DSA Public Key:
+ pub:
+ 00:ac:40:42:0e:cc:a8:28:24:0b:43:09:7e:d6:23:
+ 35:a2:8c:e6:7d:62:66:fe:23:d6:58:b8:f7:32:9f:
+ 63:99:d3:2c:ff:af:60:0b:e0:d2:8c:0b:35:8b:c9:
+ e6:77:0a:7d:8d:43:00:23:d4:e3:ff:ad:0b:b4:d3:
+ b9:af:79:c2:08:f9:af:0b:c0:5e:7c:e0:4b:23:86:
+ b9:2a:f4:7c:af:43:ca:b1:fa:13:42:df:5d:3f:96:
+ b8:84:07:6a:19:b6:89:26:f1:a8:fa:c2:86:59:e9:
+ e7:f1:17:0d:30:5a:3b:a4:1f:76:9a:b4:04:fe:3c:
+ 0a:56:5e:6f:17:00:f9:36:05
+ P:
+ 00:b5:3c:23:9a:b0:58:65:7c:c7:35:ca:37:5c:a7:
+ bc:e4:cd:71:a2:5b:e3:29:56:e1:65:b1:d6:30:90:
+ 06:bd:b0:8b:cd:ad:02:e2:da:e9:71:72:73:41:78:
+ 21:ca:0d:b9:3b:53:e2:77:fd:0c:0e:d9:76:a7:6a:
+ 94:0c:52:ab:df:8d:f8:cb:d5:04:39:55:fe:c4:35:
+ 45:8f:34:fe:dc:12:fc:7c:d8:d6:f9:8d:67:47:c9:
+ 17:d5:ff:f4:dc:88:16:4d:f0:62:cd:11:b7:e1:b5:
+ 69:61:23:a0:9b:0d:6d:40:69:8d:27:3d:9f:3b:f6:
+ b4:88:93:bf:da:34:a6:77:15
+ Q:
+ 00:b7:2b:f2:e4:00:9a:75:7e:dc:32:c8:03:99:d3:
+ a3:40:60:d1:b8:cb
+ G:
+ 24:6e:e6:79:4b:50:6c:cb:a5:44:c7:63:cd:e0:a8:
+ c9:ad:85:5d:d9:be:e1:a7:2f:22:71:3d:ff:e3:32:
+ 6d:74:c1:dd:b1:40:34:cc:b0:e9:64:ef:93:82:bd:
+ 44:af:2d:9b:9d:8d:f7:97:32:91:38:e9:01:bc:6a:
+ 4c:c6:97:c2:47:56:6c:e1:5d:54:a0:0a:9f:2c:62:
+ fd:42:ad:63:d4:3a:36:6c:09:07:68:5b:03:51:94:
+ ce:13:e4:a3:ca:c4:75:ae:ba:08:69:74:55:bc:8c:
+ d6:52:8c:26:30:3e:c2:9f:69:1b:5d:74:2f:4a:2f:
+ d7:d4:3d:7e:fa:8a:a7:95
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ Netscape Comment:
+ OpenSSL Generated Certificate
+ X509v3 Subject Key Identifier:
+ 99:2A:52:86:CC:2F:5A:D1:00:05:DF:A5:DD:6C:5C:71:17:02:C9:D5
+ X509v3 Authority Key Identifier:
+ keyid:82:08:7F:DB:00:02:86:E8:53:2A:A5:FA:58:AE:67:7F:14:38:C8:60
+
+ Signature Algorithm: sha1WithRSAEncryption
+ 81:f9:c0:bb:f8:0c:25:10:bf:04:5c:24:82:fa:c7:2f:44:d5:
+ e1:f7:cf:54:07:fb:45:29:d9:4b:a8:9b:e0:81:c6:82:bb:d7:
+ 26:f2:fe:42:1e:ef:1f:29:2f:64:8a:83:d8:bf:7a:9d:8d:84:
+ 69:23:6b:d3:25:eb:4f:cd:58:44:e9:dd:39:05:09:37:1e:18:
+ fd:6f:26:e9:ab:2e:e2:1c:c0:34:d6:6a:58:26:c0:a4:f0:c8:
+ 30:ae:95:70:f0:35:c2:b2:a0:66:a6:d6:a7:6d:7c:58:1a:88:
+ da:ff:69:5d:5d:0e:fa:3a:73:c6:ad:7e:19:e4:15:d9:4b:1b:
+ 47:07
+-----BEGIN CERTIFICATE-----
+MIIEDzCCA3igAwIBAgIJAMdKgvadG/Z/MA0GCSqGSIb3DQEBBQUAMHIxCzAJBgNV
+BAYTAlBMMQwwCgYDVQQIEwNNYXoxEDAOBgNVBAoTB1NhbXN1bmcxDTALBgNVBAsT
+BFNQUkMxEDAOBgNVBAMTB1NhbXN1bmcxIjAgBgkqhkiG9w0BCQEWE3NhbXN1bmdA
+c2Ftc3VuZy5jb20wHhcNMTExMDA1MTIxMTMzWhcNMjExMDAyMTIxMTMzWjCBijEL
+MAkGA1UEBhMCUEwxFDASBgNVBAgTC01hem93aWVja2llMRIwEAYDVQQHEwlsZWdp
+b25vd28xEDAOBgNVBAoTB3NhbXN1bmcxDTALBgNVBAsTBHNwcmMxDjAMBgNVBAMT
+BW1hZ2RhMSAwHgYJKoZIhvcNAQkBFhFtYWdkYUBzYW1zdW5nLmNvbTCCAbcwggEr
+BgcqhkjOOAQBMIIBHgKBgQC1PCOasFhlfMc1yjdcp7zkzXGiW+MpVuFlsdYwkAa9
+sIvNrQLi2ulxcnNBeCHKDbk7U+J3/QwO2XanapQMUqvfjfjL1QQ5Vf7ENUWPNP7c
+Evx82Nb5jWdHyRfV//TciBZN8GLNEbfhtWlhI6CbDW1AaY0nPZ879rSIk7/aNKZ3
+FQIVALcr8uQAmnV+3DLIA5nTo0Bg0bjLAoGAJG7meUtQbMulRMdjzeCoya2FXdm+
+4acvInE9/+MybXTB3bFANMyw6WTvk4K9RK8tm52N95cykTjpAbxqTMaXwkdWbOFd
+VKAKnyxi/UKtY9Q6NmwJB2hbA1GUzhPko8rEda66CGl0VbyM1lKMJjA+wp9pG110
+L0ov19Q9fvqKp5UDgYUAAoGBAKxAQg7MqCgkC0MJftYjNaKM5n1iZv4j1li49zKf
+Y5nTLP+vYAvg0owLNYvJ5ncKfY1DACPU4/+tC7TTua95wgj5rwvAXnzgSyOGuSr0
+fK9DyrH6E0LfXT+WuIQHahm2iSbxqPrChlnp5/EXDTBaO6Qfdpq0BP48ClZebxcA
++TYFo3sweTAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVy
+YXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUmSpShswvWtEABd+l3WxccRcCydUw
+HwYDVR0jBBgwFoAUggh/2wAChuhTKqX6WK5nfxQ4yGAwDQYJKoZIhvcNAQEFBQAD
+gYEAgfnAu/gMJRC/BFwkgvrHL0TV4ffPVAf7RSnZS6ib4IHGgrvXJvL+Qh7vHykv
+ZIqD2L96nY2EaSNr0yXrT81YROndOQUJNx4Y/W8m6asu4hzANNZqWCbApPDIMK6V
+cPA1wrKgZqbWp218WBqI2v9pXV0O+jpzxq1+GeQV2UsbRwc=
+-----END CERTIFICATE-----
--- /dev/null
+-----BEGIN DSA PRIVATE KEY-----
+MIIBuwIBAAKBgQC1PCOasFhlfMc1yjdcp7zkzXGiW+MpVuFlsdYwkAa9sIvNrQLi
+2ulxcnNBeCHKDbk7U+J3/QwO2XanapQMUqvfjfjL1QQ5Vf7ENUWPNP7cEvx82Nb5
+jWdHyRfV//TciBZN8GLNEbfhtWlhI6CbDW1AaY0nPZ879rSIk7/aNKZ3FQIVALcr
+8uQAmnV+3DLIA5nTo0Bg0bjLAoGAJG7meUtQbMulRMdjzeCoya2FXdm+4acvInE9
+/+MybXTB3bFANMyw6WTvk4K9RK8tm52N95cykTjpAbxqTMaXwkdWbOFdVKAKnyxi
+/UKtY9Q6NmwJB2hbA1GUzhPko8rEda66CGl0VbyM1lKMJjA+wp9pG110L0ov19Q9
+fvqKp5UCgYEArEBCDsyoKCQLQwl+1iM1oozmfWJm/iPWWLj3Mp9jmdMs/69gC+DS
+jAs1i8nmdwp9jUMAI9Tj/60LtNO5r3nCCPmvC8BefOBLI4a5KvR8r0PKsfoTQt9d
+P5a4hAdqGbaJJvGo+sKGWenn8RcNMFo7pB92mrQE/jwKVl5vFwD5NgUCFC0583uX
+PgTY5e9pOTVpCwebt50S
+-----END DSA PRIVATE KEY-----
--- /dev/null
+-----BEGIN CERTIFICATE-----
+MIIFVTCCBD2gAwIBAgIHBBrt1FojCzANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE
+BhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAY
+BgNVBAoTEUdvRGFkZHkuY29tLCBJbmMuMTMwMQYDVQQLEypodHRwOi8vY2VydGlm
+aWNhdGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkxMDAuBgNVBAMTJ0dvIERhZGR5
+IFNlY3VyZSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTERMA8GA1UEBRMIMDc5Njky
+ODcwHhcNMTAwNjA5MDIwNzU3WhcNMTEwNjE5MTEwNDM2WjBRMRUwEwYDVQQKEwwq
+LnVidW50dS5jb20xITAfBgNVBAsTGERvbWFpbiBDb250cm9sIFZhbGlkYXRlZDEV
+MBMGA1UEAxMMKi51YnVudHUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+CgKCAQEAu8VcCeGdREV3PYYQukyrfUAay8Ic3fMhA+YUKzqbH8UuPhcjjS3izxaT
+vHLh7v80HS4DXYu6CqoQugZndV4R9KqJN1HVK5acar91VOeQgTSoowTSFtyg6aXJ
+JVdEETyftGHSpS4WjyQZ9FazTfC47c5lJr+3wCZ90UaxaWpNERpMc2L4ZxG1wGCw
+XYWVONtV817NecZVAiytvNPSmcnFm/OC/5GtzxNhfYmsNt1+MiC3IUFe2XnQwFhG
+rvn9IcG2RhEKOOu55pHM08FcnDbfyegBkEDAmQbFIUM+tFUI7nkDNQWy/Mgzuqtg
+DjydGu8h7BObEFrqXtUpm9CbTFZgzwIDAQABo4IBtjCCAbIwDwYDVR0TAQH/BAUw
+AwEBADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDgYDVR0PAQH/BAQD
+AgWgMDMGA1UdHwQsMCowKKAmoCSGImh0dHA6Ly9jcmwuZ29kYWRkeS5jb20vZ2Rz
+MS0xOS5jcmwwUwYDVR0gBEwwSjBIBgtghkgBhv1tAQcXATA5MDcGCCsGAQUFBwIB
+FitodHRwOi8vY2VydGlmaWNhdGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvMIGA
+BggrBgEFBQcBAQR0MHIwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmdvZGFkZHku
+Y29tLzBKBggrBgEFBQcwAoY+aHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNv
+bS9yZXBvc2l0b3J5L2dkX2ludGVybWVkaWF0ZS5jcnQwHwYDVR0jBBgwFoAU/axh
+MpNsRdbi7oVfmrrndplozOcwIwYDVR0RBBwwGoIMKi51YnVudHUuY29tggp1YnVu
+dHUuY29tMB0GA1UdDgQWBBTUVPFNlBiCNfPjhD8O8mDUv7MLUjANBgkqhkiG9w0B
+AQUFAAOCAQEAUjuOqqu+vS0StsxVXj44hvPye1MC/MkanIrdce5BgYMc5a+8UJba
+ay8h34vtsvfDsTifNY8ijDx79Hprh9V2LwfWWAiWK2SdrceIdGrxDvzmDHllO5YT
+ig2XhAA7ll4toSnrUfsZmi/bgb1V6VNoq36xvK+riDGnPhc7tNDZZb1fBKE+nA1p
+CZq80Liv1xri4Nj1YQ0kMQQnSHkUgEGg7bvtf+cNkIp3OXTNW8f7VFoaWVZNKW8c
+cxNljypjJM+h7xXCG/YRKws8eCi+xpO1Oc41tnSvbCbc0B6+xwFjRx5tfja309QI
+R2+uBFsmWtBCtn31o4CFNytEnwBOPVbZBA==
+-----END CERTIFICATE-----
--- /dev/null
+-----BEGIN CERTIFICATE-----
+MIIE3jCCA8agAwIBAgICAwEwDQYJKoZIhvcNAQEFBQAwYzELMAkGA1UEBhMCVVMx
+ITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g
+RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMTYw
+MTU0MzdaFw0yNjExMTYwMTU0MzdaMIHKMQswCQYDVQQGEwJVUzEQMA4GA1UECBMH
+QXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTEaMBgGA1UEChMRR29EYWRkeS5j
+b20sIEluYy4xMzAxBgNVBAsTKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5j
+b20vcmVwb3NpdG9yeTEwMC4GA1UEAxMnR28gRGFkZHkgU2VjdXJlIENlcnRpZmlj
+YXRpb24gQXV0aG9yaXR5MREwDwYDVQQFEwgwNzk2OTI4NzCCASIwDQYJKoZIhvcN
+AQEBBQADggEPADCCAQoCggEBAMQt1RWMnCZM7DI161+4WQFapmGBWTtwY6vj3D3H
+KrjJM9N55DrtPDAjhI6zMBS2sofDPZVUBJ7fmd0LJR4h3mUpfjWoqVTr9vcyOdQm
+VZWt7/v+WIbXnvQAjYwqDL1CBM6nPwT27oDyqu9SoWlm2r4arV3aLGbqGmu75RpR
+SgAvSMeYddi5Kcju+GZtCpyz8/x4fKL4o/K1w/O5epHBp+YlLpyo7RJlbmr2EkRT
+cDCVw5wrWCs9CHRK8r5RsL+H0EwnWGu1NcWdrxcx+AuP7q2BNgWJCJjPOq8lh8BJ
+6qf9Z/dFjpfMFDniNoW1fho3/Rb2cRGadDAW/hOUoz+EDU8CAwEAAaOCATIwggEu
+MB0GA1UdDgQWBBT9rGEyk2xF1uLuhV+auud2mWjM5zAfBgNVHSMEGDAWgBTSxLDS
+kdRMEXGzYcs9of7dqGrU4zASBgNVHRMBAf8ECDAGAQH/AgEAMDMGCCsGAQUFBwEB
+BCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZ29kYWRkeS5jb20wRgYDVR0f
+BD8wPTA7oDmgN4Y1aHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNvbS9yZXBv
+c2l0b3J5L2dkcm9vdC5jcmwwSwYDVR0gBEQwQjBABgRVHSAAMDgwNgYIKwYBBQUH
+AgEWKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeTAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBANKGwOy9+aG2Z+5mC6IG
+OgRQjhVyrEp0lVPLN8tESe8HkGsz2ZbwlFalEzAFPIUyIXvJxwqoJKSQ3kbTJSMU
+A2fCENZvD117esyfxVgqwcSeIaha86ykRvOe5GPLL5CkKSkB2XIsKd83ASe8T+5o
+0yGPwLPk9Qnt0hCqU7S+8MxZC9Y7lhyVJEnfzuz9p0iRFEUOOjZv2kWzRaJBydTX
+RE4+uXR21aITVSzGh6O1mawGhId/dQb8vxRMDsxuxN89txJx9OjxUUAiKEngHUuH
+qDTMBqLdElrRhjZkAzVvb3du6/KFUJheqwNTrZEjYx8WnM25sgVjOuH0aBsXBTWV
+U+4=
+-----END CERTIFICATE-----
--- /dev/null
+-----BEGIN CERTIFICATE-----
+MIIE+zCCBGSgAwIBAgICAQ0wDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1Zh
+bGlDZXJ0IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIElu
+Yy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24g
+QXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAe
+BgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTA0MDYyOTE3MDYyMFoX
+DTI0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBE
+YWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3MgMiBDZXJ0
+aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggENADCCAQgC
+ggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv
+2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+q
+N1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiO
+r18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lN
+f4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+YihfukEH
+U1jPEX44dMX4/7VpkI+EdOqXG68CAQOjggHhMIIB3TAdBgNVHQ4EFgQU0sSw0pHU
+TBFxs2HLPaH+3ahq1OMwgdIGA1UdIwSByjCBx6GBwaSBvjCBuzEkMCIGA1UEBxMb
+VmFsaUNlcnQgVmFsaWRhdGlvbiBOZXR3b3JrMRcwFQYDVQQKEw5WYWxpQ2VydCwg
+SW5jLjE1MDMGA1UECxMsVmFsaUNlcnQgQ2xhc3MgMiBQb2xpY3kgVmFsaWRhdGlv
+biBBdXRob3JpdHkxITAfBgNVBAMTGGh0dHA6Ly93d3cudmFsaWNlcnQuY29tLzEg
+MB4GCSqGSIb3DQEJARYRaW5mb0B2YWxpY2VydC5jb22CAQEwDwYDVR0TAQH/BAUw
+AwEB/zAzBggrBgEFBQcBAQQnMCUwIwYIKwYBBQUHMAGGF2h0dHA6Ly9vY3NwLmdv
+ZGFkZHkuY29tMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9jZXJ0aWZpY2F0ZXMu
+Z29kYWRkeS5jb20vcmVwb3NpdG9yeS9yb290LmNybDBLBgNVHSAERDBCMEAGBFUd
+IAAwODA2BggrBgEFBQcCARYqaHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNv
+bS9yZXBvc2l0b3J5MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOBgQC1
+QPmnHfbq/qQaQlpE9xXUhUaJwL6e4+PrxeNYiY+Sn1eocSxI0YGyeR+sBjUZsE4O
+WBsUs5iB0QQeyAfJg594RAoYC5jcdnplDQ1tgMQLARzLrUc+cb53S8wGd9D0Vmsf
+SxOaFIqII6hR8INMqzW/Rn453HWkrugp++85j09VZw==
+-----END CERTIFICATE-----
--- /dev/null
+-----BEGIN CERTIFICATE-----\r
+MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0\r
+IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz\r
+BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y\r
+aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG\r
+9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMTk1NFoXDTE5MDYy\r
+NjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y\r
+azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs\r
+YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw\r
+Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl\r
+cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOOnHK5avIWZJV16vY\r
+dA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVCCSRrCl6zfN1SLUzm1NZ9\r
+WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7RfZHM047QS\r
+v4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9v\r
+UJSZSWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTu\r
+IYEZoDJJKPTEjlbVUjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwC\r
+W/POuZ6lcg5Ktz885hZo+L7tdEy8W9ViH0Pd\r
+-----END CERTIFICATE-----\r
--- /dev/null
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 85:7d:e1:c5:d9:de:7a:1f
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=PL, ST=Mazowieckie, O=Samsung, OU=SPRC, CN=Operator Test Root Certificate/emailAddress=operator@samsung.com
+ Validity
+ Not Before: Jan 4 17:27:08 2011 GMT
+ Not After : Jan 3 17:27:08 2014 GMT
+ Subject: C=PL, ST=Mazowieckie, O=Samsung, OU=SPRC, CN=Operator Test Root Certificate/emailAddress=operator@samsung.com
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public Key: (1024 bit)
+ Modulus (1024 bit):
+ 00:c3:39:17:a8:f9:d0:69:37:9a:56:44:39:67:10:
+ 14:a9:4b:a2:0b:c7:fc:a1:e8:e8:f7:1c:06:f4:9c:
+ 83:f7:37:07:9d:9c:2c:1b:46:43:5f:f1:7b:91:a8:
+ cd:c0:76:00:d5:9c:c9:28:f7:91:28:b6:97:ec:85:
+ b1:10:0f:58:2e:f6:6f:98:b6:ab:7b:ca:08:10:7f:
+ 55:32:bf:32:db:a7:c2:86:83:03:ee:41:0a:24:de:
+ 17:e3:9d:8f:5b:fa:46:70:78:98:b4:c1:14:77:44:
+ ab:59:7c:4c:d3:4a:f7:54:f2:30:0d:38:73:95:9f:
+ 21:0e:a9:86:3e:fc:82:4e:0b
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 25:A5:90:9F:4D:3A:A4:19:0A:80:46:5E:F3:FB:20:CE:56:30:33:DA
+ X509v3 Authority Key Identifier:
+ keyid:25:A5:90:9F:4D:3A:A4:19:0A:80:46:5E:F3:FB:20:CE:56:30:33:DA
+ DirName:/C=PL/ST=Mazowieckie/O=Samsung/OU=SPRC/CN=Operator Test Root Certificate/emailAddress=operator@samsung.com
+ serial:85:7D:E1:C5:D9:DE:7A:1F
+
+ X509v3 Basic Constraints:
+ CA:TRUE
+ Signature Algorithm: sha1WithRSAEncryption
+ b9:d7:72:49:09:d8:6f:61:94:51:40:9d:c3:d3:23:53:97:b8:
+ 12:ee:cb:dd:57:e6:1f:a2:76:38:5d:42:51:bd:a9:30:19:f7:
+ 67:5b:a8:67:4a:9e:a1:f0:a9:22:14:94:77:32:27:79:37:9c:
+ 0a:0f:52:80:14:62:00:94:45:85:3b:fd:ad:b4:c3:20:45:ba:
+ b7:91:1a:9e:38:51:0f:9b:d5:ce:74:c7:bd:4a:21:9a:2d:b5:
+ 71:0b:42:d2:95:72:66:fe:eb:11:ad:62:44:6c:32:4e:b4:00:
+ 37:d7:b8:d5:4b:f6:74:36:78:d6:ae:66:b3:ca:6e:42:ff:cb:
+ c2:e6
+-----BEGIN CERTIFICATE-----
+MIIDnzCCAwigAwIBAgIJAIV94cXZ3nofMA0GCSqGSIb3DQEBBQUAMIGSMQswCQYD
+VQQGEwJQTDEUMBIGA1UECBMLTWF6b3dpZWNraWUxEDAOBgNVBAoTB1NhbXN1bmcx
+DTALBgNVBAsTBFNQUkMxJzAlBgNVBAMTHk9wZXJhdG9yIFRlc3QgUm9vdCBDZXJ0
+aWZpY2F0ZTEjMCEGCSqGSIb3DQEJARYUb3BlcmF0b3JAc2Ftc3VuZy5jb20wHhcN
+MTEwMTA0MTcyNzA4WhcNMTQwMTAzMTcyNzA4WjCBkjELMAkGA1UEBhMCUEwxFDAS
+BgNVBAgTC01hem93aWVja2llMRAwDgYDVQQKEwdTYW1zdW5nMQ0wCwYDVQQLEwRT
+UFJDMScwJQYDVQQDEx5PcGVyYXRvciBUZXN0IFJvb3QgQ2VydGlmaWNhdGUxIzAh
+BgkqhkiG9w0BCQEWFG9wZXJhdG9yQHNhbXN1bmcuY29tMIGfMA0GCSqGSIb3DQEB
+AQUAA4GNADCBiQKBgQDDOReo+dBpN5pWRDlnEBSpS6ILx/yh6Oj3HAb0nIP3Nwed
+nCwbRkNf8XuRqM3AdgDVnMko95EotpfshbEQD1gu9m+Ytqt7yggQf1UyvzLbp8KG
+gwPuQQok3hfjnY9b+kZweJi0wRR3RKtZfEzTSvdU8jANOHOVnyEOqYY+/IJOCwID
+AQABo4H6MIH3MB0GA1UdDgQWBBQlpZCfTTqkGQqARl7z+yDOVjAz2jCBxwYDVR0j
+BIG/MIG8gBQlpZCfTTqkGQqARl7z+yDOVjAz2qGBmKSBlTCBkjELMAkGA1UEBhMC
+UEwxFDASBgNVBAgTC01hem93aWVja2llMRAwDgYDVQQKEwdTYW1zdW5nMQ0wCwYD
+VQQLEwRTUFJDMScwJQYDVQQDEx5PcGVyYXRvciBUZXN0IFJvb3QgQ2VydGlmaWNh
+dGUxIzAhBgkqhkiG9w0BCQEWFG9wZXJhdG9yQHNhbXN1bmcuY29tggkAhX3hxdne
+eh8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQC513JJCdhvYZRRQJ3D
+0yNTl7gS7svdV+YfonY4XUJRvakwGfdnW6hnSp6h8KkiFJR3Mid5N5wKD1KAFGIA
+lEWFO/2ttMMgRbq3kRqeOFEPm9XOdMe9SiGaLbVxC0LSlXJm/usRrWJEbDJOtAA3
+17jVS/Z0NnjWrmazym5C/8vC5g==
+-----END CERTIFICATE-----
--- /dev/null
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 85:7d:e1:c5:d9:de:7a:20
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=PL, ST=Mazowieckie, O=Samsung, OU=SPRC, CN=Operator Test Root Certificate/emailAddress=operator@samsung.com
+ Validity
+ Not Before: Jan 4 17:34:31 2011 GMT
+ Not After : Jan 4 17:34:31 2012 GMT
+ Subject: C=PL, ST=Malopolskie, L=Krakow, O=Samsung, OU=N/A, CN=Operator Test Second Level Certificate/emailAddress=second.operator@samsung.com
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public Key: (1024 bit)
+ Modulus (1024 bit):
+ 00:ba:3c:58:ca:87:1e:59:68:54:8a:54:34:43:61:
+ f1:81:e6:35:c1:46:74:16:c7:ff:f9:15:9e:0c:5a:
+ 6a:89:c1:13:0c:61:2e:ba:00:e0:71:ea:7e:31:ae:
+ 4e:ef:93:58:51:98:97:f3:bf:8a:9b:b2:c1:b7:0c:
+ 5f:3f:56:b3:13:3b:d0:80:be:04:66:89:84:50:ca:
+ fe:f6:f7:6b:05:3b:30:4e:96:9c:5b:c5:80:bc:d6:
+ be:6e:69:f4:b9:9b:4c:06:7a:ed:37:67:b2:fe:45:
+ 69:57:62:54:cb:69:69:48:b9:7d:a0:42:f1:b6:dc:
+ f2:7f:eb:75:2a:d4:83:69:b9
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ Netscape Comment:
+ OpenSSL Generated Certificate
+ X509v3 Subject Key Identifier:
+ D9:F3:11:BF:98:5A:60:12:7A:85:B5:E7:A7:38:4F:CF:51:1D:C6:B2
+ X509v3 Authority Key Identifier:
+ keyid:25:A5:90:9F:4D:3A:A4:19:0A:80:46:5E:F3:FB:20:CE:56:30:33:DA
+
+ Signature Algorithm: sha1WithRSAEncryption
+ 69:6c:26:81:51:91:a6:e6:11:dc:81:35:03:73:85:4f:2f:29:
+ 1f:20:f2:23:54:82:ca:8f:b8:a6:e3:3f:cd:72:5e:d7:e7:f5:
+ 84:8a:33:e2:51:9f:36:4b:30:85:f4:4f:87:c7:9a:69:0b:15:
+ 6e:92:c7:1f:2f:58:a4:57:f8:c2:cd:59:6c:d2:11:63:ae:bb:
+ b0:32:3f:09:e7:2e:ad:db:1b:fe:e7:a4:21:43:47:76:e1:de:
+ 36:bb:26:3f:16:76:20:ed:a4:68:c1:48:ae:2b:95:fb:f6:d2:
+ f2:7f:74:f6:83:e2:89:06:b5:89:54:6e:7f:cf:88:94:66:e8:
+ da:32
+-----BEGIN CERTIFICATE-----
+MIIDPjCCAqegAwIBAgIJAIV94cXZ3nogMA0GCSqGSIb3DQEBBQUAMIGSMQswCQYD
+VQQGEwJQTDEUMBIGA1UECBMLTWF6b3dpZWNraWUxEDAOBgNVBAoTB1NhbXN1bmcx
+DTALBgNVBAsTBFNQUkMxJzAlBgNVBAMTHk9wZXJhdG9yIFRlc3QgUm9vdCBDZXJ0
+aWZpY2F0ZTEjMCEGCSqGSIb3DQEJARYUb3BlcmF0b3JAc2Ftc3VuZy5jb20wHhcN
+MTEwMTA0MTczNDMxWhcNMTIwMTA0MTczNDMxWjCBsTELMAkGA1UEBhMCUEwxFDAS
+BgNVBAgTC01hbG9wb2xza2llMQ8wDQYDVQQHEwZLcmFrb3cxEDAOBgNVBAoTB1Nh
+bXN1bmcxDDAKBgNVBAsTA04vQTEvMC0GA1UEAxMmT3BlcmF0b3IgVGVzdCBTZWNv
+bmQgTGV2ZWwgQ2VydGlmaWNhdGUxKjAoBgkqhkiG9w0BCQEWG3NlY29uZC5vcGVy
+YXRvckBzYW1zdW5nLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAujxY
+yoceWWhUilQ0Q2HxgeY1wUZ0Fsf/+RWeDFpqicETDGEuugDgcep+Ma5O75NYUZiX
+87+Km7LBtwxfP1azEzvQgL4EZomEUMr+9vdrBTswTpacW8WAvNa+bmn0uZtMBnrt
+N2ey/kVpV2JUy2lpSLl9oELxttzyf+t1KtSDabkCAwEAAaN7MHkwCQYDVR0TBAIw
+ADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUw
+HQYDVR0OBBYEFNnzEb+YWmASeoW156c4T89RHcayMB8GA1UdIwQYMBaAFCWlkJ9N
+OqQZCoBGXvP7IM5WMDPaMA0GCSqGSIb3DQEBBQUAA4GBAGlsJoFRkabmEdyBNQNz
+hU8vKR8g8iNUgsqPuKbjP81yXtfn9YSKM+JRnzZLMIX0T4fHmmkLFW6Sxx8vWKRX
++MLNWWzSEWOuu7AyPwnnLq3bG/7npCFDR3bh3ja7Jj8WdiDtpGjBSK4rlfv20vJ/
+dPaD4okGtYlUbn/PiJRm6Noy
+-----END CERTIFICATE-----
--- /dev/null
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: DES-EDE3-CBC,44C051D8935528BB
+
+iISuf9ELdyP5M0vlWOK4msH09HRAhN+43qRu/RDznpsTs2lX2sJITXXEmJC4EJzS
+Zk4jf3ScTj1JsMGlg5k0mZWLmDb4kUxTRVUqJX2W4uUYEmWav7LQHRAsPwNUSMs3
+DzZabSf1vplnKKoL9mMtX4E0mj79AkJp7tARQu4Zn2FDMg/UnCErzhGeoFysztmM
+v0Biyrf8yTbatMMr7Ea6rIsKS8KbkEeYDk4LpxBXkMeOutnnUUdhUEXZ/mwgJq2e
++8LLPiWdFsrGxPdub7iuLXidXSpOd9VaC9LN/ORKF+EiJtF+twWSBotxYOtwmtgj
+xUHfXBcbaFoPnLKNS0nxwsOHF07LUfsCHzfVm1uGyWFkkLrPfcSjb6PahFlfO6w5
+fv8HnUOgeAjlhK6X+xhmw1tpwMUlmcYmq31eC8rwxP59jNQbhH6GVr5+rEMRHNgp
+loC1WqthoRtBEC0bi99VpIHVIepe9G+p40sIropoUWftfDSLl3RtONg5GyyZWQ4a
+ROxsiLHDZ7+q8eKkJuYPkiZ61/5MHuOsH5k57PG7ppG6/0p+ED4bTwxxDb6PU4pA
+08xUTZQ0CUn1x80o/lKw+1E9TJOTbCvrEJAnMksfOkNkNyedgDJaxfV63wYvnL4+
+BLzCqa6djpe0Mg2olQieV/piRUt7JaGA7bnaMAn+bJ56PzUnMl0/WlxzGTMtHjkf
+zUqgLLdxZpJP7zl4XleSfRWlPgL1iN1s84x48ej+MGgOGi7xTgX/sfCLkN4No/8k
+c5Po+lQU261XAYNuAjtjUFQP/FgIMM9CnJrDWp8xHZXUJBo0c5lOKg==
+-----END RSA PRIVATE KEY-----
--- /dev/null
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ c7:4a:82:f6:9d:1b:f6:7d
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=PL, ST=Maz, O=Samsung, OU=SPRC, CN=Samsung/emailAddress=samsung@samsung.com
+ Validity
+ Not Before: Oct 5 11:52:36 2011 GMT
+ Not After : Oct 4 11:52:36 2014 GMT
+ Subject: C=PL, ST=Maz, O=Samsung, OU=SPRC, CN=Samsung/emailAddress=samsung@samsung.com
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public Key: (1024 bit)
+ Modulus (1024 bit):
+ 00:93:c2:12:8b:3e:b1:69:fe:c8:7e:f1:fa:b0:03:
+ d7:bd:25:03:bb:14:70:ab:65:ff:8f:e9:38:14:2b:
+ 92:02:d9:e7:b4:78:60:a0:ce:b1:b8:b6:78:c5:af:
+ b3:83:3c:47:58:3d:1e:a0:78:69:4d:56:dd:8c:d8:
+ 20:27:b2:0d:9f:bf:f1:d4:e1:39:0f:1b:6f:b8:cd:
+ ca:f4:0b:fd:d7:cb:64:09:c7:6d:1e:e8:dd:89:43:
+ 7f:72:85:3d:9a:54:6e:7c:55:a0:da:f5:e9:28:01:
+ ec:3a:da:5a:18:45:fc:28:b1:0e:43:2c:4c:26:5c:
+ ca:bc:44:d9:ce:7d:5a:f2:f3
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 82:08:7F:DB:00:02:86:E8:53:2A:A5:FA:58:AE:67:7F:14:38:C8:60
+ X509v3 Authority Key Identifier:
+ keyid:82:08:7F:DB:00:02:86:E8:53:2A:A5:FA:58:AE:67:7F:14:38:C8:60
+ DirName:/C=PL/ST=Maz/O=Samsung/OU=SPRC/CN=Samsung/emailAddress=samsung@samsung.com
+ serial:C7:4A:82:F6:9D:1B:F6:7D
+
+ X509v3 Basic Constraints:
+ CA:TRUE
+ Signature Algorithm: sha1WithRSAEncryption
+ 0f:cb:a3:cd:25:02:00:17:a9:c5:21:4a:6e:bb:ce:d9:14:74:
+ 23:29:c5:47:ff:02:91:5a:ee:a1:53:a7:e4:69:6f:f2:00:bc:
+ 09:87:80:f8:3b:a5:51:59:e9:20:1f:1d:5d:cb:91:eb:91:1e:
+ f4:79:bf:35:68:a5:ed:24:e5:28:dd:c9:1f:bf:53:f7:75:77:
+ 6c:fe:94:0c:de:9c:d9:8e:42:c6:7d:61:6b:5d:5d:ad:a7:6a:
+ e4:9b:53:2a:f7:85:9c:51:1d:72:5d:5c:2f:eb:f9:ff:80:4c:
+ 6d:46:e8:a0:2c:8a:6f:94:13:b2:00:47:2c:b0:b0:1c:12:fc:
+ a0:65
+-----BEGIN CERTIFICATE-----
+MIIDOjCCAqOgAwIBAgIJAMdKgvadG/Z9MA0GCSqGSIb3DQEBBQUAMHIxCzAJBgNV
+BAYTAlBMMQwwCgYDVQQIEwNNYXoxEDAOBgNVBAoTB1NhbXN1bmcxDTALBgNVBAsT
+BFNQUkMxEDAOBgNVBAMTB1NhbXN1bmcxIjAgBgkqhkiG9w0BCQEWE3NhbXN1bmdA
+c2Ftc3VuZy5jb20wHhcNMTExMDA1MTE1MjM2WhcNMTQxMDA0MTE1MjM2WjByMQsw
+CQYDVQQGEwJQTDEMMAoGA1UECBMDTWF6MRAwDgYDVQQKEwdTYW1zdW5nMQ0wCwYD
+VQQLEwRTUFJDMRAwDgYDVQQDEwdTYW1zdW5nMSIwIAYJKoZIhvcNAQkBFhNzYW1z
+dW5nQHNhbXN1bmcuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCTwhKL
+PrFp/sh+8fqwA9e9JQO7FHCrZf+P6TgUK5IC2ee0eGCgzrG4tnjFr7ODPEdYPR6g
+eGlNVt2M2CAnsg2fv/HU4TkPG2+4zcr0C/3Xy2QJx20e6N2JQ39yhT2aVG58VaDa
+9ekoAew62loYRfwosQ5DLEwmXMq8RNnOfVry8wIDAQABo4HXMIHUMB0GA1UdDgQW
+BBSCCH/bAAKG6FMqpfpYrmd/FDjIYDCBpAYDVR0jBIGcMIGZgBSCCH/bAAKG6FMq
+pfpYrmd/FDjIYKF2pHQwcjELMAkGA1UEBhMCUEwxDDAKBgNVBAgTA01hejEQMA4G
+A1UEChMHU2Ftc3VuZzENMAsGA1UECxMEU1BSQzEQMA4GA1UEAxMHU2Ftc3VuZzEi
+MCAGCSqGSIb3DQEJARYTc2Ftc3VuZ0BzYW1zdW5nLmNvbYIJAMdKgvadG/Z9MAwG
+A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAD8ujzSUCABepxSFKbrvO2RR0
+IynFR/8CkVruoVOn5Glv8gC8CYeA+DulUVnpIB8dXcuR65Ee9Hm/NWil7STlKN3J
+H79T93V3bP6UDN6c2Y5Cxn1ha11dradq5JtTKveFnFEdcl1cL+v5/4BMbUbooCyK
+b5QTsgBHLLCwHBL8oGU=
+-----END CERTIFICATE-----
--- /dev/null
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: DES-EDE3-CBC,D2942E015452A445
+
+0M/tC+qVDqyhNsxZZB/dGLuNxsStSUA7TRDRiSBee9JsvcFZjq03D/VjBakNIeET
+6efmKfAngomfvrWtxhped3RI4vasX05swfnr4qiUKjLPyftmNEepbNGeI8MaiD7a
+fEOZuAacstyS5RMHRBXrktq+jtXW2meQTuvEMBJf1AeAIuaFNvr3OvvpCtDwRffi
+1ijUVuG0ZQ6MpP7cGeqLYUZ9StTMxeiEesAPM4YrG7HIY13KaHwMr1ZRtENe7qZ8
+R8vwgW188FYkSSrcQjCVEuj/ztTg9eVuSKdTNgjfKzTWnlrjAzi8CKBsrkYoarwS
+6Rv3TqVVnx4HHdo9RIUKZPeLOdcMD1OPK7aOUedPTAcht3Y7SQQphBQypLf6PLKB
+DCo79B4TUA1W9MijT2d2GN7oJHqHax8zO2j+yCLkEcHF32JZsEFE63Bwss72FXMg
+mTmpCwyzR+oN93687JDUBAP9zNVd76ZnpzwlMZirB6QTY/lrH+iXLH3R3PO6cl2R
+0Jei4IQ1oB+SX6GOPt4tKGTqktUFhsJYbXyifj4O1ZyDVYTp0JafOLxJfU33oYTm
+278yshFdyHRgfKIHvqctZ1xJN2ioVcWf+9DprHc5kGb6wUKRVfQpipTS2hgbMBz+
+UWRZWq+CUD5QkTz4cSQfhPWQF6TNWpTQc0dvAlo3Cmxrro1PriDItsCOeydeNWvn
+Dyynx7ODp/F1rX5ekaXkVxsdGgD/HuNF+c7tEytD7U4/CmevytuXRIrFM0alj2OE
+aBFTqKicBoKgDV9VUOTKwuFeNV7MSuVDUnngEBeYrinwGa7wuV7tzA==
+-----END RSA PRIVATE KEY-----
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<Signature xmlns="http://www.w3.org/2000/09/xmldsig#" xmlns:wac="http://wacapps.net/ns/digsig" Id="AuthorSignature">
+ <SignedInfo>
+ <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
+ <SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
+ <Reference URI="config.xml">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>xUKQbov3HL7JD2/zVUKpPEVGc5C6VWDXwxoDHzDs9y0=</DigestValue>
+ </Reference>
+ <Reference URI="index.html">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>cIE41PzyhMnF++EmhJ3Ptnd4ZqXyBlRJgiIqxlutbV8=</DigestValue>
+ </Reference>
+ <Reference URI="#prop">
+ <Transforms>
+ <Transform Algorithm="http://www.w3.org/2006/12/xml-c14n11"/>
+ </Transforms>
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>MH34nIMXxv0fMQQ8bTV1wZUNLOrXTmpnxpADlNzmQ/4=</DigestValue>
+ </Reference>
+ </SignedInfo>
+ <SignatureValue>fhh+VQq76Uodq4upHhvcC2tgbVY8bL9DiiSe9wn1O4YrIFKMnEEYqYmpQbL1puWU
+Zbht0hXpvEFXg1010q5kOZQxknqcyFg3hyVUpFDPARkJs1XhRNbFWJJF7qNXVgt5
+NyFrdXFv4lVFjkv+chSykaWu6V22z43E8kJcg+zGVU8=</SignatureValue>
+ <KeyInfo>
+ <X509Data>
+ <X509Certificate>MIIETTCCA7agAwIBAgIJANaOuOCRgiz3MA0GCSqGSIb3DQEBBQUAMIG8MQswCQYD
+VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTE9MDsGA1UEChM0WE1MIFNlY3Vy
+aXR5IExpYnJhcnkgKGh0dHA6Ly93d3cuYWxla3NleS5jb20veG1sc2VjKTEeMBwG
+A1UECxMVVGVzdCBSb290IENlcnRpZmljYXRlMRYwFAYDVQQDEw1BbGVrc2V5IFNh
+bmluMSEwHwYJKoZIhvcNAQkBFhJ4bWxzZWNAYWxla3NleS5jb20wHhcNMDUwNzEw
+MDIyOTAxWhcNMTUwNzA4MDIyOTAxWjCBvDELMAkGA1UEBhMCVVMxEzARBgNVBAgT
+CkNhbGlmb3JuaWExPTA7BgNVBAoTNFhNTCBTZWN1cml0eSBMaWJyYXJ5IChodHRw
+Oi8vd3d3LmFsZWtzZXkuY29tL3htbHNlYykxHjAcBgNVBAsTFVRlc3QgUm9vdCBD
+ZXJ0aWZpY2F0ZTEWMBQGA1UEAxMNQWxla3NleSBTYW5pbjEhMB8GCSqGSIb3DQEJ
+ARYSeG1sc2VjQGFsZWtzZXkuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
+gQDayaFajJxOdVU+8EjwO31S2XqNmYxxbHfiUJO3w2h57OPUkKAcKe5Gvt9hJbPT
+b3C4blPScOke2RexKnXS7pAXXbxFlgUlZ0QK0K2pdl559OSmrtH3mPP9BJvvDMlx
+kcNj9/EeD+yGd8GN/yT6PTDh8G/4lszOXL+tyKIkC4Ys/wIDAQABo4IBUzCCAU8w
+DAYDVR0TBAUwAwEB/zAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQg
+Q2VydGlmaWNhdGUwHQYDVR0OBBYEFNpG6Wvmr9M9quUhS1LtymYo4P6FMIHxBgNV
+HSMEgekwgeaAFNpG6Wvmr9M9quUhS1LtymYo4P6FoYHCpIG/MIG8MQswCQYDVQQG
+EwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTE9MDsGA1UEChM0WE1MIFNlY3VyaXR5
+IExpYnJhcnkgKGh0dHA6Ly93d3cuYWxla3NleS5jb20veG1sc2VjKTEeMBwGA1UE
+CxMVVGVzdCBSb290IENlcnRpZmljYXRlMRYwFAYDVQQDEw1BbGVrc2V5IFNhbmlu
+MSEwHwYJKoZIhvcNAQkBFhJ4bWxzZWNAYWxla3NleS5jb22CCQDWjrjgkYIs9zAN
+BgkqhkiG9w0BAQUFAAOBgQBUXbdOTQwArcNrbxavzARp2JGOnzo6WzTm+OFSXC0F
+08YwT8jWbht97e8lNNVOBU4Y/38ReZqYC9OqFofG1/O9AdQ58WL/FWg8DgP5MJPT
+T9kRU3FU01jUiX2+kbdnghZAOJm0ziRNxfNPwIIWPKYXyXEKQQzrnxyFey1hP7cg
+6A==</X509Certificate>
+</X509Data>
+ </KeyInfo>
+ <Object Id="prop">
+ <SignatureProperties xmlns:dsp="http://www.w3.org/2009/xmldsig-properties">
+ <SignatureProperty Id="profile" Target="#AuthorSignature">
+ <dsp:Profile URI="http://www.w3.org/ns/widgets-digsig#profile"/>
+ </SignatureProperty>
+ <SignatureProperty Id="role" Target="#AuthorSignature">
+ <dsp:Role URI="http://www.w3.org/ns/widgets-digsig#role-author"/>
+ </SignatureProperty>
+ <SignatureProperty Id="identifier" Target="#AuthorSignature">
+ <dsp:Identifier/>
+ </SignatureProperty>
+ </SignatureProperties>
+ </Object>
+</Signature>
--- /dev/null
+<widget xmlns="http://www.w3.org/ns/widgets" id="Test Widget">
+ <name shortname="ShortName">Widget Name OK</name>
+ <version>1.2.3.4</version>
+ <description>A short description of widget</description>
+ <author>Author Name</author>
+</widget>
--- /dev/null
+<!doctype html>
+<title>Not tested</title>
+<body style="background-color:#666">
+<h1>None</h1>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<Signature xmlns="http://www.w3.org/2000/09/xmldsig#" xmlns:wac="http://wacapps.net/ns/digsig" Id="DistributorSignature">
+ <SignedInfo>
+ <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
+ <SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
+ <Reference URI="author-signature.xml">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>ZLhd8X2rzCIDGHkIvpDbCXq+dwq+DK7ZZaDD/fII8RU=</DigestValue>
+ </Reference>
+ <Reference URI="config.xml">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>xUKQbov3HL7JD2/zVUKpPEVGc5C6VWDXwxoDHzDs9y0=</DigestValue>
+ </Reference>
+ <Reference URI="index.html">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>cIE41PzyhMnF++EmhJ3Ptnd4ZqXyBlRJgiIqxlutbV8=</DigestValue>
+ </Reference>
+ <Reference URI="#prop">
+ <Transforms>
+ <Transform Algorithm="http://www.w3.org/2006/12/xml-c14n11"/>
+ </Transforms>
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>ZxnfFPi1rAoxfpN98xSP3lv5tZg9ymJElAFdg3ejrXE=</DigestValue>
+ </Reference>
+ </SignedInfo>
+ <SignatureValue>Dwm15jQbvUxe7fa7p4RVRAUzYY6eGQmDJSWXnv2LBbouch163OMaXgjKXWOLU+ZA
+MwwuUUXG44QvOIv5M3Kd/Pc6kwvyb9+xm8zqmFF/mhttmAHc7VjY5sfB+bYFt9/3
+8+upSqxiUGLXYzMD/9u4W9ociwAcLiOQytBF1/TCv/4=</SignatureValue>
+ <KeyInfo>
+ <X509Data>
+ <X509Certificate>MIIC4zCCAkygAwIBAgIJAMdKgvadG/Z+MA0GCSqGSIb3DQEBBQUAMHIxCzAJBgNV
+BAYTAlBMMQwwCgYDVQQIEwNNYXoxEDAOBgNVBAoTB1NhbXN1bmcxDTALBgNVBAsT
+BFNQUkMxEDAOBgNVBAMTB1NhbXN1bmcxIjAgBgkqhkiG9w0BCQEWE3NhbXN1bmdA
+c2Ftc3VuZy5jb20wHhcNMTExMDA1MTIwMDUxWhcNMjExMDAyMTIwMDUxWjB4MQsw
+CQYDVQQGEwJQTDEMMAoGA1UECBMDTUFaMQwwCgYDVQQHEwNMZWcxDDAKBgNVBAoT
+A1NhbTENMAsGA1UECxMEU1BSQzEOMAwGA1UEAxMFRmlsaXAxIDAeBgkqhkiG9w0B
+CQEWEWZpbGlwQHNhbXN1bmcuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
+gQDS/sS0wXSCb34ojN8bWFd4Pl9eTLHh18UNGsPpLpp4itdfuc/OgyqaSoDwBzVh
+EWAVLCTxexUa4Ncva+41NbkW4RCsFzeGs0ktpu1+8Q+v0QEOGqVF2rQkgilzDF/o
+O56Fxw9vG1OA+qdQd3yOAV2EqLNBPrEYB9K5GFyffrakSQIDAQABo3sweTAJBgNV
+HRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZp
+Y2F0ZTAdBgNVHQ4EFgQUeyy3iV75KtOkpPFd6mnR9dFGZMwwHwYDVR0jBBgwFoAU
+ggh/2wAChuhTKqX6WK5nfxQ4yGAwDQYJKoZIhvcNAQEFBQADgYEADtv0CBrQ1QCM
+H9jKFjpSpq7zFKMXQeVtb/Zie823//woicg8kxnP5sS4dJWNXNb1iMLdhgV80g1y
+t3gTWPxTtFzprQyNiJHTmrbNWXLX1roRVGUE/I8Q4xexqpbNlJIW2Jjm/kqoKfnK
+xORG6HNPXZV29NY2fDRPPOIYoFQzrXI=</X509Certificate>
+</X509Data>
+ </KeyInfo>
+ <Object Id="prop">
+ <SignatureProperties xmlns:dsp="http://www.w3.org/2009/xmldsig-properties">
+ <SignatureProperty Id="profile" Target="#DistributorSignature">
+ <dsp:Profile URI="http://www.w3.org/ns/widgets-digsig#profile"/>
+ </SignatureProperty>
+ <SignatureProperty Id="role" Target="#DistributorSignature">
+ <dsp:Role URI="http://www.w3.org/ns/widgets-digsig#role-distributor"/>
+ </SignatureProperty>
+ <SignatureProperty Id="identifier" Target="#DistributorSignature">
+ <dsp:Identifier/>
+ </SignatureProperty>
+ </SignatureProperties>
+ </Object>
+</Signature>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<Signature xmlns="http://www.w3.org/2000/09/xmldsig#" xmlns:wac="http://wacapps.net/ns/digsig" Id="DistributorSignature">
+ <SignedInfo>
+ <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
+ <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1"/>
+ <Reference URI="author-signature.xml">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>ZLhd8X2rzCIDGHkIvpDbCXq+dwq+DK7ZZaDD/fII8RU=</DigestValue>
+ </Reference>
+ <Reference URI="config.xml">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>xUKQbov3HL7JD2/zVUKpPEVGc5C6VWDXwxoDHzDs9y0=</DigestValue>
+ </Reference>
+ <Reference URI="index.html">
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>cIE41PzyhMnF++EmhJ3Ptnd4ZqXyBlRJgiIqxlutbV8=</DigestValue>
+ </Reference>
+ <Reference URI="#prop">
+ <Transforms>
+ <Transform Algorithm="http://www.w3.org/2006/12/xml-c14n11"/>
+ </Transforms>
+ <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <DigestValue>ZxnfFPi1rAoxfpN98xSP3lv5tZg9ymJElAFdg3ejrXE=</DigestValue>
+ </Reference>
+ </SignedInfo>
+ <SignatureValue>fV1J/120GG5L7qsxEkyH6fBvQh2atlpiGMbVM1+pb8Q6pHib5beV6A==</SignatureValue>
+ <KeyInfo>
+ <X509Data>
+ <X509Certificate>MIIEDzCCA3igAwIBAgIJAMdKgvadG/Z/MA0GCSqGSIb3DQEBBQUAMHIxCzAJBgNV
+BAYTAlBMMQwwCgYDVQQIEwNNYXoxEDAOBgNVBAoTB1NhbXN1bmcxDTALBgNVBAsT
+BFNQUkMxEDAOBgNVBAMTB1NhbXN1bmcxIjAgBgkqhkiG9w0BCQEWE3NhbXN1bmdA
+c2Ftc3VuZy5jb20wHhcNMTExMDA1MTIxMTMzWhcNMjExMDAyMTIxMTMzWjCBijEL
+MAkGA1UEBhMCUEwxFDASBgNVBAgTC01hem93aWVja2llMRIwEAYDVQQHEwlsZWdp
+b25vd28xEDAOBgNVBAoTB3NhbXN1bmcxDTALBgNVBAsTBHNwcmMxDjAMBgNVBAMT
+BW1hZ2RhMSAwHgYJKoZIhvcNAQkBFhFtYWdkYUBzYW1zdW5nLmNvbTCCAbcwggEr
+BgcqhkjOOAQBMIIBHgKBgQC1PCOasFhlfMc1yjdcp7zkzXGiW+MpVuFlsdYwkAa9
+sIvNrQLi2ulxcnNBeCHKDbk7U+J3/QwO2XanapQMUqvfjfjL1QQ5Vf7ENUWPNP7c
+Evx82Nb5jWdHyRfV//TciBZN8GLNEbfhtWlhI6CbDW1AaY0nPZ879rSIk7/aNKZ3
+FQIVALcr8uQAmnV+3DLIA5nTo0Bg0bjLAoGAJG7meUtQbMulRMdjzeCoya2FXdm+
+4acvInE9/+MybXTB3bFANMyw6WTvk4K9RK8tm52N95cykTjpAbxqTMaXwkdWbOFd
+VKAKnyxi/UKtY9Q6NmwJB2hbA1GUzhPko8rEda66CGl0VbyM1lKMJjA+wp9pG110
+L0ov19Q9fvqKp5UDgYUAAoGBAKxAQg7MqCgkC0MJftYjNaKM5n1iZv4j1li49zKf
+Y5nTLP+vYAvg0owLNYvJ5ncKfY1DACPU4/+tC7TTua95wgj5rwvAXnzgSyOGuSr0
+fK9DyrH6E0LfXT+WuIQHahm2iSbxqPrChlnp5/EXDTBaO6Qfdpq0BP48ClZebxcA
++TYFo3sweTAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVy
+YXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUmSpShswvWtEABd+l3WxccRcCydUw
+HwYDVR0jBBgwFoAUggh/2wAChuhTKqX6WK5nfxQ4yGAwDQYJKoZIhvcNAQEFBQAD
+gYEAgfnAu/gMJRC/BFwkgvrHL0TV4ffPVAf7RSnZS6ib4IHGgrvXJvL+Qh7vHykv
+ZIqD2L96nY2EaSNr0yXrT81YROndOQUJNx4Y/W8m6asu4hzANNZqWCbApPDIMK6V
+cPA1wrKgZqbWp218WBqI2v9pXV0O+jpzxq1+GeQV2UsbRwc=</X509Certificate>
+</X509Data>
+ </KeyInfo>
+ <Object Id="prop">
+ <SignatureProperties xmlns:dsp="http://www.w3.org/2009/xmldsig-properties">
+ <SignatureProperty Id="profile" Target="#DistributorSignature">
+ <dsp:Profile URI="http://www.w3.org/ns/widgets-digsig#profile"/>
+ </SignatureProperty>
+ <SignatureProperty Id="role" Target="#DistributorSignature">
+ <dsp:Role URI="http://www.w3.org/ns/widgets-digsig#role-distributor"/>
+ </SignatureProperty>
+ <SignatureProperty Id="identifier" Target="#DistributorSignature">
+ <dsp:Identifier/>
+ </SignatureProperty>
+ </SignatureProperties>
+ </Object>
+</Signature>
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of main
+ */
+#include <dpl/test/test_runner.h>
+#include <vcore/VCore.h>
+
+#include <libsoup/soup.h> // includes headers with g_type_init
+
+int main (int argc, char *argv[])
+{
+ g_type_init();
+ g_thread_init(NULL);
+ ValidationCore::AttachToThread();
+ int status = DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv);
+ ValidationCore::DetachFromThread();
+
+ return status;
+}
+