From: Kibum Kim Date: Mon, 27 Feb 2012 12:16:50 +0000 (+0900) Subject: tizen beta release X-Git-Tag: build/2012-06-06.032427~3 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=45bf3bfbb061b87511ece6f50b1aa6c803844a65;p=platform%2Fframework%2Fweb%2Fwrt-commons.git tizen beta release --- 45bf3bfbb061b87511ece6f50b1aa6c803844a65 diff --git a/3rdparty/CMakeLists.txt b/3rdparty/CMakeLists.txt new file mode 100644 index 0000000..4783a46 --- /dev/null +++ b/3rdparty/CMakeLists.txt @@ -0,0 +1,63 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author 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) + diff --git a/3rdparty/DESCRIPTION b/3rdparty/DESCRIPTION new file mode 100644 index 0000000..6f383f3 --- /dev/null +++ b/3rdparty/DESCRIPTION @@ -0,0 +1 @@ +Third-party libraries diff --git a/3rdparty/fastdelegate/CPOL.html b/3rdparty/fastdelegate/CPOL.html new file mode 100644 index 0000000..e035a60 --- /dev/null +++ b/3rdparty/fastdelegate/CPOL.html @@ -0,0 +1,251 @@ + + +The Code Project Open License (COPL) + + + + +

The Code Project Open License (CPOL) 1.02

+
+ +
+
+ +

Preamble

+

+ This License governs Your use of the Work. This License is intended to allow developers + to use the Source Code and Executable Files provided as part of the Work in any + application in any form. +

+

+ The main points subject to the terms of the License are:

+
    +
  • Source Code and Executable Files can be used in commercial applications;
  • +
  • Source Code and Executable Files can be redistributed; and
  • +
  • Source Code can be modified to create derivative works.
  • +
  • No claim of suitability, guarantee, or any warranty whatsoever is provided. The software is + provided "as-is".
  • +
  • The Article accompanying the Work may not be distributed or republished without the + Author's consent
  • +
+ +

+ This License is entered between You, the individual or other entity reading or otherwise + making use of the Work licensed pursuant to this License and the individual or other + entity which offers the Work under the terms of this License ("Author").

+ +

License

+

+ THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CODE PROJECT OPEN + LICENSE ("LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE + LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT + LAW IS PROHIBITED.

+

+ BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HEREIN, YOU ACCEPT AND AGREE TO BE + BOUND BY THE TERMS OF THIS LICENSE. THE AUTHOR GRANTS YOU THE RIGHTS CONTAINED HEREIN + IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS. IF YOU DO NOT + AGREE TO ACCEPT AND BE BOUND BY THE TERMS OF THIS LICENSE, YOU CANNOT MAKE ANY + USE OF THE WORK.

+ +
    +
  1. Definitions. + +
      +
    1. "Articles" means, collectively, all articles written by Author + which describes how the Source Code and Executable Files for the Work may be used + by a user.
    2. +
    3. "Author" means the individual or entity that offers the Work under the terms + of this License.
    4. +
    5. "Derivative Work" means a work based upon the Work or upon the + Work and other pre-existing works.
    6. +
    7. "Executable Files" refer to the executables, binary files, configuration + and any required data files included in the Work.
    8. +
    9. "Publisher" means the provider of the website, magazine, CD-ROM, DVD or other + medium from or by which the Work is obtained by You.
    10. +
    11. "Source Code" refers to the collection of source code and configuration files + used to create the Executable Files.
    12. +
    13. "Standard Version" refers to such a Work if it has not been modified, or + has been modified in accordance with the consent of the Author, such consent being + in the full discretion of the Author.
    14. +
    15. "Work" refers to the collection of files distributed by the Publisher, including + the Source Code, Executable Files, binaries, data files, documentation, whitepapers + and the Articles.
    16. +
    17. "You" is you, an individual or entity wishing to use the Work and exercise + your rights under this License. +
    18. +
    +
  2. + +
  3. Fair Use/Fair Use Rights. Nothing in this License is intended to + reduce, limit, or restrict any rights arising from fair use, fair dealing, first + sale or other limitations on the exclusive rights of the copyright owner under copyright + law or other applicable laws. +
  4. + +
  5. License Grant. Subject to the terms and conditions of this License, + the Author hereby grants You a worldwide, royalty-free, non-exclusive, perpetual + (for the duration of the applicable copyright) license to exercise the rights in + the Work as stated below: + +
      +
    1. You may use the standard version of the Source Code or Executable Files in Your + own applications.
    2. +
    3. You may apply bug fixes, portability fixes and other modifications obtained from + the Public Domain or from the Author. A Work modified in such a way shall still + be considered the standard version and will be subject to this License.
    4. +
    5. You may otherwise modify Your copy of this Work (excluding the Articles) in any + way to create a Derivative Work, provided that You insert a prominent notice in + each changed file stating how, when and where You changed that file.
    6. +
    7. You may distribute the standard version of the Executable Files and Source Code + or Derivative Work in aggregate with other (possibly commercial) programs as part + of a larger (possibly commercial) software distribution.
    8. +
    9. The Articles discussing the Work published in any form by the author may not be + distributed or republished without the Author's consent. The author retains + copyright to any such Articles. You may use the Executable Files and Source Code + pursuant to this License but you may not repost or republish or otherwise distribute + or make available the Articles, without the prior written consent of the Author.
    10. +
    + + Any subroutines or modules supplied by You and linked into the Source Code or Executable + Files this Work shall not be considered part of this Work and will not be subject + to the terms of this License. +
  6. + +
  7. Patent License. Subject to the terms and conditions of this License, + each Author 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, import, + and otherwise transfer the Work.
  8. + +
  9. Restrictions. The license granted in Section 3 above is expressly + made subject to and limited by the following restrictions: + +
      +
    1. You agree not to remove any of the original copyright, patent, trademark, and + attribution notices and associated disclaimers that may appear in the Source Code + or Executable Files.
    2. +
    3. You agree not to advertise or in any way imply that this Work is a product of Your + own.
    4. +
    5. The name of the Author may not be used to endorse or promote products derived from + the Work without the prior written consent of the Author.
    6. +
    7. You agree not to sell, lease, or rent any part of the Work. This does not restrict + you from including the Work or any part of the Work inside a larger software + distribution that itself is being sold. The Work by itself, though, cannot be sold, + leased or rented.
    8. +
    9. You may distribute the Executable Files and Source Code only under the terms of + this License, and You must include a copy of, or the Uniform Resource Identifier + for, this License with every copy of the Executable Files or Source Code You distribute + and ensure that anyone receiving such Executable Files and Source Code agrees that + the terms of this License apply to such Executable Files and/or Source Code. You + may not offer or impose any terms on the Work that alter or restrict the terms of + this License or the recipients' exercise of the rights granted hereunder. You + may not sublicense the Work. You must keep intact all notices that refer to this + License and to the disclaimer of warranties. You may not distribute the Executable + Files or Source Code with any technological measures that control access or use + of the Work in a manner inconsistent with the terms of this License.
    10. +
    11. You agree not to use the Work for illegal, immoral or improper purposes, or on pages + containing illegal, immoral or improper material. The Work is subject to applicable + export laws. You agree to comply with all such laws and regulations that may apply + to the Work after Your receipt of the Work. +
    12. +
    +
  10. + +
  11. Representations, Warranties and Disclaimer. THIS WORK IS PROVIDED + "AS IS", "WHERE IS" AND "AS AVAILABLE", WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES + OR CONDITIONS OR GUARANTEES. YOU, THE USER, ASSUME ALL RISK IN ITS USE, INCLUDING + COPYRIGHT INFRINGEMENT, PATENT INFRINGEMENT, SUITABILITY, ETC. AUTHOR EXPRESSLY + DISCLAIMS ALL EXPRESS, IMPLIED OR STATUTORY WARRANTIES OR CONDITIONS, INCLUDING + WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY + OR FITNESS FOR A PARTICULAR PURPOSE, OR ANY WARRANTY OF TITLE OR NON-INFRINGEMENT, + OR THAT THE WORK (OR ANY PORTION THEREOF) IS CORRECT, USEFUL, BUG-FREE OR FREE OF + VIRUSES. YOU MUST PASS THIS DISCLAIMER ON WHENEVER YOU DISTRIBUTE THE WORK OR DERIVATIVE + WORKS. +
  12. + +
  13. Indemnity. You agree to defend, indemnify and hold harmless the Author and + the Publisher from and against any claims, suits, losses, damages, liabilities, + costs, and expenses (including reasonable legal or attorneys’ fees) resulting from + or relating to any use of the Work by You. +
  14. + +
  15. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE + LAW, IN NO EVENT WILL THE AUTHOR OR THE PUBLISHER BE LIABLE TO YOU ON ANY LEGAL + THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES + ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK OR OTHERWISE, EVEN IF THE AUTHOR + OR THE PUBLISHER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +
  16. + +
  17. Termination. + +
      +
    1. This License and the rights granted hereunder will terminate automatically upon + any breach by You of any term of this License. Individuals or entities who have + received Derivative Works from You under this License, however, will not have their + licenses terminated provided such individuals or entities remain in full compliance + with those licenses. Sections 1, 2, 6, 7, 8, 9, 10 and 11 will survive any termination + of this License.
    2. + +
    3. If You bring a copyright, trademark, patent or any other infringement claim against + any contributor over infringements You claim are made by the Work, your License + from such contributor to the Work ends automatically.
    4. + +
    5. Subject to the above terms and conditions, this License is perpetual (for the duration + of the applicable copyright in the Work). Notwithstanding the above, the Author + reserves the right to release the Work under different license terms or to stop + distributing the Work at any time; provided, however that any such election will + not serve to withdraw this License (or any other license that has been, or is required + to be, granted under the terms of this License), and this License will continue + in full force and effect unless terminated as stated above. +
    6. +
    +
  18. + +
  19. Publisher. The parties hereby confirm that the Publisher shall + not, under any circumstances, be responsible for and shall not have any liability + in respect of the subject matter of this License. The Publisher makes no warranty + whatsoever in connection with the Work and shall not be liable to You or any party + on any legal theory for any damages whatsoever, including without limitation any + general, special, incidental or consequential damages arising in connection to this + license. The Publisher reserves the right to cease making the Work available to + You at any time without notice
  20. + +
  21. Miscellaneous + +
      +
    1. This License shall be governed by the laws of the location of the head office of + the Author or if the Author is an individual, the laws of location of the principal + place of residence of the Author.
    2. +
    3. If any provision of this License is invalid or unenforceable under applicable law, + it shall not affect the validity or enforceability of the remainder of the terms + of this License, and without further action by the parties to this License, such + provision shall be reformed to the minimum extent necessary to make such provision + valid and enforceable.
    4. +
    5. No term or provision of this License shall be deemed waived and no breach consented + to unless such waiver or consent shall be in writing and signed by the party to + be charged with such waiver or consent.
    6. +
    7. This License constitutes the entire agreement between the parties with respect to + the Work licensed herein. There are no understandings, agreements or representations + with respect to the Work not specified herein. The Author shall not be bound by + any additional provisions that may appear in any communication from You. This License + may not be modified without the mutual written agreement of the Author and You. +
    8. +
    + +
  22. +
+ +
+
+ + + diff --git a/3rdparty/fastdelegate/DESCRIPTION b/3rdparty/fastdelegate/DESCRIPTION new file mode 100644 index 0000000..85409db --- /dev/null +++ b/3rdparty/fastdelegate/DESCRIPTION @@ -0,0 +1 @@ +Support for delegate constructs diff --git a/3rdparty/fastdelegate/Demo.cpp b/3rdparty/fastdelegate/Demo.cpp new file mode 100644 index 0000000..2b4d6f6 --- /dev/null +++ b/3rdparty/fastdelegate/Demo.cpp @@ -0,0 +1,143 @@ +#include +#include "FastDelegate.h" +// 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, char *str) { + printf("In SimpleStaticFunction. Num=%d, str = %s\n", num, str); +} + +void SimpleVoidFunction() { + printf("In SimpleVoidFunction with no parameters.\n"); +} + +class CBaseClass { +protected: + char *m_name; +public: + CBaseClass(char *name) : m_name(name) {}; + void SimpleMemberFunction(int num, char *str) { + printf("In SimpleMemberFunction in %s. Num=%d, str = %s\n", m_name, num, str); } + int SimpleMemberFunctionReturnsInt(int num, char *str) { + printf("In SimpleMemberFunction in %s. Num=%d, str = %s\n", m_name, num, str); return -1; } + void ConstMemberFunction(int num, char *str) const { + printf("In ConstMemberFunction in %s. Num=%d, str = %s\n", m_name, num, str); } + virtual void SimpleVirtualFunction(int num, char *str) { + printf("In SimpleVirtualFunction in %s. Num=%d, str = %s\n", m_name, num, str); } + static void StaticMemberFunction(int num, char *str) { + printf("In StaticMemberFunction. Num=%d, str =%s\n", num, str); } +}; + +class COtherClass { + double rubbish; // to ensure this class has non-zero size. +public: + virtual void UnusedVirtualFunction(void) { } + virtual void TrickyVirtualFunction(int num, 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, char *str) { printf("In SimpleDerived. num=%d\n", num); } + virtual void AnotherUnusedVirtualFunction(int num, char *str) {} + virtual void TrickyVirtualFunction(int num, char *str) { + printf("In Derived TrickyMemberFunction. Num=%d, str = %s\n", num, str); + } +}; + +using namespace fastdelegate; + +int main(void) +{ + // 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() + printf("-- FastDelegate demo --\nA no-parameter delegate is declared using FastDelegate0\n\n"); + + FastDelegate0<> noparameterdelegate(&SimpleVoidFunction); + + noparameterdelegate(); // invoke the delegate - this calls SimpleVoidFunction() + + printf("\n-- Examples using two-parameter delegates (int, char *) --\n\n"); + + // By default, the return value is void. + typedef FastDelegate2 MyDelegate; + + // If you want to have a non-void return value, put it at the end. + typedef FastDelegate2 IntMyDelegate; + + + MyDelegate funclist[12]; // delegates are initialized to empty + CBaseClass a("Base A"); + CBaseClass b("Base B"); + CDerivedClass d; + CDerivedClass c; + + IntMyDelegate newdeleg; + newdeleg = 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[11].bind( (const CBaseClass *)&a, &CBaseClass::ConstMemberFunction); + funclist[3].bind( &a, &CBaseClass::ConstMemberFunction); + // and virtual member functions + funclist[4].bind(&b, &CBaseClass::SimpleVirtualFunction); + + // You can also use the = operator. For static functions, a fastdelegate + // looks identical to a simple function pointer. + funclist[5] = &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[6] = 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[7].bind(&c, &CDerivedClass::TrickyVirtualFunction); + // BUT... in such cases you should be using the base class as an + // interface, anyway. + funclist[8].bind(&c, &COtherClass::TrickyVirtualFunction); + // Calling a function that was first declared in the derived class is straightforward + funclist[9] = MakeDelegate(&c, &CDerivedClass::SimpleDerivedFunction); + + // You can also bind directly using the constructor + MyDelegate dg(&b, &CBaseClass::SimpleVirtualFunction); + + char *msg = "Looking for equal delegate"; + for (int i=0; i<12; i++) { + printf("%d :", 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]) { + printf("Delegate is empty\n"); + } else { + // Invocation generates optimal assembly code. + funclist[i](i, msg); + }; + } + return 0; +} + diff --git a/3rdparty/fastdelegate/LICENSE b/3rdparty/fastdelegate/LICENSE new file mode 100644 index 0000000..1db661f --- /dev/null +++ b/3rdparty/fastdelegate/LICENSE @@ -0,0 +1,7 @@ +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. + diff --git a/3rdparty/minizip/DESCRIPTION b/3rdparty/minizip/DESCRIPTION new file mode 100644 index 0000000..d699bf1 --- /dev/null +++ b/3rdparty/minizip/DESCRIPTION @@ -0,0 +1 @@ +Minizip - ZIP file format support diff --git a/3rdparty/minizip/Makefile b/3rdparty/minizip/Makefile new file mode 100644 index 0000000..84eaad2 --- /dev/null +++ b/3rdparty/minizip/Makefile @@ -0,0 +1,25 @@ +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 diff --git a/3rdparty/minizip/MiniZip64_Changes.txt b/3rdparty/minizip/MiniZip64_Changes.txt new file mode 100644 index 0000000..13a1bd9 --- /dev/null +++ b/3rdparty/minizip/MiniZip64_Changes.txt @@ -0,0 +1,6 @@ + +MiniZip 1.1 was derrived from MiniZip at version 1.01f + +Change in 1.0 (Okt 2009) + - **TODO - Add history** + diff --git a/3rdparty/minizip/MiniZip64_info.txt b/3rdparty/minizip/MiniZip64_info.txt new file mode 100644 index 0000000..57d7152 --- /dev/null +++ b/3rdparty/minizip/MiniZip64_info.txt @@ -0,0 +1,74 @@ +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. + +---------------------------------------------------------- + diff --git a/3rdparty/minizip/crypt.h b/3rdparty/minizip/crypt.h new file mode 100644 index 0000000..a01d08d --- /dev/null +++ b/3rdparty/minizip/crypt.h @@ -0,0 +1,131 @@ +/* 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> 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 diff --git a/3rdparty/minizip/framework_minizip.h b/3rdparty/minizip/framework_minizip.h new file mode 100644 index 0000000..dd4b5c5 --- /dev/null +++ b/3rdparty/minizip/framework_minizip.h @@ -0,0 +1,8 @@ +/* + * @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 diff --git a/3rdparty/minizip/ioapi.c b/3rdparty/minizip/ioapi.c new file mode 100644 index 0000000..49958f6 --- /dev/null +++ b/3rdparty/minizip/ioapi.c @@ -0,0 +1,235 @@ +/* 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; +} diff --git a/3rdparty/minizip/ioapi.h b/3rdparty/minizip/ioapi.h new file mode 100644 index 0000000..8309c4c --- /dev/null +++ b/3rdparty/minizip/ioapi.h @@ -0,0 +1,200 @@ +/* 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 +#include +#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 + #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 diff --git a/3rdparty/minizip/iowin32.c b/3rdparty/minizip/iowin32.c new file mode 100644 index 0000000..6a2a883 --- /dev/null +++ b/3rdparty/minizip/iowin32.c @@ -0,0 +1,389 @@ +/* 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 + +#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; +} diff --git a/3rdparty/minizip/iowin32.h b/3rdparty/minizip/iowin32.h new file mode 100644 index 0000000..0ca0969 --- /dev/null +++ b/3rdparty/minizip/iowin32.h @@ -0,0 +1,28 @@ +/* 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 + + +#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 diff --git a/3rdparty/minizip/make_vms.com b/3rdparty/minizip/make_vms.com new file mode 100644 index 0000000..9ac13a9 --- /dev/null +++ b/3rdparty/minizip/make_vms.com @@ -0,0 +1,25 @@ +$ 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 diff --git a/3rdparty/minizip/miniunz.c b/3rdparty/minizip/miniunz.c new file mode 100644 index 0000000..9ed009f --- /dev/null +++ b/3rdparty/minizip/miniunz.c @@ -0,0 +1,648 @@ +/* + 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 +#include +#include +#include +#include +#include + +#ifdef unix +# include +# include +#else +# include +# include +#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;i0) + 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)='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 +#include +#include +#include +#include +#include + +#ifdef unix +# include +# include +# include +# include +#else +# include +# include +#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='0') && (c<='9')) + opt_compress_level = c-'0'; + if ((c=='j') || (c=='J')) + opt_exclude_path = 1; + + if (((c=='p') || (c=='P')) && (i+1='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='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; +} diff --git a/3rdparty/minizip/mztools.c b/3rdparty/minizip/mztools.c new file mode 100644 index 0000000..f9092e6 --- /dev/null +++ b/3rdparty/minizip/mztools.c @@ -0,0 +1,281 @@ +/* + Additional tools for Minizip + Code: Xavier Roche '2004 + License: Same as ZLIB (www.gzip.org) +*/ + +/* Code */ +#include +#include +#include +#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; +} diff --git a/3rdparty/minizip/mztools.h b/3rdparty/minizip/mztools.h new file mode 100644 index 0000000..88b3459 --- /dev/null +++ b/3rdparty/minizip/mztools.h @@ -0,0 +1,31 @@ +/* + 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 diff --git a/3rdparty/minizip/unzip.c b/3rdparty/minizip/unzip.c new file mode 100644 index 0000000..7617f41 --- /dev/null +++ b/3rdparty/minizip/unzip.c @@ -0,0 +1,2125 @@ +/* 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 +#include +#include + +#ifndef NOUNCRYPT + #define NOUNCRYPT +#endif + +#include "zlib.h" +#include "unzip.h" + +#ifdef STDC +# include +# include +# include +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else +# include +#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 (c1c2) + 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 (uBackReaduMaxBack) + 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 (uBackReaduMaxBack) + 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_pospfile_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_filename0) && (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_extraz_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_commentz_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_compressedrest_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;iread_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;istream.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); +} diff --git a/3rdparty/minizip/unzip.h b/3rdparty/minizip/unzip.h new file mode 100644 index 0000000..3183968 --- /dev/null +++ b/3rdparty/minizip/unzip.h @@ -0,0 +1,437 @@ +/* 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 */ diff --git a/3rdparty/minizip/unzip11.zip b/3rdparty/minizip/unzip11.zip new file mode 100644 index 0000000..fe55dc3 Binary files /dev/null and b/3rdparty/minizip/unzip11.zip differ diff --git a/3rdparty/minizip/zip.c b/3rdparty/minizip/zip.c new file mode 100644 index 0000000..3c34fc8 --- /dev/null +++ b/3rdparty/minizip/zip.c @@ -0,0 +1,2004 @@ +/* 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 +#include +#include +#include +#include "zlib.h" +#include "zip.h" + +#ifdef STDC +# include +# include +# include +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else +# include +#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;ifilled_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 (uBackReaduMaxBack) + 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 (uBackReaduMaxBack) + 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_posz_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;ici.central_header+SIZECENTRALHEADER+i) = *(filename+i); + + for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+i) = + *(((const char*)extrafield_global)+i); + + for (i=0;ici.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;ici.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; +} diff --git a/3rdparty/minizip/zip.h b/3rdparty/minizip/zip.h new file mode 100644 index 0000000..8aaebb6 --- /dev/null +++ b/3rdparty/minizip/zip.h @@ -0,0 +1,362 @@ +/* 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 */ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..42a1e50 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,203 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# @file CMakeLists.txt +# @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) +# @version 1.0 +# @brief +# + +# +# Check minimum CMake version +# +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) + +# +# Project name +# +PROJECT(dpl) + +# +# 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) + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..247c97d --- /dev/null +++ b/LICENSE @@ -0,0 +1,203 @@ +Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..ded3804 --- /dev/null +++ b/NOTICE @@ -0,0 +1 @@ +Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. \ No newline at end of file diff --git a/bin/run_all.sh b/bin/run_all.sh new file mode 100755 index 0000000..a245ea7 --- /dev/null +++ b/bin/run_all.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +./dpl-tests-core --output=text +./dpl-tests-dbus --output=text +./dpl-tests-db --output=text +./dpl-tests-event --output=text diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt new file mode 100644 index 0000000..835f856 --- /dev/null +++ b/build/CMakeLists.txt @@ -0,0 +1,33 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author 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) diff --git a/build/ace/CMakeLists.txt b/build/ace/CMakeLists.txt new file mode 100644 index 0000000..f2ab0b8 --- /dev/null +++ b/build/ace/CMakeLists.txt @@ -0,0 +1,30 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file 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 + ) + diff --git a/build/ace/dpl-ace-dao-ro.pc.in b/build/ace/dpl-ace-dao-ro.pc.in new file mode 100644 index 0000000..6af8514 --- /dev/null +++ b/build/ace/dpl-ace-dao-ro.pc.in @@ -0,0 +1,11 @@ +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} diff --git a/build/ace/dpl-ace-dao-rw.pc.in b/build/ace/dpl-ace-dao-rw.pc.in new file mode 100644 index 0000000..fe6f99f --- /dev/null +++ b/build/ace/dpl-ace-dao-rw.pc.in @@ -0,0 +1,11 @@ +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} diff --git a/build/ace/dpl-ace.pc.in b/build/ace/dpl-ace.pc.in new file mode 100644 index 0000000..45d1278 --- /dev/null +++ b/build/ace/dpl-ace.pc.in @@ -0,0 +1,11 @@ +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} diff --git a/build/core/CMakeLists.txt b/build/core/CMakeLists.txt new file mode 100644 index 0000000..a6dc980 --- /dev/null +++ b/build/core/CMakeLists.txt @@ -0,0 +1,88 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file 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) diff --git a/build/core/DESCRIPTION b/build/core/DESCRIPTION new file mode 100644 index 0000000..f7f1581 --- /dev/null +++ b/build/core/DESCRIPTION @@ -0,0 +1,2 @@ +!!!options!!! stop +EFL support diff --git a/build/core/dpl-efl.pc b/build/core/dpl-efl.pc new file mode 100644 index 0000000..193fcd4 --- /dev/null +++ b/build/core/dpl-efl.pc @@ -0,0 +1,11 @@ +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 diff --git a/build/db/CMakeLists.txt b/build/db/CMakeLists.txt new file mode 100644 index 0000000..7426d5b --- /dev/null +++ b/build/db/CMakeLists.txt @@ -0,0 +1,68 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file 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) diff --git a/build/db/dpl-db-efl.pc b/build/db/dpl-db-efl.pc new file mode 100644 index 0000000..f0dc43e --- /dev/null +++ b/build/db/dpl-db-efl.pc @@ -0,0 +1,11 @@ +prefix=/usr +exec_prefix=${prefix} +libdir=${prefix}/lib +includedir=${prefix}/include + +Name: dpl-db-efl +Description: DPL DB - EFL based +Version: 1.0.0 +Requires: dpl-efl sqlite3 db-util +Libs: -L${libdir} -ldpl-db-efl +Cflags: -I${includedir}/dpl-efl diff --git a/build/dbus/CMakeLists.txt b/build/dbus/CMakeLists.txt new file mode 100644 index 0000000..71e883a --- /dev/null +++ b/build/dbus/CMakeLists.txt @@ -0,0 +1,69 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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) diff --git a/build/dbus/dpl-dbus-efl.pc b/build/dbus/dpl-dbus-efl.pc new file mode 100644 index 0000000..6fafa42 --- /dev/null +++ b/build/dbus/dpl-dbus-efl.pc @@ -0,0 +1,11 @@ +prefix=/usr +exec_prefix=${prefix} +libdir=${prefix}/lib +includedir=${prefix}/include + +Name: dpl-dbus-efl +Description: DPL DBus - EFL based +Version: 1.0.0 +Requires: dbus-1 dpl-efl dpl-event-efl +Libs: -L${libdir} -ldpl-dbus-efl +Cflags: -I${includedir}/dpl-efl diff --git a/build/event/CMakeLists.txt b/build/event/CMakeLists.txt new file mode 100644 index 0000000..305434a --- /dev/null +++ b/build/event/CMakeLists.txt @@ -0,0 +1,71 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Lukasz Marek (l.marek@samsung.com) +# @version 1.0 +# @brief +# + +# Check required modules +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(SYS_EFL_EVENT + ecore + appcore-efl + vconf + 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) diff --git a/build/event/dpl-event-efl.pc b/build/event/dpl-event-efl.pc new file mode 100644 index 0000000..1b9f911 --- /dev/null +++ b/build/event/dpl-event-efl.pc @@ -0,0 +1,11 @@ +prefix=/usr +exec_prefix=${prefix} +libdir=${prefix}/lib +includedir=${prefix}/include + +Name: dpl-event-efl +Description: DPL Event - EFL based +Version: 1.0.0 +Requires: dpl-efl ecore appcore-efl vconf heynoti +Libs: -L${libdir} -ldpl-event-efl +Cflags: -I${includedir}/dpl-efl diff --git a/build/log/CMakeLists.txt b/build/log/CMakeLists.txt new file mode 100644 index 0000000..6669aaa --- /dev/null +++ b/build/log/CMakeLists.txt @@ -0,0 +1,65 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Lukasz Marek (l.marek@samsung.com) +# @version 1.0 +# @brief +# + +# Check required modules +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(SYS_EFL_LOG + dlog + REQUIRED +) + +# Add core include directories +INCLUDE_DIRECTORIES( + ${DPL_LOG_INCLUDE_DIR} + ${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) diff --git a/build/log/dpl-log-efl.pc b/build/log/dpl-log-efl.pc new file mode 100644 index 0000000..ea4fff9 --- /dev/null +++ b/build/log/dpl-log-efl.pc @@ -0,0 +1,11 @@ +prefix=/usr +exec_prefix=${prefix} +libdir=${prefix}/lib +includedir=${prefix}/include + +Name: dpl-log-efl +Description: DPL Log Engine - EFL based +Version: 1.0.0 +Requires: dpl-efl dlog +Libs: -L${libdir} -ldpl-log-efl +Cflags: -I${includedir}/dpl-efl diff --git a/build/popup/CMakeLists.txt b/build/popup/CMakeLists.txt new file mode 100644 index 0000000..d55fa47 --- /dev/null +++ b/build/popup/CMakeLists.txt @@ -0,0 +1,68 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file 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) diff --git a/build/popup/dpl-popup-efl.pc b/build/popup/dpl-popup-efl.pc new file mode 100644 index 0000000..92053b9 --- /dev/null +++ b/build/popup/dpl-popup-efl.pc @@ -0,0 +1,11 @@ +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 diff --git a/build/rpc/CMakeLists.txt b/build/rpc/CMakeLists.txt new file mode 100644 index 0000000..553c52f --- /dev/null +++ b/build/rpc/CMakeLists.txt @@ -0,0 +1,74 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file 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) diff --git a/build/rpc/dpl-rpc-efl.pc b/build/rpc/dpl-rpc-efl.pc new file mode 100644 index 0000000..c5e870a --- /dev/null +++ b/build/rpc/dpl-rpc-efl.pc @@ -0,0 +1,11 @@ +prefix=/usr +exec_prefix=${prefix} +libdir=${prefix}/lib +includedir=${prefix}/include + +Name: dpl-rpc-efl +Description: DPL RPC - EFL based +Version: 1.0.0 +Requires: dpl-efl dpl-event-efl dpl-socket-efl +Libs: -L${libdir} -ldpl-rpc-efl +Cflags: -I${includedir}/dpl-efl diff --git a/build/socket/CMakeLists.txt b/build/socket/CMakeLists.txt new file mode 100644 index 0000000..ea7df4b --- /dev/null +++ b/build/socket/CMakeLists.txt @@ -0,0 +1,72 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Lukasz Marek (l.marek@samsung.com) +# @version 1.0 +# @brief +# + +# Check required modules +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(SYS_EFL_SOCKET + ecore + appcore-efl + REQUIRED +) + +# Add core include directories +INCLUDE_DIRECTORIES( + ${DPL_LOG_INCLUDE_DIR} + ${DPL_CORE_INCLUDE_DIR} + ${DPL_SOCKET_INCLUDE_DIR} + ${DPL_EVENT_INCLUDE_DIR} + ${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) diff --git a/build/socket/dpl-socket-efl.pc b/build/socket/dpl-socket-efl.pc new file mode 100644 index 0000000..6de04b0 --- /dev/null +++ b/build/socket/dpl-socket-efl.pc @@ -0,0 +1,11 @@ +prefix=/usr +exec_prefix=${prefix} +libdir=${prefix}/lib +includedir=${prefix}/include + +Name: dpl-socket-efl +Description: DPL Socket - EFL based +Version: 1.0.0 +Requires: dpl-efl dpl-event-efl +Libs: -L${libdir} -ldpl-socket-efl +Cflags: -I${includedir}/dpl-efl diff --git a/build/test/CMakeLists.txt b/build/test/CMakeLists.txt new file mode 100644 index 0000000..22cb230 --- /dev/null +++ b/build/test/CMakeLists.txt @@ -0,0 +1,67 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file 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) diff --git a/build/test/dpl-test-efl.pc b/build/test/dpl-test-efl.pc new file mode 100644 index 0000000..94e9064 --- /dev/null +++ b/build/test/dpl-test-efl.pc @@ -0,0 +1,11 @@ +prefix=/usr +exec_prefix=${prefix} +libdir=${prefix}/lib +includedir=${prefix}/include + +Name: dpl-test-efl +Description: DPL Test Engine - EFL based +Version: 1.0.0 +Requires: dpl-efl +Libs: -L${libdir} -ldpl-test-efl +Cflags: -I${includedir}/dpl-efl diff --git a/build/utils/CMakeLists.txt b/build/utils/CMakeLists.txt new file mode 100644 index 0000000..6a4f875 --- /dev/null +++ b/build/utils/CMakeLists.txt @@ -0,0 +1,85 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file 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) diff --git a/build/utils/dpl-utils-efl.pc b/build/utils/dpl-utils-efl.pc new file mode 100644 index 0000000..ce770c1 --- /dev/null +++ b/build/utils/dpl-utils-efl.pc @@ -0,0 +1,11 @@ +prefix=/usr +exec_prefix=${prefix} +libdir=${prefix}/lib +includedir=${prefix}/include + +Name: dpl-utils-efl +Description: DPL UTILS - EFL based +Version: 1.0.0 +Requires: dpl-efl +Libs: -L${libdir} -ldpl-utils-efl +Cflags: -I${includedir}/dpl-efl diff --git a/build/vcore/CMakeLists.txt b/build/vcore/CMakeLists.txt new file mode 100644 index 0000000..99200d2 --- /dev/null +++ b/build/vcore/CMakeLists.txt @@ -0,0 +1,21 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) +# @brief +# + +CONFIGURE_FILE(dpl-vcore.pc.in dpl-vcore.pc @ONLY) +INSTALL(FILES ${CMAKE_BINARY_DIR}/build/vcore/dpl-vcore.pc DESTINATION lib/pkgconfig) diff --git a/build/vcore/dpl-vcore.pc.in b/build/vcore/dpl-vcore.pc.in new file mode 100644 index 0000000..73fb442 --- /dev/null +++ b/build/vcore/dpl-vcore.pc.in @@ -0,0 +1,11 @@ +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} diff --git a/build/widget_dao/CMakeLists.txt b/build/widget_dao/CMakeLists.txt new file mode 100644 index 0000000..2703ae5 --- /dev/null +++ b/build/widget_dao/CMakeLists.txt @@ -0,0 +1,26 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author 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) diff --git a/build/widget_dao/dpl-wrt-dao-ro.pc.in b/build/widget_dao/dpl-wrt-dao-ro.pc.in new file mode 100644 index 0000000..d2d112b --- /dev/null +++ b/build/widget_dao/dpl-wrt-dao-ro.pc.in @@ -0,0 +1,12 @@ +prefix=/usr +exec_prefix=${prefix} + +libdir=${prefix}/lib +includedir=${prefix}/include +Name: dpl-wrt-dao-ro +Description: dpl-wrt-dao-ro + +Version: @VERSION@ +Requires: dpl-efl libxml-2.0 +Libs: -ldpl-wrt-dao-ro -L${libdir} +Cflags: -I${includedir}/dpl-efl diff --git a/build/widget_dao/dpl-wrt-dao-rw.pc.in b/build/widget_dao/dpl-wrt-dao-rw.pc.in new file mode 100644 index 0000000..c71e58d --- /dev/null +++ b/build/widget_dao/dpl-wrt-dao-rw.pc.in @@ -0,0 +1,12 @@ +prefix=/usr +exec_prefix=${prefix} + +libdir=${prefix}/lib +includedir=${prefix}/include +Name: dpl-wrt-dao-rw +Description: dpl-wrt-dao-rw + +Version: @VERSION@ +Requires: dpl-efl dpl-wrt-dao-ro libxml-2.0 +Libs: -ldpl-wrt-dao-rw -ldpl-wrt-dao-ro -L${libdir} +Cflags: -I${includedir}/dpl-efl diff --git a/debian/DESCRIPTION b/debian/DESCRIPTION new file mode 100644 index 0000000..158a449 --- /dev/null +++ b/debian/DESCRIPTION @@ -0,0 +1 @@ +Debian folder (rules, control etc.) diff --git a/debian/README.Debian b/debian/README.Debian new file mode 100644 index 0000000..0ec9a2d --- /dev/null +++ b/debian/README.Debian @@ -0,0 +1,6 @@ +dpl for Debian +-------------- + + + + -- unknown Tue, 23 Mar 2010 11:40:32 +0100 diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..6326243 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,26 @@ +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 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 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 Mon, 13 Feb 2012 16:04:58 +0100 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +5 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..a786fd3 --- /dev/null +++ b/debian/control @@ -0,0 +1,83 @@ +Source: wrt-commons +Section: devel +Priority: extra +Maintainer: Lukasz Wrzosek, Taejeong.lee +Standards-Version: 3.7.2 +Uploaders: Yunchan Cho ,Przemyslaw Dobrowolski , Pawel Sikorski , Zbigniew Kostrzewa +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. + diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..e69de29 diff --git a/debian/dirs b/debian/dirs new file mode 100644 index 0000000..e69de29 diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..3c1584f --- /dev/null +++ b/debian/rules @@ -0,0 +1,84 @@ +#!/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 diff --git a/debian/wrt-commons-dev.dirs b/debian/wrt-commons-dev.dirs new file mode 100644 index 0000000..ca24d3e --- /dev/null +++ b/debian/wrt-commons-dev.dirs @@ -0,0 +1,5 @@ +usr/include +usr/include/dpl-efl +usr/include/dpl-efl/dpl +usr/include/dpl-efl/dpl/3rdparty +usr/include/dpl-efl/dpl/3rdparty/fastdelegate diff --git a/debian/wrt-commons-dev.install b/debian/wrt-commons-dev.install new file mode 100644 index 0000000..8163e23 --- /dev/null +++ b/debian/wrt-commons-dev.install @@ -0,0 +1,2 @@ +usr/include/dpl-efl/* +usr/lib/pkgconfig/*.pc diff --git a/debian/wrt-commons-test.install b/debian/wrt-commons-test.install new file mode 100644 index 0000000..5dec5e8 --- /dev/null +++ b/debian/wrt-commons-test.install @@ -0,0 +1,13 @@ +/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/* diff --git a/debian/wrt-commons.dirs b/debian/wrt-commons.dirs new file mode 100644 index 0000000..f5b3bee --- /dev/null +++ b/debian/wrt-commons.dirs @@ -0,0 +1,2 @@ +usr/lib + diff --git a/debian/wrt-commons.install b/debian/wrt-commons.install new file mode 100644 index 0000000..dce5a2d --- /dev/null +++ b/debian/wrt-commons.install @@ -0,0 +1,10 @@ +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/* diff --git a/debian/wrt-commons.postinst b/debian/wrt-commons.postinst new file mode 100755 index 0000000..ed20a1f --- /dev/null +++ b/debian/wrt-commons.postinst @@ -0,0 +1,63 @@ +#!/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 ..." diff --git a/dir-struct.py b/dir-struct.py new file mode 100755 index 0000000..a1fc0f0 --- /dev/null +++ b/dir-struct.py @@ -0,0 +1,126 @@ +#!/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) + diff --git a/doc/DESCRIPTION b/doc/DESCRIPTION new file mode 100644 index 0000000..c3f01bd --- /dev/null +++ b/doc/DESCRIPTION @@ -0,0 +1 @@ +Documentation diff --git a/doc/doxyfile b/doc/doxyfile new file mode 100644 index 0000000..f058b7a --- /dev/null +++ b/doc/doxyfile @@ -0,0 +1,1600 @@ +# Doxyfile 1.6.2 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = DPL + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 1.0 + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = . + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = YES + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it parses. +# With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this tag. +# The format is ext=language, where ext is a file extension, and language is one of +# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, +# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat +# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), +# use: inc=Fortran f=C. Note that for custom extensions you also need to set +# FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = YES + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen to replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penality. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will rougly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols + +SYMBOL_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by +# doxygen. The layout file controls the global structure of the generated output files +# in an output format independent way. The create the layout file that represents +# doxygen's defaults, run doxygen with the -l option. You can optionally specify a +# file name after the option, if omitted DoxygenLayout.xml will be used as the name +# of the layout file. + +LAYOUT_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = ../core ../detail + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.d \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.idl \ + *.odl \ + *.cs \ + *.php \ + *.php3 \ + *.inc \ + *.m \ + *.mm \ + *.dox \ + *.py \ + *.f90 \ + *.f \ + *.vhd \ + *.vhdl + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = NO + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = YES + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER +# are set, an additional index file will be generated that can be used as input for +# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated +# HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. +# For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's +# filter section matches. +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. + +GENERATE_TREEVIEW = YES + +# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list. + +USE_INLINE_TREES = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvances is that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES + +# By default doxygen will write a font called FreeSans.ttf to the output +# directory and reference it in all dot files that doxygen generates. This +# font does not include all possible unicode characters however, so when you need +# these (or just want a differently looking font) you can specify the font name +# using DOT_FONTNAME. You need need to make sure dot is able to find the font, +# which can be done by putting it in a standard location or by setting the +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory +# containing the font. + +DOT_FONTNAME = FreeSans + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot +# can find it using this tag. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = NO + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = NO + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = gif + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/doc/dpl_programming_guide.docx b/doc/dpl_programming_guide.docx new file mode 100644 index 0000000..f8e11e9 Binary files /dev/null and b/doc/dpl_programming_guide.docx differ diff --git a/doc/dpl_programming_guide.pdf b/doc/dpl_programming_guide.pdf new file mode 100644 index 0000000..474a40d Binary files /dev/null and b/doc/dpl_programming_guide.pdf differ diff --git a/etc/CMakeLists.txt b/etc/CMakeLists.txt new file mode 100644 index 0000000..3eab79c --- /dev/null +++ b/etc/CMakeLists.txt @@ -0,0 +1,25 @@ + +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) diff --git a/etc/DESCRIPTION b/etc/DESCRIPTION new file mode 100644 index 0000000..bf6eac9 --- /dev/null +++ b/etc/DESCRIPTION @@ -0,0 +1 @@ +This directory contain confiration scripts, config files, certificates and all other data that don't fit to other directories. diff --git a/etc/certificates/CMakeLists.txt b/etc/certificates/CMakeLists.txt new file mode 100644 index 0000000..f7f1a94 --- /dev/null +++ b/etc/certificates/CMakeLists.txt @@ -0,0 +1,30 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file 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/ + ) diff --git a/etc/certificates/tizen.root.preproduction.cert.pem b/etc/certificates/tizen.root.preproduction.cert.pem new file mode 100644 index 0000000..bbf523b --- /dev/null +++ b/etc/certificates/tizen.root.preproduction.cert.pem @@ -0,0 +1,60 @@ +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----- diff --git a/etc/certificates/wac.publisherid.pem b/etc/certificates/wac.publisherid.pem new file mode 100644 index 0000000..758fe66 --- /dev/null +++ b/etc/certificates/wac.publisherid.pem @@ -0,0 +1,24 @@ +-----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----- diff --git a/etc/certificates/wac.root.preproduction.pem b/etc/certificates/wac.root.preproduction.pem new file mode 100644 index 0000000..7c46a6a --- /dev/null +++ b/etc/certificates/wac.root.preproduction.pem @@ -0,0 +1,22 @@ +-----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----- + diff --git a/etc/certificates/wac.root.production.pem b/etc/certificates/wac.root.production.pem new file mode 100644 index 0000000..efccefd --- /dev/null +++ b/etc/certificates/wac.root.production.pem @@ -0,0 +1,22 @@ +-----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----- + diff --git a/etc/fingerprint_list.xml b/etc/fingerprint_list.xml new file mode 100644 index 0000000..970c718 --- /dev/null +++ b/etc/fingerprint_list.xml @@ -0,0 +1,21 @@ + + + AF:90:29:D2:B2:E1:6F:D6:7E:7E:EC:8E:BE:74:FA:4C:00:9C:49:FE + A6:00:BC:53:AC:37:5B:6A:03:C3:7A:8A:E0:1B:87:8B:82:94:9B:C2 + C2:C4:B5:72:9A:CF:D9:72:C5:DE:C1:E1:30:FF:74:7F:7A:AF:27:12 + + + AF:90:29:D2:B2:E1:6F:D6:7E:7E:EC:8E:BE:74:FA:4C:00:9C:49:FE + C2:C4:B5:72:9A:CF:D9:72:C5:DE:C1:E1:30:FF:74:7F:7A:AF:27:12 + A0:59:D3:37:E8:C8:2E:7F:38:84:7D:21:A9:9E:19:A9:8E:EC:EB:E1 + 8D:1F:CB:31:68:11:DA:22:59:26:58:13:6C:C6:72:C9:F0:DE:84:2A + + + 4A:9D:7A:4B:3B:29:D4:69:0A:70:B3:80:EC:A9:44:6B:03:7C:9A:38 + + + + + AD:A1:44:89:6A:35:6D:17:01:E9:6F:46:C6:00:7B:78:BE:2E:D9:4E + + diff --git a/etc/fingerprint_list.xsd b/etc/fingerprint_list.xsd new file mode 100644 index 0000000..b0fab23 --- /dev/null +++ b/etc/fingerprint_list.xsd @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/etc/schema.xsd b/etc/schema.xsd new file mode 100644 index 0000000..8028f3e --- /dev/null +++ b/etc/schema.xsd @@ -0,0 +1,415 @@ + + + + + + ]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/etc/wrt_create_clean_db.sh b/etc/wrt_create_clean_db.sh new file mode 100755 index 0000000..db450a3 --- /dev/null +++ b/etc/wrt_create_clean_db.sh @@ -0,0 +1,31 @@ +#!/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 + + diff --git a/etc/wrt_reset_db.sh b/etc/wrt_reset_db.sh new file mode 100755 index 0000000..42afbe3 --- /dev/null +++ b/etc/wrt_reset_db.sh @@ -0,0 +1,49 @@ +#!/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 + diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt new file mode 100644 index 0000000..a5546f4 --- /dev/null +++ b/examples/CMakeLists.txt @@ -0,0 +1,42 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author 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) diff --git a/examples/DESCRIPTION b/examples/DESCRIPTION new file mode 100644 index 0000000..db99a6d --- /dev/null +++ b/examples/DESCRIPTION @@ -0,0 +1,2 @@ +!!!options!!! stop +Example code diff --git a/examples/binary_queue/CMakeLists.txt b/examples/binary_queue/CMakeLists.txt new file mode 100644 index 0000000..5fb9fee --- /dev/null +++ b/examples/binary_queue/CMakeLists.txt @@ -0,0 +1,32 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) +# @version 1.0 +# @brief +# +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(BINARY_QUEUE_SYS dpl-gtk REQUIRED) + +SET(BINARY_QUEUE_SOURCES + binary_queue.cpp) + +ADD_DEFINITIONS("-D_DEBUG") + +INCLUDE_DIRECTORIES(${BINARY_QUEUE_SYS_INCLUDE_DIRS}) +LINK_DIRECTORIES(${BINARY_QUEUE_SYS_LIBRARY_DIRS}) + +ADD_EXECUTABLE(binary_queue ${BINARY_QUEUE_SOURCES}) +TARGET_LINK_LIBRARIES(binary_queue ${BINARY_QUEUE_SYS_LIBRARIES}) diff --git a/examples/binary_queue/binary_queue.cpp b/examples/binary_queue/binary_queue.cpp new file mode 100644 index 0000000..a978a6d --- /dev/null +++ b/examples/binary_queue/binary_queue.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file binary_queue.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of binary queue example + */ +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + (void)argc; + (void)argv; + + DPL::BinaryQueue queue; + Assert(queue.Size() == 0); + + for (int i=0; i<10; ++i) + { + int value = 12345; + queue.AppendCopy(&value, sizeof(value)); + queue.AppendUnmanaged(malloc(100), 100); + } + + Assert(queue.Size() == 10 * sizeof(int) + 10 * 100); + + for (size_t i = 0; i < 10 * sizeof(int) + 10 * 100; ++i) + { + char buffer[1]; + queue.Flatten(buffer, 1); + + queue.FlattenConsume(NULL, 0); + queue.Flatten(NULL, 0); + queue.FlattenConsume(buffer, 1); + } + +// UNHANDLED_EXCEPTION_HANDLER_BEGIN +// { +// char a; +// queue.FlattenConsume(&a, sizeof(a)); +// } +// UNHANDLED_EXCEPTION_HANDLER_END + + return 0; +} diff --git a/examples/copy/CMakeLists.txt b/examples/copy/CMakeLists.txt new file mode 100644 index 0000000..ace88df --- /dev/null +++ b/examples/copy/CMakeLists.txt @@ -0,0 +1,32 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) +# @version 1.0 +# @brief +# +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(COPY_SYS dpl-gtk REQUIRED) + +SET(COPY_SOURCES + copy.cpp) + +ADD_DEFINITIONS("-D_DEBUG") + +INCLUDE_DIRECTORIES(${COPY_SYS_INCLUDE_DIRS}) +LINK_DIRECTORIES(${COPY_SYS_LIBRARY_DIRS}) + +ADD_EXECUTABLE(copy ${COPY_SOURCES}) +TARGET_LINK_LIBRARIES(copy ${COPY_SYS_LIBRARIES}) diff --git a/examples/copy/copy.cpp b/examples/copy/copy.cpp new file mode 100644 index 0000000..1ab7607 --- /dev/null +++ b/examples/copy/copy.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file copy.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of copy example + */ +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + if (argc != 3 && argc != 4) + { + std::cout << "Invalid parameters: copy [input_file] [output_file] [OPTIONAL: number_of_bytes]" << std::endl; + return -1; + } + UNHANDLED_EXCEPTION_HANDLER_BEGIN + { + DPL::FileInput input(argv[1]); + DPL::FileOutput output(argv[2]); + + if (argc == 3) + DPL::Copy(&input, &output); + else + DPL::Copy(&input, &output, static_cast(atoi(argv[3]))); + } + UNHANDLED_EXCEPTION_HANDLER_END + + return 0; +} diff --git a/examples/crypto_hash/CMakeLists.txt b/examples/crypto_hash/CMakeLists.txt new file mode 100644 index 0000000..e0b0598 --- /dev/null +++ b/examples/crypto_hash/CMakeLists.txt @@ -0,0 +1,32 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) +# @version 1.0 +# @brief +# +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(CRYPTO_HASH_SYS dpl-efl REQUIRED) + +SET(CRYPTO_HASH_SOURCES + crypto_hash.cpp) + +ADD_DEFINITIONS("-D_DEBUG") + +INCLUDE_DIRECTORIES(${CRYPTO_HASH_SYS_INCLUDE_DIRS}) +LINK_DIRECTORIES(${CRYPTO_HASH_SYS_LIBRARY_DIRS}) + +ADD_EXECUTABLE(crypto_hash ${CRYPTO_HASH_SOURCES}) +TARGET_LINK_LIBRARIES(crypto_hash ${CRYPTO_HASH_SYS_LIBRARIES}) diff --git a/examples/crypto_hash/crypto_hash.cpp b/examples/crypto_hash/crypto_hash.cpp new file mode 100644 index 0000000..0fffefa --- /dev/null +++ b/examples/crypto_hash/crypto_hash.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file crypto_hash.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of crypto hash example + */ +#include +#include +#include + +void help() +{ + std::cout << "Invalid parameters: crypto_hash [hash_function] [message]" << std::endl; + std::cout << "hash_function is one of following: MD2, MD4, MD5, SHA, SHA1, DSS, DSS1, ECDSA, SHA224, SHA256, SHA384, SHA512" << std::endl; +} + +int main(int argc, char *argv[]) +{ + if (argc != 3) + { + help(); + return 0; + } + + DPL::Crypto::Hash::Base *crypto; + std::string algorithm = argv[1]; + + if (algorithm == "MD2") + crypto = new DPL::Crypto::Hash::MD2(); + else if (algorithm == "MD4") + crypto = new DPL::Crypto::Hash::MD4(); + else if (algorithm == "MD5") + crypto = new DPL::Crypto::Hash::MD5(); + else if (algorithm == "SHA") + crypto = new DPL::Crypto::Hash::SHA(); + else if (algorithm == "SHA1") + crypto = new DPL::Crypto::Hash::SHA1(); + else if (algorithm == "DSS") + crypto = new DPL::Crypto::Hash::DSS(); + else if (algorithm == "DSS1") + crypto = new DPL::Crypto::Hash::DSS1(); + else if (algorithm == "ECDSA") + crypto = new DPL::Crypto::Hash::ECDSA(); + else if (algorithm == "SHA224") + crypto = new DPL::Crypto::Hash::SHA224(); + else if (algorithm == "SHA256") + crypto = new DPL::Crypto::Hash::SHA256(); + else if (algorithm == "SHA384") + crypto = new DPL::Crypto::Hash::SHA384(); + else if (algorithm == "SHA512") + crypto = new DPL::Crypto::Hash::SHA512(); + else + { + help(); + return 0; + } + + crypto->Append(argv[2]); + crypto->Finish(); + + std::cout << crypto->ToString() << std::endl; + + delete crypto; + + return 0; +} diff --git a/examples/dbus/client-example/CMakeLists.txt b/examples/dbus/client-example/CMakeLists.txt new file mode 100644 index 0000000..1f9241f --- /dev/null +++ b/examples/dbus/client-example/CMakeLists.txt @@ -0,0 +1,24 @@ +cmake_minimum_required(VERSION 2.6) +project(client-example) + +include(FindPkgConfig) + +pkg_check_modules(DEPS + dbus-1 + dpl-efl + dpl-dbus-efl + REQUIRED) + +set(TARGET_NAME "client-example") + +set(SRCS + client-example.cpp) + +include_directories(${DEPS_INCLUDE_DIRS}) + +add_definitions("-std=c++0x") +add_definitions("-DDPL_LOGS_ENABLED") + +add_executable(${TARGET_NAME} ${SRCS}) +target_link_libraries(${TARGET_NAME} ${DEPS_LIBRARIES}) + diff --git a/examples/dbus/client-example/client-example.cpp b/examples/dbus/client-example/client-example.cpp new file mode 100644 index 0000000..964333e --- /dev/null +++ b/examples/dbus/client-example/client-example.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file client-example.h + * @author Tomasz Swierczek (t.swierczek@samsung.com) + * @version 1.0 + * @brief Implementation for simple echo service DBus client. + */ + +#include +#include + +#include + +int main(int argc, char **argv) +{ + DPL::DBus::Client client("/path/to/object", + "org.tizen.EchoService", + "org.tizen.EchoInterface"); + std::string outstr; + client.Call("echo", "Samsung Rocks! Hello World Test!", &outstr); + std::cout << "Returned: " << outstr << std::endl; + exit(0); +} + diff --git a/examples/dbus/server-example/CMakeLists.txt b/examples/dbus/server-example/CMakeLists.txt new file mode 100644 index 0000000..34266e3 --- /dev/null +++ b/examples/dbus/server-example/CMakeLists.txt @@ -0,0 +1,26 @@ +cmake_minimum_required(VERSION 2.6) +project(server-example) + +include(FindPkgConfig) + +pkg_check_modules(DEPS + glib-2.0 + gio-2.0 + dpl-efl + dpl-dbus-efl + REQUIRED) + +set(TARGET_NAME "server-example") + +set(SRCS + server-example.cpp) + +include_directories(${DEPS_INCLUDE_DIRS}) + +add_definitions("-std=c++0x") +add_definitions("-pedantic") +add_definitions("-Wall") +add_definitions("-DDPL_LOGS_ENABLED") + +add_executable(${TARGET_NAME} ${SRCS}) +target_link_libraries(${TARGET_NAME} ${DEPS_LIBRARIES}) \ No newline at end of file diff --git a/examples/dbus/server-example/server-example.cpp b/examples/dbus/server-example/server-example.cpp new file mode 100644 index 0000000..3a54d2a --- /dev/null +++ b/examples/dbus/server-example/server-example.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +std::string xml = +"" +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +""; + +GMainLoop* g_loop = NULL; + +auto g_interfaces = DPL::DBus::Interface::fromXMLString(xml); + +class DBusDispatcher : public DPL::DBus::Dispatcher +{ +public: + void onMethodCall(GDBusConnection *connection, + const gchar *sender, + const gchar *objectPath, + const gchar *interfaceName, + const gchar *methodName, + GVariant *parameters, + GDBusMethodInvocation *invocation) + { + 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 +{ +protected: + void OnEventReceived(const DPL::DBus::ServerEvents::NewConnectionEvent& event) + { + m_connection = event.GetArg0(); + + auto quitInterface = g_interfaces.at(1); + quitInterface->setDispatcher(std::make_shared()); + m_quitObject = DBus::Object::create("/object/quit", quitInterface); + + m_connection->registerObject(m_quitObject); + } + +private: + DPL::DBus::ConnectionPtr m_connection; + DPL::DBus::ObjectPtr m_quitObject; +}; + +int main() +{ + g_type_init(); + + // --------------- echo + auto echoConnection = DPL::DBus::Connection::sessionBus(); + + auto echoInterface = g_interfaces.at(0); + echoInterface->setDispatcher(std::make_shared()); + + auto echoObject = DPL::DBus::Object::create("/object/echo", echoInterface); + + echoConnection->registerObject(echoObject); + + echoConnection->registerService("org.tizen.EchoService"); + + // --------------- quit + std::unique_ptr listener(new NewConnectionListener); + auto server = DPL::DBus::Server::create("unix:abstract=someaddr"); + server->AddListener(listener.get()); + server->start(); + + g_loop = g_main_loop_new(NULL, FALSE); + g_main_loop_run(g_loop); + g_main_loop_unref(g_loop); + + return 0; +} diff --git a/examples/event_delivery_test/CMakeLists.txt b/examples/event_delivery_test/CMakeLists.txt new file mode 100644 index 0000000..1734a80 --- /dev/null +++ b/examples/event_delivery_test/CMakeLists.txt @@ -0,0 +1,34 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author 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}) + + diff --git a/examples/event_delivery_test/event_delivery_test.cpp b/examples/event_delivery_test/event_delivery_test.cpp new file mode 100644 index 0000000..5f0f104 --- /dev/null +++ b/examples/event_delivery_test/event_delivery_test.cpp @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 +#include +#include +#include +#include +#include +#include + +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::Type>, + public DPL::EventListener, + public DPL::EventListener +{ +private: + class OneTimeListener : + public DPL::EventListener + { + public: + OneTimeListener() + { + DPL::EventDeliverySystem::AddListener (this); + } + + ~OneTimeListener() + { + LogError("Deleting OneTimeListener"); + DPL::EventDeliverySystem::RemoveListener (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::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(this); + DPL::EventDeliverySystem::AddListener(this); + + DPL::ControllerEventHandler::PostTimedEvent(CloseEvent(), 8); + oneTimeListener = new OneTimeListener(); + } + + virtual ~MyListener() + { + DPL::EventDeliverySystem::RemoveListener (this); + DPL::EventDeliverySystem::RemoveListener (this); + delete oneTimeListener; + } +}; + +class MyPusher : + public DPL::Application, + private DPL::Controller::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::PostTimedEvent(StartEvent(), 2); + DPL::ControllerEventHandler::PostTimedEvent(StartEvent(), 6); + DPL::ControllerEventHandler::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; +} diff --git a/examples/fake_rpc/CMakeLists.txt b/examples/fake_rpc/CMakeLists.txt new file mode 100644 index 0000000..0778da7 --- /dev/null +++ b/examples/fake_rpc/CMakeLists.txt @@ -0,0 +1,33 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Pawel Sikorski (p.sikorski@samsung.com) +# @version 1.0 +# @brief +# +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(FAKE_RPC_SYS dpl-efl REQUIRED) + +SET(FAKE_RPC_SOURCES + fake_rpc.cpp) + +ADD_DEFINITIONS("-D_DEBUG") +ADD_DEFINITIONS("-DDPL_LOGS_ENABLED") + +INCLUDE_DIRECTORIES(${FAKE_RPC_SYS_INCLUDE_DIRS}) +LINK_DIRECTORIES(${FAKE_RPC_SYS_LIBRARY_DIRS}) + +ADD_EXECUTABLE(fake_rpc ${FAKE_RPC_SOURCES}) +TARGET_LINK_LIBRARIES(fake_rpc ${FAKE_RPC_SYS_LIBRARIES}) diff --git a/examples/fake_rpc/fake_rpc.cpp b/examples/fake_rpc/fake_rpc.cpp new file mode 100644 index 0000000..9750c62 --- /dev/null +++ b/examples/fake_rpc/fake_rpc.cpp @@ -0,0 +1,281 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file rpc.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of RPC example + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// FLOW: +// 1st connection - UnixSockets +// 2nd connection - Fake +// client sends data via fake IPC +// server sends back this data via unix IPC. +// client compare sent and received data + +static const char *UNIX_RPC_NAME = "/tmp/unix_socket_rpc"; +static const char *FAKE_RPC_NAME = "/tmp/fake_rpc"; + +typedef DPL::AbstractRPCConnectionEvents::AsyncCallEvent AsyncCallEvent; +typedef DPL::AbstractRPCConnectionEvents::ConnectionClosedEvent + ConnectionClosedEvent; +typedef DPL::AbstractRPCConnectionEvents::ConnectionBrokenEvent + ConnectionBrokenEvent; +typedef DPL::AbstractRPCConnectorEvents::ConnectionEstablishedEvent + ConnectionEstablishedEvent; + +class MyThread + : public DPL::Thread, + private DPL::EventListener, + private DPL::EventListener +{ +private: + DPL::UnixSocketRPCClient m_rpcUnixClient; + DPL::FakeRpcClient m_rpcFakeClient; + int m_connections; + int m_sentData; + int m_receivedData; + + DPL::ScopedPtr m_rpcUnixConnection; + DPL::ScopedPtr 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(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::AddListener(this); + } + else{ + ++m_connections; + LogInfo("CLIENT: Acquiring new unix connection"); + m_rpcUnixConnection.Reset(event.GetArg1()); + m_rpcUnixConnection->DPL::EventSupport::AddListener(this); + } + if(m_connections == 2){ + m_sentData = 1213; + // Emit RPC function call + DPL::RPCFunction proc; + proc.AppendArg(m_sentData); + 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::AddListener(this); + m_rpcFakeClient.DPL::EventSupport::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::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::RemoveListener(this); + m_rpcFakeConnection.Reset(); + } + + // Detach RPC client listener + LogInfo("CLIENT: Detaching connection established event"); + m_rpcUnixClient.DPL::EventSupport::RemoveListener(this); + m_rpcFakeClient.DPL::EventSupport::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::Type>, + private DPL::EventListener, + private DPL::EventListener +{ +private: + DPL::UnixSocketRPCServer m_rpcUnixServer; + DPL::FakeRpcServer m_rpcFakeServer; + + DPL::ScopedPtr m_rpcUnixConnection; + DPL::ScopedPtr 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::RemoveListener(this); + m_rpcUnixConnection.Reset(); + } + + if (m_rpcFakeConnection.Get()) { + m_rpcFakeConnection->DPL::EventSupport::RemoveListener(this); + m_rpcFakeConnection.Reset(); + } + + LogInfo("SERVER: Closing Server"); + m_rpcUnixServer.CloseAll(); + m_rpcFakeServer.CloseAll();//not needed + m_rpcUnixServer.DPL::EventSupport::RemoveListener(this); + m_rpcFakeServer.DPL::EventSupport::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(event.GetArg1())){ + LogInfo("SERVER: Acquiring Fake RPC connection"); + m_rpcFakeConnection.Reset(event.GetArg1()); + m_rpcFakeConnection->DPL::EventSupport::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::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::AddListener(this); + m_rpcFakeServer.DPL::EventSupport::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::PostTimedEvent(CloseThreadEvent(), 2); + DPL::ControllerEventHandler::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(); +} diff --git a/examples/metronome/CMakeLists.txt b/examples/metronome/CMakeLists.txt new file mode 100644 index 0000000..b5d1017 --- /dev/null +++ b/examples/metronome/CMakeLists.txt @@ -0,0 +1,38 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) +# @version 1.0 +# @brief +# +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(METRONOME_SYS dpl-efl REQUIRED) + +SET(METRONOME_CLIENT_SOURCES + metronome_client.cpp) + +SET(METRONOME_SERVER_SOURCES + metronome_server.cpp) + +ADD_DEFINITIONS("-D_DEBUG") + +INCLUDE_DIRECTORIES(${METRONOME_SYS_INCLUDE_DIRS}) +LINK_DIRECTORIES(${METRONOME_SYS_LIBRARY_DIRS}) + +ADD_EXECUTABLE(metronome_client ${METRONOME_CLIENT_SOURCES}) +TARGET_LINK_LIBRARIES(metronome_client ${METRONOME_SYS_LIBRARIES}) + +ADD_EXECUTABLE(metronome_server ${METRONOME_SERVER_SOURCES}) +TARGET_LINK_LIBRARIES(metronome_server ${METRONOME_SYS_LIBRARIES}) diff --git a/examples/metronome/metronome_client.cpp b/examples/metronome/metronome_client.cpp new file mode 100644 index 0000000..2411d09 --- /dev/null +++ b/examples/metronome/metronome_client.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file metronome_client.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of metronome client example + */ +#include +#include +#include +#include + +class MetronomeClientApplication + : public DPL::Application, + private DPL::EventListener, + private DPL::EventListener, + private DPL::EventListener, + private DPL::EventListener +{ +private: + DPL::TcpSocketRPCClient m_rpcClient; + DPL::ScopedPtr 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::AddListener(this); + m_rpcConnection->DPL::EventSupport::AddListener(this); + m_rpcConnection->DPL::EventSupport::AddListener(this); + } + +public: + MetronomeClientApplication(int argc, char **argv) + : Application(argc, argv, "rpc") + { + // Attach RPC server listeners + m_rpcClient.DPL::EventSupport::AddListener(this); + + // Open RPC server + m_rpcClient.Open("127.0.0.1", 12345); + + // Started + LogInfo("Metronome client started"); + } + + virtual ~MetronomeClientApplication() + { + // Delete all RPC connections + if (m_rpcConnection.Get()) + { + m_rpcConnection->DPL::EventSupport::RemoveListener(this); + m_rpcConnection->DPL::EventSupport::RemoveListener(this); + m_rpcConnection->DPL::EventSupport::RemoveListener(this); + m_rpcConnection.Reset(); + } + + // Close RPC server + m_rpcClient.CloseAll(); + + // Detach RPC server listener + m_rpcClient.DPL::EventSupport::RemoveListener(this); + } +}; + +int main(int argc, char *argv[]) +{ + return MetronomeClientApplication(argc, argv).Exec(); +} diff --git a/examples/metronome/metronome_server.cpp b/examples/metronome/metronome_server.cpp new file mode 100644 index 0000000..7efa458 --- /dev/null +++ b/examples/metronome/metronome_server.cpp @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file metronome_server.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of metronome server example + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Metronome signal event +DECLARE_GENERIC_EVENT_0(SignalEvent) +DECLARE_GENERIC_EVENT_1(DeleteConnectionEvent, DPL::AbstractRPCConnection *) + +// Heart beat interval +const double HEART_BEAT_INTERVAL = 1.0; // seconds + +class MetronomeServerApplication + : public DPL::Application, + private DPL::Controller::Type>, + private DPL::EventListener, + private DPL::EventListener, + private DPL::EventListener +{ +private: + DPL::TcpSocketRPCServer m_rpcServer; + + typedef std::list ConnectionList; + ConnectionList m_connections; + + // Matronome signal received + virtual void OnEventReceived(const SignalEvent &event) + { + (void)event; + + // Signal all conection about heart beat + DPL::RPCFunction proc; + proc.AppendArg((int)0); + + for (ConnectionList::iterator it = m_connections.begin(); it != m_connections.end(); ++it) + (*it)->AsyncCall(proc); + + // Continue to emot heart beats + DPL::ControllerEventHandler::PostTimedEvent(SignalEvent(), HEART_BEAT_INTERVAL); + } + + virtual void OnEventReceived(const DeleteConnectionEvent &event) + { + delete event.GetArg0(); + } + + void RemoveConnection(DPL::AbstractRPCConnection *connection) + { + // Find connection + ConnectionList::iterator it = std::find(m_connections.begin(), m_connections.end(), connection); + Assert(it != m_connections.end()); + + // Erase connection + m_connections.erase(it); + + // Detach RPC connection listeners + connection->DPL::EventSupport::RemoveListener(this); + connection->DPL::EventSupport::RemoveListener(this); + + // Delete connection + DPL::ControllerEventHandler::PostEvent(DeleteConnectionEvent(connection)); + } + + void AddConnection(DPL::AbstractRPCConnection *connection) + { + // Add connection + m_connections.push_back(connection); + + // Attach event listeners + connection->DPL::EventSupport::AddListener(this); + connection->DPL::EventSupport::AddListener(this); + } + + virtual void OnEventReceived(const DPL::AbstractRPCConnectionEvents::ConnectionClosedEvent &event) + { + (void)event; + + LogInfo("Connection closed"); + + // Remove connection from list + RemoveConnection(static_cast(event.GetSender())); + } + + virtual void OnEventReceived(const DPL::AbstractRPCConnectionEvents::ConnectionBrokenEvent &event) + { + (void)event; + + LogInfo("Connection broken"); + + // Remove connection from list + RemoveConnection(static_cast(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::AddListener(this); + + // Inherit calling context + Touch(); + + // Open RPC server + m_rpcServer.Open(12345); + + // Start heart beat + DPL::ControllerEventHandler::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::RemoveListener(this); + } +}; + +int main(int argc, char *argv[]) +{ + return MetronomeServerApplication(argc, argv).Exec(); +} diff --git a/examples/rpc/CMakeLists.txt b/examples/rpc/CMakeLists.txt new file mode 100644 index 0000000..d9c7d57 --- /dev/null +++ b/examples/rpc/CMakeLists.txt @@ -0,0 +1,32 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) +# @version 1.0 +# @brief +# +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(RPC_SYS dpl-efl REQUIRED) + +SET(RPC_SOURCES + rpc.cpp) + +ADD_DEFINITIONS("-D_DEBUG") + +INCLUDE_DIRECTORIES(${RPC_SYS_INCLUDE_DIRS}) +LINK_DIRECTORIES(${RPC_SYS_LIBRARY_DIRS}) + +ADD_EXECUTABLE(rpc ${RPC_SOURCES}) +TARGET_LINK_LIBRARIES(rpc ${RPC_SYS_LIBRARIES}) diff --git a/examples/rpc/rpc.cpp b/examples/rpc/rpc.cpp new file mode 100644 index 0000000..833a20f --- /dev/null +++ b/examples/rpc/rpc.cpp @@ -0,0 +1,274 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file rpc.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of RPC example + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const char *RPC_NAME = "/tmp/unix_socket_rpc"; + +class MyThread + : public DPL::Thread, + private DPL::EventListener, + private DPL::EventListener, + private DPL::EventListener, + private DPL::EventListener +{ +private: + DPL::UnixSocketRPCClient m_rpcClient; + DPL::ScopedPtr 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::AddListener(this); + m_rpcConnection->DPL::EventSupport::AddListener(this); + m_rpcConnection->DPL::EventSupport::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::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::RemoveListener(this); + m_rpcConnection->DPL::EventSupport::RemoveListener(this); + m_rpcConnection->DPL::EventSupport::RemoveListener(this); + + LogInfo("CLIENT: Resetting connection"); + m_rpcConnection.Reset(); + } + + // Detach RPC client listener + LogInfo("CLIENT: Detaching connection established event"); + m_rpcClient.DPL::EventSupport::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::Type>, + private DPL::EventListener, + private DPL::EventListener, + private DPL::EventListener, + private DPL::EventListener +{ +private: + DPL::UnixSocketRPCServer m_rpcServer; + DPL::ScopedPtr 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::RemoveListener(this); + m_rpcConnection->DPL::EventSupport::RemoveListener(this); + m_rpcConnection->DPL::EventSupport::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::AddListener(this); + m_rpcConnection->DPL::EventSupport::AddListener(this); + m_rpcConnection->DPL::EventSupport::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::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::PostTimedEvent(CloseThreadEvent(), 2); + DPL::ControllerEventHandler::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::RemoveListener(this); + } +}; + +int main(int argc, char *argv[]) +{ + LogInfo("Starting"); + MyApplication app(argc, argv); + return app.Exec(); +} diff --git a/examples/simple/CMakeLists.txt b/examples/simple/CMakeLists.txt new file mode 100644 index 0000000..42020ec --- /dev/null +++ b/examples/simple/CMakeLists.txt @@ -0,0 +1,32 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) +# @version 1.0 +# @brief +# +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(SIMPLE_SYS dpl-gtk REQUIRED) + +SET(SIMPLE_SOURCES + simple.cpp) + +ADD_DEFINITIONS("-D_DEBUG") + +INCLUDE_DIRECTORIES(${SIMPLE_SYS_INCLUDE_DIRS}) +LINK_DIRECTORIES(${SIMPLE_SYS_LIBRARY_DIRS}) + +ADD_EXECUTABLE(simple ${SIMPLE_SOURCES}) +TARGET_LINK_LIBRARIES(simple ${SIMPLE_SYS_LIBRARIES}) diff --git a/examples/simple/simple.cpp b/examples/simple/simple.cpp new file mode 100644 index 0000000..e09af81 --- /dev/null +++ b/examples/simple/simple.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file simple.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of simple example + */ +#include + +int main(int argc, char *argv[]) +{ + (void)argc; + (void)argv; + LogInfo("Hello world!"); + return 0; +} + diff --git a/examples/single_instance/CMakeLists.txt b/examples/single_instance/CMakeLists.txt new file mode 100644 index 0000000..3c29cc6 --- /dev/null +++ b/examples/single_instance/CMakeLists.txt @@ -0,0 +1,32 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) +# @version 1.0 +# @brief +# +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(RPC_SYS dpl-efl REQUIRED) + +SET(RPC_SOURCES + single_instance.cpp) + +ADD_DEFINITIONS("-D_DEBUG") + +INCLUDE_DIRECTORIES(${RPC_SYS_INCLUDE_DIRS}) +LINK_DIRECTORIES(${RPC_SYS_LIBRARY_DIRS}) + +ADD_EXECUTABLE(single_instance ${RPC_SOURCES}) +TARGET_LINK_LIBRARIES(single_instance ${RPC_SYS_LIBRARIES}) diff --git a/examples/single_instance/single_instance.cpp b/examples/single_instance/single_instance.cpp new file mode 100644 index 0000000..cadb4f4 --- /dev/null +++ b/examples/single_instance/single_instance.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file single_instance.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of single instance example + */ +#include +#include + +int main(int argc, char *argv[]) +{ + if (argc != 2) + { + std::cout << "Specify instance name!" << std::endl; + return 0; + } + + DPL::SingleInstance singleInstance; + + if (singleInstance.TryLock(argv[1])) + { + std::cout << "Succedded to lock single instance." << std::endl << "Press ENTER to release lock..." << std::endl; + + // Wait for any key + getchar(); + + // Release gathered lock + singleInstance.Release(); + + // Done + return 0; + } + + std::cout << "Cannot retrieve single instance lock." << std::endl + << "Another application has locked single instance." << std::endl + << "Will now exit." << std::endl; + + // Done + return 0; +} diff --git a/examples/socket/CMakeLists.txt b/examples/socket/CMakeLists.txt new file mode 100644 index 0000000..9fe5009 --- /dev/null +++ b/examples/socket/CMakeLists.txt @@ -0,0 +1,32 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) +# @version 1.0 +# @brief +# +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(SOCKET_SYS dpl-efl REQUIRED) + +SET(SOCKET_SOURCES + socket.cpp) + +ADD_DEFINITIONS("-D_DEBUG") + +INCLUDE_DIRECTORIES(${SOCKET_SYS_INCLUDE_DIRS}) +LINK_DIRECTORIES(${SOCKET_SYS_LIBRARY_DIRS}) + +ADD_EXECUTABLE(socket ${SOCKET_SOURCES}) +TARGET_LINK_LIBRARIES(socket ${SOCKET_SYS_LIBRARIES}) diff --git a/examples/socket/socket.cpp b/examples/socket/socket.cpp new file mode 100644 index 0000000..c8a2894 --- /dev/null +++ b/examples/socket/socket.cpp @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file socket.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of socket example + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace // anonymous +{ +static const char *SOCKET_NAME = "/tmp/unix_sock"; +} // namespace anonymous + +class MyThread + : public DPL::Thread, + private DPL::EventListener +{ +private: + DPL::UnixSocket m_socket; + + // Socket accept event + virtual void OnEventReceived(const DPL::AbstractSocketEvents::AcceptEvent &event) + { + (void)event; + LogInfo("Accept event occurred"); + + DPL::UnixSocket *client = static_cast(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::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::RemoveListener(this); + + // Must close socket in same context + m_socket.Close(); + + return result; + } +}; + +DECLARE_GENERIC_EVENT_0(QuitEvent) + +class MyApplication + : public DPL::Application, + public DPL::Controller::Type>, + private DPL::EventListener +{ +private: + MyThread thread; + DPL::UnixSocket sock; + + // Quit application event occurred + virtual void OnEventReceived(const QuitEvent &event) + { + (void)event; + Quit(); + } + + // Socket connected event + virtual void OnEventReceived(const DPL::AbstractSocketEvents::ConnectedEvent &event) + { + (void)event; + LogInfo("Connected event occurred"); + } + +public: + MyApplication(int argc, char **argv) + : Application(argc, argv, "example_socket_application") + { + // Add listeners + sock.DPL::EventSupport::AddListener(this); + + // Touch self controller + Touch(); + + // Start threaded server + 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::PostTimedEvent(QuitEvent(), 2); + } + + virtual ~MyApplication() + { + // Remove listeners + sock.DPL::EventSupport::RemoveListener(this); + } +}; + +int main(int argc, char *argv[]) +{ + MyApplication app(argc, argv); + return app.Exec(); +} diff --git a/examples/tcpsock/CMakeLists.txt b/examples/tcpsock/CMakeLists.txt new file mode 100644 index 0000000..a6550fc --- /dev/null +++ b/examples/tcpsock/CMakeLists.txt @@ -0,0 +1,32 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) +# @version 1.0 +# @brief +# +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(TCPSOCK_SYS dpl-efl REQUIRED) + +SET(TCPSOCK_SOURCES + tcpsock.cpp) + +ADD_DEFINITIONS("-D_DEBUG") + +INCLUDE_DIRECTORIES(${TCPSOCK_SYS_INCLUDE_DIRS}) +LINK_DIRECTORIES(${TCPSOCK_SYS_LIBRARY_DIRS}) + +ADD_EXECUTABLE(tcpsock ${TCPSOCK_SOURCES}) +TARGET_LINK_LIBRARIES(tcpsock ${TCPSOCK_SYS_LIBRARIES}) diff --git a/examples/tcpsock/tcpsock.cpp b/examples/tcpsock/tcpsock.cpp new file mode 100644 index 0000000..c2697cd --- /dev/null +++ b/examples/tcpsock/tcpsock.cpp @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file tcpsock.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of tcpsock example + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class MyApplication + : public DPL::Application, + private DPL::EventListener, + private DPL::EventListener +{ +private: + DPL::TcpSocket m_socket; + + virtual void OnEventReceived(const DPL::AbstractSocketEvents::ConnectedEvent &event) + { + (void)event; + 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 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::AddListener(this); + m_socket.DPL::EventSupport::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::RemoveListener(this); + m_socket.DPL::EventSupport::RemoveListener(this); + } +}; + +int main(int argc, char *argv[]) +{ + MyApplication app(argc, argv); + return app.Exec(); +} diff --git a/examples/timed_event/CMakeLists.txt b/examples/timed_event/CMakeLists.txt new file mode 100644 index 0000000..cb60fb0 --- /dev/null +++ b/examples/timed_event/CMakeLists.txt @@ -0,0 +1,32 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) +# @version 1.0 +# @brief +# +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(RPC_SYS dpl-efl REQUIRED) + +SET(RPC_SOURCES + timed_event.cpp) + +ADD_DEFINITIONS("-D_DEBUG") + +INCLUDE_DIRECTORIES(${RPC_SYS_INCLUDE_DIRS}) +LINK_DIRECTORIES(${RPC_SYS_LIBRARY_DIRS}) + +ADD_EXECUTABLE(timed_event ${RPC_SOURCES}) +TARGET_LINK_LIBRARIES(timed_event ${RPC_SYS_LIBRARIES}) diff --git a/examples/timed_event/timed_event.cpp b/examples/timed_event/timed_event.cpp new file mode 100644 index 0000000..28c74a4 --- /dev/null +++ b/examples/timed_event/timed_event.cpp @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file timed_event.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of timed event example + */ +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GENERIC_EVENT_0(FirstEvent) +DECLARE_GENERIC_EVENT_0(SecondEvent) + +class ControllerInThread + : public DPL::Controller::Type> +{ +protected: + virtual void OnEventReceived(const FirstEvent &event) + { + (void)event; + 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::Type> +{ +private: + DPL::Thread m_thread; + ControllerInThread m_controllerInThread; + + // Quit application event occurred + virtual void OnEventReceived(const QuitEvent &event) + { + (void)event; + Quit(); + } + +public: + MyApplication(int argc, char **argv) + : Application(argc, argv, "timed_event", false) + { + // Touch + Touch(); + m_controllerInThread.Touch(); + + // Run thread + m_thread.Run(); + m_controllerInThread.SwitchToThread(&m_thread); + + // Emit thread timed events + m_controllerInThread.DPL::ControllerEventHandler::PostTimedEvent(SecondEvent(), 3); + m_controllerInThread.DPL::ControllerEventHandler::PostTimedEvent(FirstEvent(), 2); + + // Emit framework timed quit event + DPL::ControllerEventHandler::PostTimedEvent(QuitEvent(), 5); + } + + virtual ~MyApplication() + { + m_controllerInThread.SwitchToThread(NULL); + + // Quit thread + m_thread.Quit(); + } +}; + +int main(int argc, char *argv[]) +{ + MyApplication app(argc, argv); + return app.Exec(); +} diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt new file mode 100644 index 0000000..7d34aaf --- /dev/null +++ b/modules/CMakeLists.txt @@ -0,0 +1,35 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# @file 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) diff --git a/modules/ace/CMakeLists.txt b/modules/ace/CMakeLists.txt new file mode 100644 index 0000000..358ba76 --- /dev/null +++ b/modules/ace/CMakeLists.txt @@ -0,0 +1,169 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 + ) + diff --git a/modules/ace/DESCRIPTION b/modules/ace/DESCRIPTION new file mode 100644 index 0000000..aac5ef6 --- /dev/null +++ b/modules/ace/DESCRIPTION @@ -0,0 +1,2 @@ +!!!options!!! stop +ACE - Access Control Engine - security module for Device APIs diff --git a/modules/ace/configuration/UnrestrictedPolicy.xml b/modules/ace/configuration/UnrestrictedPolicy.xml new file mode 100644 index 0000000..558f2dc --- /dev/null +++ b/modules/ace/configuration/UnrestrictedPolicy.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/modules/ace/configuration/WACPolicy.xml b/modules/ace/configuration/WACPolicy.xml new file mode 100644 index 0000000..f2c9236 --- /dev/null +++ b/modules/ace/configuration/WACPolicy.xml @@ -0,0 +1,520 @@ + + + + + + + + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + asdfkjlhxvczxnbcvnjahfjhsdfklahfdas + + + +

PValue

QValue Gvalue laj? +
+ + + modulus + + + exponent + + +
+ + Subject name + SKI + +
+
+ + + + + + + + + Identified + + + + + + + + http://jil.org/jil/api/1.1/devicestateinfo.DeviceStateInfo.requestPositionInfo + + + + + + + http://jil.org/jil/api/1.1/widget.Widget.openURL + + + http://jil.org/jil/api/1.1/addressbookitem.AddressBookItem.update + + + http://jil.org/jil/api/1.1/device.Device.launchApplication + + + http://jil.org/jil/api/1.1/multimedia.Camera.captureImage + + + http://jil.org/jil/api/1.1/messaging.Messaging.sendMessage + + + http://jil.org/jil/api/1.1.1/pim.PIM.findAddressBookItems + + + http://jil.org/jil/api/1.1.1/pim.PIM.getAddressBookItem + + + http://jil.org/jil/api/1.1.1/pim.PIM.getAddressBookItemsCount + + + + + + + + http://jil.org/jil/api/1.1/device.Device.getAvailableApplications + + + http://jil.org/jil/api/1.1/addressbookitem.AddressBookItem.getAttributeValue + + + http://jil.org/jil/api/1.1/addressbookitem.AddressBookItem.getAvailableAttributes + + + http://jil.org/jil/api/1.1/addressbookitem.AddressBookItem.setAttributeValue + + + http://jil.org/jil/api/1.1/multimedia.AudioPlayer.open + + + http://jil.org/jil/api/1.1/multimedia.AudioPlayer.play + + + http://jil.org/jil/api/1.1/multimedia.AudioPlayer.pause + + + http://jil.org/jil/api/1.1/multimedia.AudioPlayer.resume + + + http://jil.org/jil/api/1.1/multimedia.AudioPlayer.stop + + + http://jil.org/jil/api/1.1/multimedia.AudioPlayer.onStateChange + + + http://jil.org/jil/api/1.1/multimedia.Camera.onCameraCaptured + + + http://jil.org/jil/api/1.1/multimedia.Camera.setWindow + + + http://jil.org/jil/api/1.1/device.Device.PositionInfo + + + http://jil.org/jil/api/1.1/device.Device.DeviceStateInfo + + + http://jil.org/jil/api/1.1/devicestateinfo.DeviceStateInfo.onPositionRetrieved + + + http://jil.org/jil/api/1.1/messaging.Messaging.createMessage + + + http://jil.org/jil/api/1.1/messaging.Messaging.onMessageSendingFailure + + + http://jil.org/jil/api/1.1/multimedia.Multimedia.getVolume + + + http://jil.org/jil/api/1.1/multimedia.Multimedia.stopAll + + + http://jil.org/jil/api/1.1/multimedia.Multimedia.isAudioPlaying + + + http://jil.org/jil/api/1.1.1/pim.PIM.createAddressBookItem + + + http://jil.org/jil/api/1.1.1/pim.PIM.onAddressBookItemFound + + + http://jil.org/jil/api/1.1/accelerometerinfo + + + http://jil.org/jil/api/1.1/addressbookitem + + + http://jil.org/jil/api/1.1.5/applicationtypes + + + http://jil.org/jil/api/1.1.2/camera + + + http://jil.org/jil/api/1.1/device + + + http://jil.org/jil/api/1.1/devicestateinfo + + + http://jil.org/jil/api/1.1.5/exception + + + http://jil.org/jil/api/1.1.5/exceptiontypes + + + http://jil.org/jil/api/1.1/message + + + http://jil.org/jil/api/1.1/messagetypes + + + http://jil.org/jil/api/1.1/messaging + + + http://jil.org/jil/api/1.1/multimedia + + + http://jil.org/jil/api/1.1.1/pim + + + http://jil.org/jil/api/1.1/positioninfo + + + http://jil.org/jil/api/1.1/widget + + + + + + + + + + + + Operator + + + + + + + + + +
diff --git a/modules/ace/configuration/bondixml.xsd b/modules/ace/configuration/bondixml.xsd new file mode 100644 index 0000000..d16a14d --- /dev/null +++ b/modules/ace/configuration/bondixml.xsd @@ -0,0 +1,184 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/ace/configuration/config.dtd b/modules/ace/configuration/config.dtd new file mode 100644 index 0000000..f483631 --- /dev/null +++ b/modules/ace/configuration/config.dtd @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/modules/ace/configuration/config.xml b/modules/ace/configuration/config.xml new file mode 100644 index 0000000..278081a --- /dev/null +++ b/modules/ace/configuration/config.xml @@ -0,0 +1,10 @@ + + + + /usr/etc/ace/ + + demo.xml + + + + diff --git a/modules/ace/configuration/demo.xml b/modules/ace/configuration/demo.xml new file mode 100644 index 0000000..4c4f423 --- /dev/null +++ b/modules/ace/configuration/demo.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/modules/ace/dao/AceDAO.cpp b/modules/ace/dao/AceDAO.cpp new file mode 100644 index 0000000..155c979 --- /dev/null +++ b/modules/ace/dao/AceDAO.cpp @@ -0,0 +1,368 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 + +#include +#include +#include +#include +#include +#include +#include +#include + +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(userParam), + Equals(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(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(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(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 e1(handler); + Equals 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(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(DPL::FromUTF8String( + *(*iter)->getName()))); + std::list 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 &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"); + } +} + + +} diff --git a/modules/ace/dao/AceDAOConversions.cpp b/modules/ace/dao/AceDAOConversions.cpp new file mode 100644 index 0000000..5254112 --- /dev/null +++ b/modules/ace/dao/AceDAOConversions.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * + * + * @file AceDaoConversions.h + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @author Grzegorz Krawczyk (g.krawczyk@samsung.com) + * @version 0.1 + * @brief + */ + +#include +#include + +#include + +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(attrHash[i])); + } + return DPL::FromASCIIString(attrHashCoded); +} + + +} diff --git a/modules/ace/dao/AceDAOReadOnly.cpp b/modules/ace/dao/AceDAOReadOnly.cpp new file mode 100644 index 0000000..1f1b617 --- /dev/null +++ b/modules/ace/dao/AceDAOReadOnly.cpp @@ -0,0 +1,338 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 +#include +#include +#include + +#include + +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(hash), + Equals(DPLParam))); + + std::list 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 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 e1(attrHash); + select->Where(e1); + + std::list 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 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 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(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(resourceId), + Equals(handler))); + + std::list values = + select->GetValueList(); + 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 *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(widgetHandle)); + std::list devCapNames = + select->GetValueList(); + permissions->insert(devCapNames.begin(), devCapNames.end()); + transaction.Commit(); + } Catch(DPL::DB::SqlConnection::Exception::Base) { + ReThrowMsg(Exception::DatabaseError, "Failed to getStaticDevCapPermissions"); + } +} +} diff --git a/modules/ace/dao/AceDAOUtilities.cpp b/modules/ace/dao/AceDAOUtilities.cpp new file mode 100644 index 0000000..1f8c95e --- /dev/null +++ b/modules/ace/dao/AceDAOUtilities.cpp @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 +#include +#include + +#include +#include +#include + +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(DPL::FromUTF8String(uri))); + std::list 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(DPL::FromUTF8String(uri))); + std::list rows = select->GetRowList(); + if (rows.empty()) { + return false; + } + + row = rows.front(); + return true; +} + + +} diff --git a/modules/ace/dao/AceDatabase.cpp b/modules/ace/dao/AceDatabase.cpp new file mode 100644 index 0000000..110f791 --- /dev/null +++ b/modules/ace/dao/AceDatabase.cpp @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file AceDatabase.cpp + * @author Lukasz Marek (l.marek@samsung.com) + * @version 1.0 + * @brief This file contains the declaration of ace database + */ + +#include + +DPL::Mutex g_aceDbQueriesMutex; diff --git a/modules/ace/dao/BaseAttribute.cpp b/modules/ace/dao/BaseAttribute.cpp new file mode 100644 index 0000000..095e2f5 --- /dev/null +++ b/modules/ace/dao/BaseAttribute.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * + * + * @file BaseAttribute.cpp + * @author Lukasz Marek (l.marek@samsung.com) + * @version 0.1 + * @brief + */ + +#include +#include + +#include + +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::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; +} + +} diff --git a/modules/ace/dao/CMakeLists.txt b/modules/ace/dao/CMakeLists.txt new file mode 100644 index 0000000..a19dcae --- /dev/null +++ b/modules/ace/dao/CMakeLists.txt @@ -0,0 +1,110 @@ + +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 +) diff --git a/modules/ace/dao/PromptModel.cpp b/modules/ace/dao/PromptModel.cpp new file mode 100644 index 0000000..d3c82a0 --- /dev/null +++ b/modules/ace/dao/PromptModel.cpp @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* @file PromptModel.cpp + * @author Justyna Mejzner (j.kwiatkowsk@samsung.com) + * @author Jaroslaw Osmanski (j.osmanski@samsung.com) + * @version 1.0 + * + */ + +#include + +#include +#include +#include + +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 += "
"; + strLabel += resourceId; + + return new Prompt::PromptLabels(promptType, aceQuestionLabel, strLabel); +} + +Prompt::Validity fromPromptTypeToValidity(int aPromptType, bool checkClicked) +{ + using namespace Prompt; + PromptModel::PromptType promptTypeEnum = + static_cast(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 diff --git a/modules/ace/dao/common_dao_types.cpp b/modules/ace/dao/common_dao_types.cpp new file mode 100644 index 0000000..94e1222 --- /dev/null +++ b/modules/ace/dao/common_dao_types.cpp @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * + * @file 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 + +#include + +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 diff --git a/modules/ace/engine/Attribute.cpp b/modules/ace/engine/Attribute.cpp new file mode 100644 index 0000000..45a8221 --- /dev/null +++ b/modules/ace/engine/Attribute.cpp @@ -0,0 +1,913 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +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 *first, + const std::list *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::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::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(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 & attrs) +{ + if (attrs.empty()) { + LogWarning("Empty attribute set"); + } else { + LogDebug("PRINT ATTRIBUTES:"); + for (std::list::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 } diff --git a/modules/ace/engine/CombinerImpl.cpp b/modules/ace/engine/CombinerImpl.cpp new file mode 100644 index 0000000..ccc3c9b --- /dev/null +++ b/modules/ace/engine/CombinerImpl.cpp @@ -0,0 +1,445 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 +#include + +#include +#include +#include + +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 * CombinerImpl::convertEffectsToInts( + const std::list * effects) +{ + std::list * intList = new std::list(); + for ( + std::list::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 & effects) +{ + if (isError(effects)) { + return Error; + } + + std::list * intList = convertEffectsToInts(&effects); + + int result = InapplicableInt; //Deny has value 0, Undetermined value 1, Inapplicable value 6 + + std::list::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 & effects) //mb jk modified +{ if (isError(effects)) { + return Error; + } + + int result = DenyInt; //Deny has value 0, Inapplicable value 5 + std::list * intList = convertEffectsToInts(&effects); + std::list::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 & effects) //jk mb modified to comply with BONDI 1.0 ("undetermined" handling) +{ std::list::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 & 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 & effects) +{ + FOREACH(it, effects) + { + if (Error == *it) { + return true; + } + } + return false; +} + +Effect CombinerImpl::combineRules(const TreeNode * policy) +{ + const Policy * policyObj = dynamic_cast(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 effects; + + while (it != children.end()) { + const Rule * rule = dynamic_cast((*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(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 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 & 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 * subjectsList, + bool &isUndetermined) +{ + if (subjectsList->empty()) { + return true; + } + + std::list::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; +} diff --git a/modules/ace/engine/Condition.cpp b/modules/ace/engine/Condition.cpp new file mode 100644 index 0000000..739e58a --- /dev/null +++ b/modules/ace/engine/Condition.cpp @@ -0,0 +1,265 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 +#include +#include +#include +#include + +/** + * 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* 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* 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::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::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; +} + diff --git a/modules/ace/engine/ConfigurationManager.cpp b/modules/ace/engine/ConfigurationManager.cpp new file mode 100644 index 0000000..9cc7cd7 --- /dev/null +++ b/modules/ace/engine/ConfigurationManager.cpp @@ -0,0 +1,422 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include +#include +#include +#include + +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(text); + xmlFree(text); +} + +void ConfigurationManager::processNode(void) +{ + xmlReaderTypes type = + static_cast(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(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 << "" << std::endl; + output << + "" << + std::endl; + output << "" << std::endl; + output << " " << storagePath << "" << + std::endl; + output << " " << std::endl; + for (list::const_iterator it = policyFiles.begin(); + it != policyFiles.end(); + ++it) { + output << "\t" << *it << "" << std::endl; + } + output << " \n"; + output << " "; + 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; +} diff --git a/modules/ace/engine/NodeFactory.cpp b/modules/ace/engine/NodeFactory.cpp new file mode 100644 index 0000000..a0b93f1 --- /dev/null +++ b/modules/ace/engine/NodeFactory.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include + +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; +} diff --git a/modules/ace/engine/Policy.cpp b/modules/ace/engine/Policy.cpp new file mode 100644 index 0000000..1b47a89 --- /dev/null +++ b/modules/ace/engine/Policy.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// +// +// +// @ Project : Access Control Engine +// @ File Name : Policy.cpp +// @ Date : 2009-05-06 +// @ Author : Samsung +// +// + +#include +#include + +Policy::Policy(std::istream& is) +{ + Serializer* serializer = Serializer::getInstance(); + + std::list* 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::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"; + } +} diff --git a/modules/ace/engine/PolicyEnforcementPoint.cpp b/modules/ace/engine/PolicyEnforcementPoint.cpp new file mode 100644 index 0000000..d593f02 --- /dev/null +++ b/modules/ace/engine/PolicyEnforcementPoint.cpp @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +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(); +} diff --git a/modules/ace/engine/PolicyEvaluator.cpp b/modules/ace/engine/PolicyEvaluator.cpp new file mode 100644 index 0000000..609d0fc --- /dev/null +++ b/modules/ace/engine/PolicyEvaluator.cpp @@ -0,0 +1,447 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 +#include + +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include + +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(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_iterator it = + policy->getSubjects()->begin(); + for (; it != policy->getSubjects()->end(); ++it) + { + const std::list & 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::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(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(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"; + } +} diff --git a/modules/ace/engine/PolicyInformationPoint.cpp b/modules/ace/engine/PolicyInformationPoint.cpp new file mode 100644 index 0000000..8727d30 --- /dev/null +++ b/modules/ace/engine/PolicyInformationPoint.cpp @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 + +#include +#include + +#include +#include + +#include +#include + +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; + } + } +} + diff --git a/modules/ace/engine/Rule.cpp b/modules/ace/engine/Rule.cpp new file mode 100644 index 0000000..3fe4051 --- /dev/null +++ b/modules/ace/engine/Rule.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// +// +// +// @ Project : Access Control Engine +// @ File Name : Rule.h +// @ Date : 2009-05-06 +// @ Author : Samsung +// +// + +#include +#include + +#include +#include + +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 "<deserializeCondition(is); + effect = serializer->deserializeEffect(is); +} + +void Rule::serialize(std::ostream& os) +{ + Serializer* serializer = Serializer::getInstance(); + + serializer->serializeCondition(os, condition); + serializer->serializeEffect(os, effect); +} + diff --git a/modules/ace/engine/Serializer.cpp b/modules/ace/engine/Serializer.cpp new file mode 100644 index 0000000..a3141be --- /dev/null +++ b/modules/ace/engine/Serializer.cpp @@ -0,0 +1,402 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include + +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: " <& inputList) +{ + int dataLength = inputList.size(); + os.write((char*)(&dataLength), sizeof(dataLength)); + + //LogInfo("SerializeListAttributes SIZE: " <serialize(os); + } + + Assert(os.bad() == false && "Error Writing to file failure"); +} + +std::list Serializer::deserializeListAttributes(std::istream& is) +{ + std::list outputList; + + int numElem = 0; + is.read((char*)(&numElem), sizeof(numElem)); + + //LogInfo("DESerializeListAttributes SIZE: " <& 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 Serializer::deserializeListStrings(std::istream& is) +{ + std::list 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& inputList) +{ + int dataLength = inputList.size(); + os.write((char*)(&dataLength), sizeof(dataLength)); + + // LogInfo("SerializeListTreeNode SIZE: " <serialize(os); + } + + Assert(os.bad() == false && "Error Writing to file failure"); +} + +std::list Serializer::deserializeListTreeNode(std::istream&is, + TreeNode* parent) +{ + std::list outputList; + + int numElem = 0; + is.read((char*)(&numElem), sizeof(numElem)); + + // LogInfo("DESerializeListTreeNode SIZE: " <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& 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((*it))->serialize(os); + } + + Assert(os.bad() == false && "Error Writing to file failure"); +} + +std::list* Serializer::deserializeListSubjects(std::istream& is) +{ + std::list* outputList = new std::list; + + int numElem = 0; + is.read((char*)(&numElem), sizeof(numElem)); + + //LogInfo("DESerialize list Subjects SIZE: " <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: " <& inputList) +{ + int dataLength = inputList.size(); + os.write((char*)(&dataLength), sizeof(dataLength)); + + //LogInfo("Serialize List Conditions SIZE:" <serialize(os); + } + + Assert(os.bad() == false && "Error Writing to file failure"); +} + +std::list Serializer::deserializeListConditions(std::istream& is, + Condition* parent) +{ + std::list outputList; + + int numElem = 0; + is.read((char*)(&numElem), sizeof(numElem)); + + //LogInfo("DESerialize list Condition SIZE: " < + +#include +#include + +#include + +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); +} diff --git a/modules/ace/engine/Subject.cpp b/modules/ace/engine/Subject.cpp new file mode 100644 index 0000000..760b93d --- /dev/null +++ b/modules/ace/engine/Subject.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include + +#include +#include +#include + +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& 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; +} diff --git a/modules/ace/engine/TreeNode.cpp b/modules/ace/engine/TreeNode.cpp new file mode 100644 index 0000000..5bcc136 --- /dev/null +++ b/modules/ace/engine/TreeNode.cpp @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include + +//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::iterator it = this->children.begin(); + while (it != children.end()) { + (*it)->releaseResources(); + ++it; + } + delete this; +} + +// KW void TreeNode::releaseTheSubtree(){ +// KW +// KW std::list::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;ichildren.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; +} + diff --git a/modules/ace/engine/parser.cpp b/modules/ace/engine/parser.cpp new file mode 100644 index 0000000..1b20a6a --- /dev/null +++ b/modules/ace/engine/parser.cpp @@ -0,0 +1,744 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include +#include + +#include +#include + +namespace { + +class ParserWarningLogger +{ + public: + void operator()(const std::string& logMsg) + { + LogWarning(logMsg); + } +}; + +class ParserErrorLogger +{ + public: + void operator()(const std::string& logMsg) + { + LogError(logMsg); + } +}; + +template +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 > + 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 > + schemaContext( + xmlSchemaParserContext, + xmlSchemaFreeParserCtxt); + + LogDebug("Setting callbacks"); + + xmlSchemaSetParserErrors( + schemaContext.get(), + static_cast + (&xmlLogFunction), + static_cast + (&xmlLogFunction), + 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 > + schemaValidContext( + xmlValidContext, + xmlSchemaFreeValidCtxt); + + xmlSchemaSetValidErrors( + schemaValidContext.get(), + static_cast + (&xmlLogFunction), + static_cast + (&xmlLogFunction), + 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 > + reader(xmlReader, xmlFreeTextReader); + + int ret; + ret = xmlTextReaderRead(reader.get()); + while (ret == 1) { + std::unique_ptr > + 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(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(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(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(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(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(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(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(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(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( + 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 "< +#include + +namespace AceDB { +namespace AceDaoConversions { + +DPL::String convertToHash(const BaseAttributeSet &attributes); + +} +} + +#endif diff --git a/modules/ace/include/dpl/ace-dao-ro/AceDAOReadOnly.h b/modules/ace/include/dpl/ace-dao-ro/AceDAOReadOnly.h new file mode 100644 index 0000000..da94943 --- /dev/null +++ b/modules/ace/include/dpl/ace-dao-ro/AceDAOReadOnly.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 *permissions); + + protected: + static int promptDecisionToInt(PromptDecision decision); + static PromptDecision intToPromptDecision(int decision); +}; + +} + +#endif diff --git a/modules/ace/include/dpl/ace-dao-ro/AceDAOUtilities.h b/modules/ace/include/dpl/ace-dao-ro/AceDAOUtilities.h new file mode 100644 index 0000000..0e0ec00 --- /dev/null +++ b/modules/ace/include/dpl/ace-dao-ro/AceDAOUtilities.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * + * + * @file 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 +#include +#include +#include +#include + +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 diff --git a/modules/ace/include/dpl/ace-dao-ro/AceDatabase.h b/modules/ace/include/dpl/ace-dao-ro/AceDatabase.h new file mode 100644 index 0000000..d5b2838 --- /dev/null +++ b/modules/ace/include/dpl/ace-dao-ro/AceDatabase.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 +#include + +extern DPL::Mutex g_aceDbQueriesMutex; + +#define ACE_DB_INTERNAL(tlsCommand, InternalType, interface) \ + static DPL::ThreadLocalVariable *tlsCommand ## Ptr = NULL; \ + { \ + DPL::Mutex::ScopedLock lock(&g_aceDbQueriesMutex); \ + if (!tlsCommand ## Ptr) { \ + static DPL::ThreadLocalVariable tmp; \ + tlsCommand ## Ptr = &tmp; \ + } \ + } \ + DPL::ThreadLocalVariable &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 diff --git a/modules/ace/include/dpl/ace-dao-ro/BaseAttribute.h b/modules/ace/include/dpl/ace-dao-ro/BaseAttribute.h new file mode 100644 index 0000000..1956af5 --- /dev/null +++ b/modules/ace/include/dpl/ace-dao-ro/BaseAttribute.h @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 +#include +#include +#include +#include + +namespace AceDB { + +class BaseAttribute; +typedef DPL::SharedPtr 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 * getValue() const + { + return const_cast* >(&value); + } + virtual bool isValueEmpty() const + { + return value.empty(); + } + + virtual void setValue(const std::list& 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 value; //string bag list +}; + +typedef std::set BaseAttributeSet; + +} + +#endif diff --git a/modules/ace/include/dpl/ace-dao-ro/BasePermission.h b/modules/ace/include/dpl/ace-dao-ro/BasePermission.h new file mode 100644 index 0000000..8305f42 --- /dev/null +++ b/modules/ace/include/dpl/ace-dao-ro/BasePermission.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * + * + * @file 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 +#include + +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 BasePermissionList; + +} + +#endif diff --git a/modules/ace/include/dpl/ace-dao-ro/IRequest.h b/modules/ace/include/dpl/ace-dao-ro/IRequest.h new file mode 100644 index 0000000..2975b8b --- /dev/null +++ b/modules/ace/include/dpl/ace-dao-ro/IRequest.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * + * + * @file 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 diff --git a/modules/ace/include/dpl/ace-dao-ro/PreferenceTypes.h b/modules/ace/include/dpl/ace-dao-ro/PreferenceTypes.h new file mode 100644 index 0000000..0f96dc5 --- /dev/null +++ b/modules/ace/include/dpl/ace-dao-ro/PreferenceTypes.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * + * + * @file 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 +#include + +namespace AceDB{ + +enum class PreferenceTypes +{ + PREFERENCE_PERMIT, + PREFERENCE_DENY, + PREFERENCE_DEFAULT, + PREFERENCE_BLANKET_PROMPT, + PREFERENCE_SESSION_PROMPT, + PREFERENCE_ONE_SHOT_PROMPT +}; + + +typedef std::map PreferenceTypesMap; + +} + +#endif diff --git a/modules/ace/include/dpl/ace-dao-ro/PromptModel.h b/modules/ace/include/dpl/ace-dao-ro/PromptModel.h new file mode 100644 index 0000000..e610e12 --- /dev/null +++ b/modules/ace/include/dpl/ace-dao-ro/PromptModel.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* @file 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 +#include +#include + +#include +#include + +namespace Prompt { +typedef std::vector 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 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_ */ diff --git a/modules/ace/include/dpl/ace-dao-ro/TimedVerdict.h b/modules/ace/include/dpl/ace-dao-ro/TimedVerdict.h new file mode 100644 index 0000000..1fbac52 --- /dev/null +++ b/modules/ace/include/dpl/ace-dao-ro/TimedVerdict.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * + * + * @file 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 + +namespace AceDB{ + +struct TimedVerdict +{ + VerdictTypes decision; + /*Below values are optional,its filled only when verdict depend on session*/ + std::string session; + int subjectVerdictId; +}; + +} + +#endif diff --git a/modules/ace/include/dpl/ace-dao-ro/ValidityTypes.h b/modules/ace/include/dpl/ace-dao-ro/ValidityTypes.h new file mode 100644 index 0000000..1283cf1 --- /dev/null +++ b/modules/ace/include/dpl/ace-dao-ro/ValidityTypes.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * + * + * @file 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 diff --git a/modules/ace/include/dpl/ace-dao-ro/VerdictTypes.h b/modules/ace/include/dpl/ace-dao-ro/VerdictTypes.h new file mode 100644 index 0000000..8a312b5 --- /dev/null +++ b/modules/ace/include/dpl/ace-dao-ro/VerdictTypes.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * + * + * @file 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 diff --git a/modules/ace/include/dpl/ace-dao-ro/common_dao_types.h b/modules/ace/include/dpl/ace-dao-ro/common_dao_types.h new file mode 100644 index 0000000..6913766 --- /dev/null +++ b/modules/ace/include/dpl/ace-dao-ro/common_dao_types.h @@ -0,0 +1,487 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 +#include +#include +#include +#include +#include +#include + +namespace WrtDB { +namespace Powder { + +typedef std::set 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 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 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 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 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 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 m_deviceCapabilities; + + bool operator< (const Feature& obj) const + { + return m_name < obj.m_name; + } + }; + typedef std::set 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 Objects; + typedef DPL::SharedPtr 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 WidgetAccessInfoList; + +typedef std::list 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 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 DbWidgetFeatureSet; + +/** + * @brief Default container with DbWidgetHandle's + */ +typedef std::list 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 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 WidgetApplicationServiceList; +#endif /* WRT_SRC_CONFIGURATION_COMMON_DAO_TYPES_H_ */ diff --git a/modules/ace/include/dpl/ace-dao-ro/wrt_db_types.h b/modules/ace/include/dpl/ace-dao-ro/wrt_db_types.h new file mode 100644 index 0000000..a0dc08b --- /dev/null +++ b/modules/ace/include/dpl/ace-dao-ro/wrt_db_types.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * 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 + +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_ */ diff --git a/modules/ace/include/dpl/ace-dao-rw/AceDAO.h b/modules/ace/include/dpl/ace-dao-rw/AceDAO.h new file mode 100644 index 0000000..82b86f6 --- /dev/null +++ b/modules/ace/include/dpl/ace-dao-rw/AceDAO.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * + * + * @file AceDAO.h + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 0.1 + * @brief + */ + +#ifndef ACEDAO_H_ +#define ACEDAO_H_ + +#include +#include +#include +#include + +#include +#include +#include +#include + +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 &permissions); + +}; +} +#endif /* ACEDAO_H_ */ diff --git a/modules/ace/include/dpl/ace/AbstractPolicyEnforcementPoint.h b/modules/ace/include/dpl/ace/AbstractPolicyEnforcementPoint.h new file mode 100644 index 0000000..b808a76 --- /dev/null +++ b/modules/ace/include/dpl/ace/AbstractPolicyEnforcementPoint.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WRT_SRC_ACCESS_CONTROL_LOGIC_ABSTRACT_POLICY_ENFORCEMENT_POINTS_H +#define WRT_SRC_ACCESS_CONTROL_LOGIC_ABSTRACT_POLICY_ENFORCEMENT_POINTS_H + +#include +#include +#include + +class AbstractPolicyEnforcementPoint +{ + public: + typedef DPL::Event::ICDelegate ResponseReceiver; + virtual PolicyResult check(Request &request) = 0; +}; + +#endif /* WRT_SRC_ACCESS_CONTROL_LOGIC_ABSTRACT_POLICY_ENFORCEMENT_POINTS_H */ diff --git a/modules/ace/include/dpl/ace/AbstractPolicyInformationPoint.h b/modules/ace/include/dpl/ace/AbstractPolicyInformationPoint.h new file mode 100644 index 0000000..e8d95ed --- /dev/null +++ b/modules/ace/include/dpl/ace/AbstractPolicyInformationPoint.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class AbstractPolicyInformationPoint +{ + public: + virtual ~AbstractPolicyInformationPoint() {} +}; diff --git a/modules/ace/include/dpl/ace/AbstractTreeElement.h b/modules/ace/include/dpl/ace/AbstractTreeElement.h new file mode 100644 index 0000000..634eea0 --- /dev/null +++ b/modules/ace/include/dpl/ace/AbstractTreeElement.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// +// +// +// @ Project : Access Control Engine +// @ File Name : AbstractTreeElement.h +// @ Date : 2009-05-25 +// @ Author : Samsung +// +// +#if !defined(_ABSTRACTTREEELEMENT_H) +#define _ABSTRACTTREEELEMENT_H + +#include +#include "Effect.h" +#include + +class AbstractTreeElement +{ + public: + + virtual ~AbstractTreeElement() + { + } + + virtual void printData() = 0; + + virtual void serialize(std::ostream& os) = 0; + protected: +}; + +#endif //_ABSTRACTTREEELEMENT_H diff --git a/modules/ace/include/dpl/ace/AsyncVerdictResultListener.h b/modules/ace/include/dpl/ace/AsyncVerdictResultListener.h new file mode 100644 index 0000000..9b0d4f6 --- /dev/null +++ b/modules/ace/include/dpl/ace/AsyncVerdictResultListener.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _ASYNCVERDICT_H +#define _ASYNCVERDICT_H + +#include +#include +#include + +class AsyncVerdictResultListener +{ + public: + virtual void onVerdict(const Verdict &verdict, + const Request *request) = 0; + virtual ~AsyncVerdictResultListener() + { + } +}; + +#endif diff --git a/modules/ace/include/dpl/ace/Attribute.h b/modules/ace/include/dpl/ace/Attribute.h new file mode 100644 index 0000000..ddf100b --- /dev/null +++ b/modules/ace/include/dpl/ace/Attribute.h @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 +#include +#include +#include + +#include + +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 * 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 + * + * ://? + * 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 ] + * @: + * + * 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 *first, + const std::list *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 & attrs); + +#endif //_ATTRIBUTE_H diff --git a/modules/ace/include/dpl/ace/Combiner.h b/modules/ace/include/dpl/ace/Combiner.h new file mode 100644 index 0000000..62a044f --- /dev/null +++ b/modules/ace/include/dpl/ace/Combiner.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// +// +// +// @ Project : Access Control Engine +// @ File Name : Combiner.h +// @ Date : 2009-05-06 +// @ Author : Samsung +// +// + +#if !defined(_COMBINER_H) +#define _COMBINER_H + +#include + +#include +#include + +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 diff --git a/modules/ace/include/dpl/ace/CombinerImpl.h b/modules/ace/include/dpl/ace/CombinerImpl.h new file mode 100644 index 0000000..02cd8c6 --- /dev/null +++ b/modules/ace/include/dpl/ace/CombinerImpl.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 +#include + +#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 * subjectsSet, + bool &isUndetermined); + + Effect combine(Policy::CombineAlgorithm algorithm, + std::list & effects); + + Effect denyOverrides(const std::list & effects); + Effect permitOverrides(const std::list & effects); + Effect firstApplicable(const std::list & effects); + Effect firstMatchingTarget(const std::list & effects); + + std::list * convertEffectsToInts(const std::list * effects); + Effect convertIntToEffect(int intEffect); + + void showEffectList(std::list & effects) + { + std::list::iterator it = effects.begin(); + for (; it != effects.end(); ++it) { + LogDebug(toString(*it)); + } + } + + private: + bool isError(const std::list & effects); + static const int + DenyInt, + UndeterminedInt, + PromptOneShotInt, + PromptSessionInt, + PromptBlanketInt, + PermitInt, + InapplicableInt, + NotMatchingTargetInt, + ErrorInt; +}; + +#endif //_COMBINERIMPL_H diff --git a/modules/ace/include/dpl/ace/Condition.h b/modules/ace/include/dpl/ace/Condition.h new file mode 100644 index 0000000..4574673 --- /dev/null +++ b/modules/ace/include/dpl/ace/Condition.h @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 +#include +#include +#include + +#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 * attributes) const; + + // KW Attribute::MatchResult performORalgorithm(const std::set * attributes) const; + + bool isEmpty() const + { + return attributes.empty() && conditions.empty(); + } + + bool isAndCondition() const + { + return combineType == AND; + } + + bool isOrCondition() const + { + return combineType == OR; + } + + std::list conditions; + CombineType combineType; + std::list attributes; + Condition *parent; +}; + +#endif /* _CONDITION_H */ + diff --git a/modules/ace/include/dpl/ace/ConfigurationManager.h b/modules/ace/include/dpl/ace/ConfigurationManager.h new file mode 100644 index 0000000..9de311a --- /dev/null +++ b/modules/ace/include/dpl/ace/ConfigurationManager.h @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _CONFIGURATIONMANAGER_H_ +#define _CONFIGURATIONMANAGER_H_ + +#include +#include +#include +#include +#include "Constants.h" +#include +#include +#include + +#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 & 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 policyFiles; + + //////////NEW +}; + +#endif + diff --git a/modules/ace/include/dpl/ace/Constants.h b/modules/ace/include/dpl/ace/Constants.h new file mode 100644 index 0000000..db1b798 --- /dev/null +++ b/modules/ace/include/dpl/ace/Constants.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file 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 */ + diff --git a/modules/ace/include/dpl/ace/Effect.h b/modules/ace/include/dpl/ace/Effect.h new file mode 100644 index 0000000..301e821 --- /dev/null +++ b/modules/ace/include/dpl/ace/Effect.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// +// +// +// @ 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 diff --git a/modules/ace/include/dpl/ace/NodeFactory.h b/modules/ace/include/dpl/ace/NodeFactory.h new file mode 100644 index 0000000..9abb490 --- /dev/null +++ b/modules/ace/include/dpl/ace/NodeFactory.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#if !defined(_NODE_FACTORY_H) +#define _NODE_FACTORY_H + +#include +#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 + diff --git a/modules/ace/include/dpl/ace/PermissionTriple.h b/modules/ace/include/dpl/ace/PermissionTriple.h new file mode 100644 index 0000000..c55f9d7 --- /dev/null +++ b/modules/ace/include/dpl/ace/PermissionTriple.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// +// +// +// @ Project : Access Control Engine +// @ File Name : PermissionTriple.h +// @ Date : 2009-05-06 +// @ Author : Samsung +// +// + +#if !defined(_PERMISSION_TRIPLE_H) +#define _PERMISSION_TRIPLE_H + +#include +#include +#include +#include + +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 diff --git a/modules/ace/include/dpl/ace/Policy.h b/modules/ace/include/dpl/ace/Policy.h new file mode 100644 index 0000000..e70a355 --- /dev/null +++ b/modules/ace/include/dpl/ace/Policy.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// +// +// +// @ Project : Access Control Engine +// @ File Name : Policy.h +// @ Date : 2009-05-06 +// @ Author : Samsung +// +// + +#if !defined(_POLICY_H) +#define _POLICY_H + +#include + +#include +#include +#include +#include +#include +#include + +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(); + } + + CombineAlgorithm getCombineAlgorithm() const + { + return this->combineAlgorithm; + } + + void setCombineAlgorithm(CombineAlgorithm algorithm) + { + this->combineAlgorithm = algorithm; + } + + const std::list * 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 *subjects; + CombineAlgorithm combineAlgorithm; +}; + +const char * toString(Policy::CombineAlgorithm algorithm); + +#endif //_POLICY_H diff --git a/modules/ace/include/dpl/ace/PolicyEffect.h b/modules/ace/include/dpl/ace/PolicyEffect.h new file mode 100644 index 0000000..43c79d7 --- /dev/null +++ b/modules/ace/include/dpl/ace/PolicyEffect.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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_ diff --git a/modules/ace/include/dpl/ace/PolicyEnforcementPoint.h b/modules/ace/include/dpl/ace/PolicyEnforcementPoint.h new file mode 100644 index 0000000..027e4d9 --- /dev/null +++ b/modules/ace/include/dpl/ace/PolicyEnforcementPoint.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * 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 +#include +#include + +//#include +//#include +//#include + +//#include +#include +#include + +#include +#include + +// 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 diff --git a/modules/ace/include/dpl/ace/PolicyEvaluator.h b/modules/ace/include/dpl/ace/PolicyEvaluator.h new file mode 100644 index 0000000..418faef --- /dev/null +++ b/modules/ace/include/dpl/ace/PolicyEvaluator.h @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +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 diff --git a/modules/ace/include/dpl/ace/PolicyEvaluatorFactory.h b/modules/ace/include/dpl/ace/PolicyEvaluatorFactory.h new file mode 100644 index 0000000..19ad88e --- /dev/null +++ b/modules/ace/include/dpl/ace/PolicyEvaluatorFactory.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file AbstractObjectFactory.h + * @author Piotr Fatyga (p.fatyga@samsung.com) + * @version 0.1 + * @brief + */ + +#ifndef _ABSTRACTOBJECTFACTORY_H +#define _ABSTRACTOBJECTFACTORY_H + +#include + +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 */ + diff --git a/modules/ace/include/dpl/ace/PolicyInformationPoint.h b/modules/ace/include/dpl/ace/PolicyInformationPoint.h new file mode 100644 index 0000000..2b3de29 --- /dev/null +++ b/modules/ace/include/dpl/ace/PolicyInformationPoint.h @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// +// +// +// @ 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 + +#include +#include + +#include + +#include + +typedef int PipResponse; + +class PolicyInformationPoint +{ + private: + + /** queries for interfaces*/ + std::list resourceAttributesQuery; + std::list environmentAttributesQuery; + std::list subjectAttributesQuery; + std::list 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 diff --git a/modules/ace/include/dpl/ace/PolicyResult.h b/modules/ace/include/dpl/ace/PolicyResult.h new file mode 100644 index 0000000..8ccb41e --- /dev/null +++ b/modules/ace/include/dpl/ace/PolicyResult.h @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _SRC_ACCESS_CONTROL_COMMON_POLICY_RESULT_H_ +#define _SRC_ACCESS_CONTROL_COMMON_POLICY_RESULT_H_ + +#include +#include +#include + +#include + +typedef DPL::Optional 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 OptionalPolicyResult; + +#endif // _SRC_ACCESS_CONTROL_COMMON_POLICY_RESULT_H_ diff --git a/modules/ace/include/dpl/ace/PolicySet.h b/modules/ace/include/dpl/ace/PolicySet.h new file mode 100644 index 0000000..6d6307d --- /dev/null +++ b/modules/ace/include/dpl/ace/PolicySet.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// +// +// +// @ 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 + +class PolicySet : public Policy +{ + public: + + //TODO Clean this class + //PolicySet(CombineAlgorithm algorithm, std::list * targetAttr,const std::string & subjectId) + // : Policy(algorithm,targetAttr,subjectId) + // {} + PolicySet() + { + } + ~PolicySet() + { + } + + PolicySet(std::istream& is) : Policy(is) + { + } +}; + +#endif //_POLICYSET_H diff --git a/modules/ace/include/dpl/ace/Preference.h b/modules/ace/include/dpl/ace/Preference.h new file mode 100644 index 0000000..97b34fc --- /dev/null +++ b/modules/ace/include/dpl/ace/Preference.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// +// +// +// @ Project : Access Control Engine +// @ File Name : Preference.h +// @ Date : 2009-05-2 +// @ Author : Samsung +// +// + +#ifndef _Preference_H_ +#define _Preference_H_ + +#include +#include + +#include + +typedef AceDB::PreferenceTypes Preference; +typedef AceDB::PreferenceTypesMap PreferenceMap; + +#endif //_Preference_H + diff --git a/modules/ace/include/dpl/ace/PromptDecision.h b/modules/ace/include/dpl/ace/PromptDecision.h new file mode 100644 index 0000000..bfe425b --- /dev/null +++ b/modules/ace/include/dpl/ace/PromptDecision.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _SRC_ACCESS_CONTROL_COMMON_PROMPT_DECISION_H_ +#define _SRC_ACCESS_CONTROL_COMMON_PROMPT_DECISION_H_ + +#include +#include + +enum class PromptDecision { + ALLOW_ALWAYS, + DENY_ALWAYS, + ALLOW_THIS_TIME, + DENY_THIS_TIME, + ALLOW_FOR_SESSION, + DENY_FOR_SESSION +}; + +typedef DPL::Optional OptionalPromptDecision; + +struct CachedPromptDecision { + PromptDecision decision; + DPL::OptionalString session; +}; + +typedef DPL::Optional OptionalCachedPromptDecision; + +#endif // _SRC_ACCESS_CONTROL_COMMON_PROMPT_DECISION_H_ diff --git a/modules/ace/include/dpl/ace/Request.h b/modules/ace/include/dpl/ace/Request.h new file mode 100644 index 0000000..c29def4 --- /dev/null +++ b/modules/ace/include/dpl/ace/Request.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 +#include +#include + +#include + +#include + +class Request : public AceDB::IRequest +{ + public: + typedef std::string DeviceCapability; + typedef std::set 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 Requests; + +#endif //_REQUEST_H_ diff --git a/modules/ace/include/dpl/ace/Rule.h b/modules/ace/include/dpl/ace/Rule.h new file mode 100644 index 0000000..7877ced --- /dev/null +++ b/modules/ace/include/dpl/ace/Rule.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// +// +// +// @ 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 + +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 diff --git a/modules/ace/include/dpl/ace/Serializer.h b/modules/ace/include/dpl/ace/Serializer.h new file mode 100644 index 0000000..1e1c4cb --- /dev/null +++ b/modules/ace/include/dpl/ace/Serializer.h @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#if !defined(_SERIALIZER_H) +#define _SERIALIZER_H + +#include +#include +#include + +#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& inputList); + std::list 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& inputList) const; + + std::list 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& inputList); + std::list 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& inputList); + std::list* 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& inputList); + std::list 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 + diff --git a/modules/ace/include/dpl/ace/SettingsLogic.h b/modules/ace/include/dpl/ace/SettingsLogic.h new file mode 100644 index 0000000..62096db --- /dev/null +++ b/modules/ace/include/dpl/ace/SettingsLogic.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * + * + * @file 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 +#include +#include +#include +#include +#include +#include +#include +#include + +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 > &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_ */ diff --git a/modules/ace/include/dpl/ace/Subject.h b/modules/ace/include/dpl/ace/Subject.h new file mode 100644 index 0000000..5821429 --- /dev/null +++ b/modules/ace/include/dpl/ace/Subject.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// +// File: Subject.h +// Author: notroot +// +// Created on June 2, 2009, 8:47 AM +// + +#ifndef _SUBJECT_H +#define _SUBJECT_H + +#include +#include +#include +#include +#include + +#include "Attribute.h" + +class Subject : DPL::Noncopyable +{ + std::string subjectId; + std::list targetAttributes; + + public: + Subject() + {} + + //deserialize + Subject(std::istream&); + + virtual bool serialize (std::ostream& os); + + const std::list& 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 * 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 */ + diff --git a/modules/ace/include/dpl/ace/TestTimer.h b/modules/ace/include/dpl/ace/TestTimer.h new file mode 100644 index 0000000..1f07e61 --- /dev/null +++ b/modules/ace/include/dpl/ace/TestTimer.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _TEST_TIMER_H +#define _TEST_TIMER_H + +#include + +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 + diff --git a/modules/ace/include/dpl/ace/TreeNode.h b/modules/ace/include/dpl/ace/TreeNode.h new file mode 100644 index 0000000..05bb0e6 --- /dev/null +++ b/modules/ace/include/dpl/ace/TreeNode.h @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 +#include + +#include + +class TreeNode; + +typedef std::list ChildrenSet; +typedef std::list::iterator ChildrenIterator; +typedef std::list::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 children; + TreeNode * parent; + //TODO standarize ID case + TypeID typeID; + AbstractTreeElement * element; + static int level; +}; + +#endif //_TREE_NODE_H diff --git a/modules/ace/include/dpl/ace/UserDecision.h b/modules/ace/include/dpl/ace/UserDecision.h new file mode 100644 index 0000000..4bc405d --- /dev/null +++ b/modules/ace/include/dpl/ace/UserDecision.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// +// +// +// @ Project : Access Control Engine +// @ File Name : UserDecision.h +// @ Date : 2009-05-22 +// @ Author : Samsung +// +// + +#ifndef _USERDECISION_H +#define _USERDECISION_H + +#include +#include + +typedef AceDB::ValidityTypes Validity; + +const char * toString(Validity validity); + +#endif //_USERDECISION_H + diff --git a/modules/ace/include/dpl/ace/Verdict.h b/modules/ace/include/dpl/ace/Verdict.h new file mode 100644 index 0000000..805d02a --- /dev/null +++ b/modules/ace/include/dpl/ace/Verdict.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// +// +// +// @ Project : Access Control Engine +// @ File Name : Verdict.h +// @ Date : 2009-05-2 +// @ Author : Samsung +// +// + +#ifndef _VERDICT_H +#define _VERDICT_H + +#include +#include +#include + +typedef AceDB::VerdictTypes Verdict; +//typedef AceDB::TimedVerdict TimedVerdict; + +const char * toString(Verdict verditct); + +#endif //_VERDICT_H + diff --git a/modules/ace/include/dpl/ace/WRT_INTERFACE.h b/modules/ace/include/dpl/ace/WRT_INTERFACE.h new file mode 100644 index 0000000..2f5b80b --- /dev/null +++ b/modules/ace/include/dpl/ace/WRT_INTERFACE.h @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 +#include +#include + +#include + +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* > +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 *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 *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 *attributes) = 0; + + virtual ~IOperationSystem() + { + } +}; + +class IFunctionParam +{ + public: + virtual int getAttributesValues(const Request &request, + std::list *attributes) = 0; + virtual ~IFunctionParam() + { + } +}; + +#endif //_WRT_INERFACE_4_ACE_EXAMPLE_H_ diff --git a/modules/ace/include/dpl/ace/WidgetUsageModel.h b/modules/ace/include/dpl/ace/WidgetUsageModel.h new file mode 100644 index 0000000..09d15f8 --- /dev/null +++ b/modules/ace/include/dpl/ace/WidgetUsageModel.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// +// @ Project : Access Control Engine +// @ File Name : UserDecision.h +// @ Date : 2009-05-22 +// @ Author : Samsung +// +// + +#ifndef _WIDGET_USAGE_H +#define _WIDGET_USAGE_H + +#include + +#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 diff --git a/modules/ace/include/dpl/ace/acf_consts.h b/modules/ace/include/dpl/ace/acf_consts.h new file mode 100644 index 0000000..93ecfae --- /dev/null +++ b/modules/ace/include/dpl/ace/acf_consts.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * 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 + diff --git a/modules/ace/include/dpl/ace/parser.h b/modules/ace/include/dpl/ace/parser.h new file mode 100644 index 0000000..4fcd4d4 --- /dev/null +++ b/modules/ace/include/dpl/ace/parser.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 +#include +#include +#include +#include + +#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 diff --git a/modules/ace/orm/ace_db b/modules/ace/orm/ace_db new file mode 100644 index 0000000..0dc1c27 --- /dev/null +++ b/modules/ace/orm/ace_db @@ -0,0 +1,60 @@ +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; +) diff --git a/modules/ace/orm/ace_db_definitions b/modules/ace/orm/ace_db_definitions new file mode 100644 index 0000000..46836e9 --- /dev/null +++ b/modules/ace/orm/ace_db_definitions @@ -0,0 +1,6 @@ +DATABASE_START(ace) + +#include "ace_db" +#include "version_db" + +DATABASE_END() diff --git a/modules/ace/orm/ace_db_sql_generator.h b/modules/ace/orm/ace_db_sql_generator.h new file mode 100644 index 0000000..5af05ac --- /dev/null +++ b/modules/ace/orm/ace_db_sql_generator.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file wrt_db_sql_generator.h + * @author Bartosz Janiak (b.janiak@samsung.com) + * @version 1.0 + * @brief Macro definitions for generating the SQL input file from database definition. + */ + +//Do not include this file directly! It is used only for SQL code generation. + +#include + +#include "ace_db_definitions" diff --git a/modules/ace/orm/gen_db_md5.sh b/modules/ace/orm/gen_db_md5.sh new file mode 100755 index 0000000..38587b7 --- /dev/null +++ b/modules/ace/orm/gen_db_md5.sh @@ -0,0 +1,19 @@ +#!/bin/sh +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +CHECKSUM=`cat ${2} ${3} 2>/dev/null | md5sum 2>/dev/null | cut -d\ -f1 2>/dev/null` +echo "#define DB_CHECKSUM DB_VERSION_${CHECKSUM}" > ${1} +echo "#define DB_CHECKSUM_STR \"DB_VERSION_${CHECKSUM}\"" >> ${1} + diff --git a/modules/ace/orm/orm_generator_ace.h b/modules/ace/orm/orm_generator_ace.h new file mode 100644 index 0000000..640dd35 --- /dev/null +++ b/modules/ace/orm/orm_generator_ace.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ORM_GENERATOR_ACE_H +#define ORM_GENERATOR_ACE_H + +#define ORM_GENERATOR_DATABASE_NAME ace_db_definitions +#include +#undef ORM_GENERATOR_DATABASE_NAME + +#endif diff --git a/modules/ace/orm/version_db b/modules/ace/orm/version_db new file mode 100644 index 0000000..7e20d8d --- /dev/null +++ b/modules/ace/orm/version_db @@ -0,0 +1,5 @@ +SQL( + BEGIN TRANSACTION; + CREATE TABLE DB_CHECKSUM (version INT); + COMMIT; +) diff --git a/modules/core/DESCRIPTION b/modules/core/DESCRIPTION new file mode 100644 index 0000000..1369c40 --- /dev/null +++ b/modules/core/DESCRIPTION @@ -0,0 +1 @@ +Main library code diff --git a/modules/core/config.cmake b/modules/core/config.cmake new file mode 100644 index 0000000..10450d0 --- /dev/null +++ b/modules/core/config.cmake @@ -0,0 +1,159 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# @file 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 +) + diff --git a/modules/core/include/DESCRIPTION b/modules/core/include/DESCRIPTION new file mode 100644 index 0000000..6dfd446 --- /dev/null +++ b/modules/core/include/DESCRIPTION @@ -0,0 +1,2 @@ +!!!options!!! stop +Header files, including template implementations diff --git a/modules/core/include/dpl/3rdparty/fastdelegate/FastDelegate.h b/modules/core/include/dpl/3rdparty/fastdelegate/FastDelegate.h new file mode 100644 index 0000000..c69fccc --- /dev/null +++ b/modules/core/include/dpl/3rdparty/fastdelegate/FastDelegate.h @@ -0,0 +1,2108 @@ +// FastDelegate.h +// Efficient delegates in C++ that generate only two lines of asm code! +// Documentation is found at http://www.codeproject.com/cpp/FastDelegate.asp +// +// - Don Clugston, Mar 2004. +// Major contributions were made by Jody Hagins. +// History: +// 24-Apr-04 1.0 * Submitted to CodeProject. +// 28-Apr-04 1.1 * Prevent most unsafe uses of evil static function hack. +// * Improved syntax for horrible_cast (thanks Paul Bludov). +// * Tested on Metrowerks MWCC and Intel ICL (IA32) +// * Compiled, but not run, on Comeau C++ and Intel Itanium ICL. +// 27-Jun-04 1.2 * Now works on Borland C++ Builder 5.5 +// * Now works on /clr "managed C++" code on VC7, VC7.1 +// * Comeau C++ now compiles without warnings. +// * Prevent the virtual inheritance case from being used on +// VC6 and earlier, which generate incorrect code. +// * Improved warning and error messages. Non-standard hacks +// now have compile-time checks to make them safer. +// * implicit_cast used instead of static_cast in many cases. +// * If calling a const member function, a const class pointer can be used. +// * MakeDelegate() global helper function added to simplify pass-by-value. +// * Added fastdelegate.clear() +// 16-Jul-04 1.2.1* Workaround for gcc bug (const member function pointers in templates) +// 30-Oct-04 1.3 * Support for (non-void) return values. +// * No more workarounds in client code! +// MSVC and Intel now use a clever hack invented by John Dlugosz: +// - The FASTDELEGATEDECLARE workaround is no longer necessary. +// - No more warning messages for VC6 +// * Less use of macros. Error messages should be more comprehensible. +// * Added include guards +// * Added FastDelegate::empty() to test if invocation is safe (Thanks Neville Franks). +// * Now tested on VS 2005 Express Beta, PGI C++ +// 24-Dec-04 1.4 * Added DelegateMemento, to allow collections of disparate delegates. +// * <,>,<=,>= comparison operators to allow storage in ordered containers. +// * Substantial reduction of code size, especially the 'Closure' class. +// * Standardised all the compiler-specific workarounds. +// * MFP conversion now works for CodePlay (but not yet supported in the full code). +// * Now compiles without warnings on _any_ supported compiler, including BCC 5.5.1 +// * New syntax: FastDelegate< int (char *, double) >. +// 14-Feb-05 1.4.1* Now treats =0 as equivalent to .clear(), ==0 as equivalent to .empty(). (Thanks elfric). +// * Now tested on Intel ICL for AMD64, VS2005 Beta for AMD64 and Itanium. +// 30-Mar-05 1.5 * Safebool idiom: "if (dg)" is now equivalent to "if (!dg.empty())" +// * Fully supported by CodePlay VectorC +// * Bugfix for Metrowerks: empty() was buggy because a valid MFP can be 0 on MWCC! +// * More optimal assignment,== and != operators for static function pointers. + +#ifndef FASTDELEGATE_H +#define FASTDELEGATE_H +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include // to allow <,> comparisons + +//////////////////////////////////////////////////////////////////////////////// +// Configuration options +// +//////////////////////////////////////////////////////////////////////////////// + +// Uncomment the following #define for optimally-sized delegates. +// In this case, the generated asm code is almost identical to the code you'd get +// if the compiler had native support for delegates. +// It will not work on systems where sizeof(dataptr) < sizeof(codeptr). +// Thus, it will not work for DOS compilers using the medium model. +// It will also probably fail on some DSP systems. +#define FASTDELEGATE_USESTATICFUNCTIONHACK + +// Uncomment the next line to allow function declarator syntax. +// It is automatically enabled for those compilers where it is known to work. +//#define FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX + +//////////////////////////////////////////////////////////////////////////////// +// Compiler identification for workarounds +// +//////////////////////////////////////////////////////////////////////////////// + +// Compiler identification. It's not easy to identify Visual C++ because +// many vendors fraudulently define Microsoft's identifiers. +#if defined(_MSC_VER) && !defined(__MWERKS__) && !defined(__VECTOR_C) && !defined(__ICL) && !defined(__BORLANDC__) +#define FASTDLGT_ISMSVC + +#if (_MSC_VER <1300) // Many workarounds are required for VC6. +#define FASTDLGT_VC6 +#pragma warning(disable:4786) // disable this ridiculous warning +#endif + +#endif + +// Does the compiler uses Microsoft's member function pointer structure? +// If so, it needs special treatment. +// Metrowerks CodeWarrior, Intel, and CodePlay fraudulently define Microsoft's +// identifier, _MSC_VER. We need to filter Metrowerks out. +#if defined(_MSC_VER) && !defined(__MWERKS__) +#define FASTDLGT_MICROSOFT_MFP + +#if !defined(__VECTOR_C) +// CodePlay doesn't have the __single/multi/virtual_inheritance keywords +#define FASTDLGT_HASINHERITANCE_KEYWORDS +#endif +#endif + +// Does it allow function declarator syntax? The following compilers are known to work: +#if defined(FASTDLGT_ISMSVC) && (_MSC_VER >=1310) // VC 7.1 +#define FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX +#endif + +// Gcc(2.95+), and versions of Digital Mars, Intel and Comeau in common use. +#if defined (__DMC__) || defined(__GNUC__) || defined(__ICL) || defined(__COMO__) +#define FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX +#endif + +// It works on Metrowerks MWCC 3.2.2. From boost.Config it should work on earlier ones too. +#if defined (__MWERKS__) +#define FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX +#endif + +#ifdef __GNUC__ // Workaround GCC bug #8271 + // At present, GCC doesn't recognize constness of MFPs in templates +#define FASTDELEGATE_GCC_BUG_8271 +#endif + + + +//////////////////////////////////////////////////////////////////////////////// +// General tricks used in this code +// +// (a) Error messages are generated by typdefing an array of negative size to +// generate compile-time errors. +// (b) Warning messages on MSVC are generated by declaring unused variables, and +// enabling the "variable XXX is never used" warning. +// (c) Unions are used in a few compiler-specific cases to perform illegal casts. +// (d) For Microsoft and Intel, when adjusting the 'this' pointer, it's cast to +// (char *) first to ensure that the correct number of *bytes* are added. +// +//////////////////////////////////////////////////////////////////////////////// +// Helper templates +// +//////////////////////////////////////////////////////////////////////////////// + + +namespace fastdelegate { +namespace detail { // we'll hide the implementation details in a nested namespace. + +// implicit_cast< > +// I believe this was originally going to be in the C++ standard but +// was left out by accident. It's even milder than static_cast. +// I use it instead of static_cast<> to emphasize that I'm not doing +// anything nasty. +// Usage is identical to static_cast<> +template +inline OutputClass implicit_cast(InputClass input){ + return input; +} + +// horrible_cast< > +// This is truly evil. It completely subverts C++'s type system, allowing you +// to cast from any class to any other class. Technically, using a union +// to perform the cast is undefined behaviour (even in C). But we can see if +// it is OK by checking that the union is the same size as each of its members. +// horrible_cast<> should only be used for compiler-specific workarounds. +// Usage is identical to reinterpret_cast<>. + +// This union is declared outside the horrible_cast because BCC 5.5.1 +// can't inline a function with a nested class, and gives a warning. +template +union horrible_union{ + OutputClass out; + InputClass in; +}; + +template +inline OutputClass horrible_cast(const InputClass input){ + horrible_union u; + // Cause a compile-time error if in, out and u are not the same size. + // If the compile fails here, it means the compiler has peculiar + // unions which would prevent the cast from working. + typedef int ERROR_CantUseHorrible_cast[sizeof(InputClass)==sizeof(u) + && sizeof(InputClass)==sizeof(OutputClass) ? 1 : -1]; + u.in = input; + return u.out; +} + +//////////////////////////////////////////////////////////////////////////////// +// Workarounds +// +//////////////////////////////////////////////////////////////////////////////// + +// Backwards compatibility: This macro used to be necessary in the virtual inheritance +// case for Intel and Microsoft. Now it just forward-declares the class. +#define FASTDELEGATEDECLARE(CLASSNAME) class CLASSNAME; + +// Prevent use of the static function hack with the DOS medium model. +#ifdef __MEDIUM__ +#undef FASTDELEGATE_USESTATICFUNCTIONHACK +#endif + +// DefaultVoid - a workaround for 'void' templates in VC6. +// +// (1) VC6 and earlier do not allow 'void' as a default template argument. +// (2) They also doesn't allow you to return 'void' from a function. +// +// Workaround for (1): Declare a dummy type 'DefaultVoid' which we use +// when we'd like to use 'void'. We convert it into 'void' and back +// using the templates DefaultVoidToVoid<> and VoidToDefaultVoid<>. +// Workaround for (2): On VC6, the code for calling a void function is +// identical to the code for calling a non-void function in which the +// return value is never used, provided the return value is returned +// in the EAX register, rather than on the stack. +// This is true for most fundamental types such as int, enum, void *. +// Const void * is the safest option since it doesn't participate +// in any automatic conversions. But on a 16-bit compiler it might +// cause extra code to be generated, so we disable it for all compilers +// except for VC6 (and VC5). +#ifdef FASTDLGT_VC6 +// VC6 workaround +typedef const void * DefaultVoid; +#else +// On any other compiler, just use a normal void. +typedef void DefaultVoid; +#endif + +// Translate from 'DefaultVoid' to 'void'. +// Everything else is unchanged +template +struct DefaultVoidToVoid { typedef T type; }; + +template <> +struct DefaultVoidToVoid { typedef void type; }; + +// Translate from 'void' into 'DefaultVoid' +// Everything else is unchanged +template +struct VoidToDefaultVoid { typedef T type; }; + +template <> +struct VoidToDefaultVoid { typedef DefaultVoid type; }; + + + +//////////////////////////////////////////////////////////////////////////////// +// Fast Delegates, part 1: +// +// Conversion of member function pointer to a standard form +// +//////////////////////////////////////////////////////////////////////////////// + +// GenericClass is a fake class, ONLY used to provide a type. +// It is vitally important that it is never defined, so that the compiler doesn't +// think it can optimize the invocation. For example, Borland generates simpler +// code if it knows the class only uses single inheritance. + +// Compilers using Microsoft's structure need to be treated as a special case. +#ifdef FASTDLGT_MICROSOFT_MFP + +#ifdef FASTDLGT_HASINHERITANCE_KEYWORDS + // For Microsoft and Intel, we want to ensure that it's the most efficient type of MFP + // (4 bytes), even when the /vmg option is used. Declaring an empty class + // would give 16 byte pointers in this case.... + class __single_inheritance GenericClass; +#endif + // ...but for Codeplay, an empty class *always* gives 4 byte pointers. + // If compiled with the /clr option ("managed C++"), the JIT compiler thinks + // it needs to load GenericClass before it can call any of its functions, + // (compiles OK but crashes at runtime!), so we need to declare an + // empty class to make it happy. + // Codeplay and VC4 can't cope with the unknown_inheritance case either. + class GenericClass {}; +#else + class GenericClass; +#endif + +// The size of a single inheritance member function pointer. +const int SINGLE_MEMFUNCPTR_SIZE = sizeof(void (GenericClass::*)()); + +// SimplifyMemFunc< >::Convert() +// +// A template function that converts an arbitrary member function pointer into the +// simplest possible form of member function pointer, using a supplied 'this' pointer. +// According to the standard, this can be done legally with reinterpret_cast<>. +// For (non-standard) compilers which use member function pointers which vary in size +// depending on the class, we need to use knowledge of the internal structure of a +// member function pointer, as used by the compiler. Template specialization is used +// to distinguish between the sizes. Because some compilers don't support partial +// template specialisation, I use full specialisation of a wrapper struct. + +// general case -- don't know how to convert it. Force a compile failure +template +struct SimplifyMemFunc { + template + inline static GenericClass *Convert(X *pthis, XFuncType function_to_bind, + GenericMemFuncType &bound_func) { + // Unsupported member function type -- force a compile failure. + // (it's illegal to have a array with negative size). + typedef char ERROR_Unsupported_member_function_pointer_on_this_compiler[N-100]; + return 0; + } +}; + +// For compilers where all member func ptrs are the same size, everything goes here. +// For non-standard compilers, only single_inheritance classes go here. +template <> +struct SimplifyMemFunc { + template + inline static GenericClass *Convert(X *pthis, XFuncType function_to_bind, + GenericMemFuncType &bound_func) { +#if defined __DMC__ + // Digital Mars doesn't allow you to cast between abitrary PMF's, + // even though the standard says you can. The 32-bit compiler lets you + // static_cast through an int, but the DOS compiler doesn't. + bound_func = horrible_cast(function_to_bind); +#else + bound_func = reinterpret_cast(function_to_bind); +#endif + return reinterpret_cast(pthis); + } +}; + +//////////////////////////////////////////////////////////////////////////////// +// Fast Delegates, part 1b: +// +// Workarounds for Microsoft and Intel +// +//////////////////////////////////////////////////////////////////////////////// + + +// Compilers with member function pointers which violate the standard (MSVC, Intel, Codeplay), +// need to be treated as a special case. +#ifdef FASTDLGT_MICROSOFT_MFP + +// We use unions to perform horrible_casts. I would like to use #pragma pack(push, 1) +// at the start of each function for extra safety, but VC6 seems to ICE +// intermittently if you do this inside a template. + +// __multiple_inheritance classes go here +// Nasty hack for Microsoft and Intel (IA32 and Itanium) +template<> +struct SimplifyMemFunc< SINGLE_MEMFUNCPTR_SIZE + sizeof(int) > { + template + inline static GenericClass *Convert(X *pthis, XFuncType function_to_bind, + GenericMemFuncType &bound_func) { + // We need to use a horrible_cast to do this conversion. + // In MSVC, a multiple inheritance member pointer is internally defined as: + union { + XFuncType func; + struct { + GenericMemFuncType funcaddress; // points to the actual member function + int delta; // #BYTES to be added to the 'this' pointer + }s; + } u; + // Check that the horrible_cast will work + typedef int ERROR_CantUsehorrible_cast[sizeof(function_to_bind)==sizeof(u.s)? 1 : -1]; + u.func = function_to_bind; + bound_func = u.s.funcaddress; + return reinterpret_cast(reinterpret_cast(pthis) + u.s.delta); + } +}; + +// virtual inheritance is a real nuisance. It's inefficient and complicated. +// On MSVC and Intel, there isn't enough information in the pointer itself to +// enable conversion to a closure pointer. Earlier versions of this code didn't +// work for all cases, and generated a compile-time error instead. +// But a very clever hack invented by John M. Dlugosz solves this problem. +// My code is somewhat different to his: I have no asm code, and I make no +// assumptions about the calling convention that is used. + +// In VC++ and ICL, a virtual_inheritance member pointer +// is internally defined as: +struct MicrosoftVirtualMFP { + void (GenericClass::*codeptr)(); // points to the actual member function + int delta; // #bytes to be added to the 'this' pointer + int vtable_index; // or 0 if no virtual inheritance +}; +// The CRUCIAL feature of Microsoft/Intel MFPs which we exploit is that the +// m_codeptr member is *always* called, regardless of the values of the other +// members. (This is *not* true for other compilers, eg GCC, which obtain the +// function address from the vtable if a virtual function is being called). +// Dlugosz's trick is to make the codeptr point to a probe function which +// returns the 'this' pointer that was used. + +// Define a generic class that uses virtual inheritance. +// It has a trival member function that returns the value of the 'this' pointer. +struct GenericVirtualClass : virtual public GenericClass +{ + typedef GenericVirtualClass * (GenericVirtualClass::*ProbePtrType)(); + GenericVirtualClass * GetThis() { return this; } +}; + +// __virtual_inheritance classes go here +template <> +struct SimplifyMemFunc +{ + + template + inline static GenericClass *Convert(X *pthis, XFuncType function_to_bind, + GenericMemFuncType &bound_func) { + union { + XFuncType func; + GenericClass* (X::*ProbeFunc)(); + MicrosoftVirtualMFP s; + } u; + u.func = function_to_bind; + bound_func = reinterpret_cast(u.s.codeptr); + union { + GenericVirtualClass::ProbePtrType virtfunc; + MicrosoftVirtualMFP s; + } u2; + // Check that the horrible_cast<>s will work + typedef int ERROR_CantUsehorrible_cast[sizeof(function_to_bind)==sizeof(u.s) + && sizeof(function_to_bind)==sizeof(u.ProbeFunc) + && sizeof(u2.virtfunc)==sizeof(u2.s) ? 1 : -1]; + // Unfortunately, taking the address of a MF prevents it from being inlined, so + // this next line can't be completely optimised away by the compiler. + u2.virtfunc = &GenericVirtualClass::GetThis; + u.s.codeptr = u2.s.codeptr; + return (pthis->*u.ProbeFunc)(); + } +}; + +#if (_MSC_VER <1300) + +// Nasty hack for Microsoft Visual C++ 6.0 +// unknown_inheritance classes go here +// There is a compiler bug in MSVC6 which generates incorrect code in this case!! +template <> +struct SimplifyMemFunc +{ + template + inline static GenericClass *Convert(X *pthis, XFuncType function_to_bind, + GenericMemFuncType &bound_func) { + // There is an apalling but obscure compiler bug in MSVC6 and earlier: + // vtable_index and 'vtordisp' are always set to 0 in the + // unknown_inheritance case! + // This means that an incorrect function could be called!!! + // Compiling with the /vmg option leads to potentially incorrect code. + // This is probably the reason that the IDE has a user interface for specifying + // the /vmg option, but it is disabled - you can only specify /vmg on + // the command line. In VC1.5 and earlier, the compiler would ICE if it ever + // encountered this situation. + // It is OK to use the /vmg option if /vmm or /vms is specified. + + // Fortunately, the wrong function is only called in very obscure cases. + // It only occurs when a derived class overrides a virtual function declared + // in a virtual base class, and the member function + // points to the *Derived* version of that function. The problem can be + // completely averted in 100% of cases by using the *Base class* for the + // member fpointer. Ie, if you use the base class as an interface, you'll + // stay out of trouble. + // Occasionally, you might want to point directly to a derived class function + // that isn't an override of a base class. In this case, both vtable_index + // and 'vtordisp' are zero, but a virtual_inheritance pointer will be generated. + // We can generate correct code in this case. To prevent an incorrect call from + // ever being made, on MSVC6 we generate a warning, and call a function to + // make the program crash instantly. + typedef char ERROR_VC6CompilerBug[-100]; + return 0; + } +}; + + +#else + +// Nasty hack for Microsoft and Intel (IA32 and Itanium) +// unknown_inheritance classes go here +// This is probably the ugliest bit of code I've ever written. Look at the casts! +// There is a compiler bug in MSVC6 which prevents it from using this code. +template <> +struct SimplifyMemFunc +{ + template + inline static GenericClass *Convert(X *pthis, XFuncType function_to_bind, + GenericMemFuncType &bound_func) { + // The member function pointer is 16 bytes long. We can't use a normal cast, but + // we can use a union to do the conversion. + union { + XFuncType func; + // In VC++ and ICL, an unknown_inheritance member pointer + // is internally defined as: + struct { + GenericMemFuncType m_funcaddress; // points to the actual member function + int delta; // #bytes to be added to the 'this' pointer + int vtordisp; // #bytes to add to 'this' to find the vtable + int vtable_index; // or 0 if no virtual inheritance + } s; + } u; + // Check that the horrible_cast will work + typedef int ERROR_CantUsehorrible_cast[sizeof(XFuncType)==sizeof(u.s)? 1 : -1]; + u.func = function_to_bind; + bound_func = u.s.funcaddress; + int virtual_delta = 0; + if (u.s.vtable_index) { // Virtual inheritance is used + // First, get to the vtable. + // It is 'vtordisp' bytes from the start of the class. + const int * vtable = *reinterpret_cast( + reinterpret_cast(pthis) + u.s.vtordisp ); + + // 'vtable_index' tells us where in the table we should be looking. + virtual_delta = u.s.vtordisp + *reinterpret_cast( + reinterpret_cast(vtable) + u.s.vtable_index); + } + // The int at 'virtual_delta' gives us the amount to add to 'this'. + // Finally we can add the three components together. Phew! + return reinterpret_cast( + reinterpret_cast(pthis) + u.s.delta + virtual_delta); + }; +}; +#endif // MSVC 7 and greater + +#endif // MS/Intel hacks + +} // namespace detail + +//////////////////////////////////////////////////////////////////////////////// +// Fast Delegates, part 2: +// +// Define the delegate storage, and cope with static functions +// +//////////////////////////////////////////////////////////////////////////////// + +// DelegateMemento -- an opaque structure which can hold an arbitary delegate. +// It knows nothing about the calling convention or number of arguments used by +// the function pointed to. +// It supplies comparison operators so that it can be stored in STL collections. +// It cannot be set to anything other than null, nor invoked directly: +// it must be converted to a specific delegate. + +// Implementation: +// There are two possible implementations: the Safe method and the Evil method. +// DelegateMemento - Safe version +// +// This implementation is standard-compliant, but a bit tricky. +// A static function pointer is stored inside the class. +// Here are the valid values: +// +-- Static pointer --+--pThis --+-- pMemFunc-+-- Meaning------+ +// | 0 | 0 | 0 | Empty | +// | !=0 |(dontcare)| Invoker | Static function| +// | 0 | !=0 | !=0* | Method call | +// +--------------------+----------+------------+----------------+ +// * For Metrowerks, this can be 0. (first virtual function in a +// single_inheritance class). +// When stored stored inside a specific delegate, the 'dontcare' entries are replaced +// with a reference to the delegate itself. This complicates the = and == operators +// for the delegate class. + +// DelegateMemento - Evil version +// +// For compilers where data pointers are at least as big as code pointers, it is +// possible to store the function pointer in the this pointer, using another +// horrible_cast. In this case the DelegateMemento implementation is simple: +// +--pThis --+-- pMemFunc-+-- Meaning---------------------+ +// | 0 | 0 | Empty | +// | !=0 | !=0* | Static function or method call| +// +----------+------------+-------------------------------+ +// * For Metrowerks, this can be 0. (first virtual function in a +// single_inheritance class). +// Note that the Sun C++ and MSVC documentation explicitly state that they +// support static_cast between void * and function pointers. + +class DelegateMemento { +protected: + // the data is protected, not private, because many + // compilers have problems with template friends. + typedef void (detail::GenericClass::*GenericMemFuncType)(); // arbitrary MFP. + detail::GenericClass *m_pthis; + GenericMemFuncType m_pFunction; + +#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) + typedef void (*GenericFuncPtr)(); // arbitrary code pointer + GenericFuncPtr m_pStaticFunction; +#endif + +public: +#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) + DelegateMemento() : m_pthis(0), m_pFunction(0), m_pStaticFunction(0) {}; + void clear() { + m_pthis=0; m_pFunction=0; m_pStaticFunction=0; + } +#else + DelegateMemento() : m_pthis(0), m_pFunction(0) {}; + void clear() { m_pthis=0; m_pFunction=0; } +#endif +public: +#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) + inline bool IsEqual (const DelegateMemento &x) const{ + // We have to cope with the static function pointers as a special case + if (m_pFunction!=x.m_pFunction) return false; + // the static function ptrs must either both be equal, or both be 0. + if (m_pStaticFunction!=x.m_pStaticFunction) return false; + if (m_pStaticFunction!=0) return m_pthis==x.m_pthis; + else return true; + } +#else // Evil Method + inline bool IsEqual (const DelegateMemento &x) const{ + return m_pthis==x.m_pthis && m_pFunction==x.m_pFunction; + } +#endif + // Provide a strict weak ordering for DelegateMementos. + inline bool IsLess(const DelegateMemento &right) const { + // deal with static function pointers first +#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) + if (m_pStaticFunction !=0 || right.m_pStaticFunction!=0) + return m_pStaticFunction < right.m_pStaticFunction; +#endif + if (m_pthis !=right.m_pthis) return m_pthis < right.m_pthis; + // There are no ordering operators for member function pointers, + // but we can fake one by comparing each byte. The resulting ordering is + // arbitrary (and compiler-dependent), but it permits storage in ordered STL containers. + return memcmp(&m_pFunction, &right.m_pFunction, sizeof(m_pFunction)) < 0; + + } + // BUGFIX (Mar 2005): + // We can't just compare m_pFunction because on Metrowerks, + // m_pFunction can be zero even if the delegate is not empty! + inline bool operator ! () const // Is it bound to anything? + { return m_pthis==0 && m_pFunction==0; } + inline bool empty() const // Is it bound to anything? + { return m_pthis==0 && m_pFunction==0; } +public: + DelegateMemento & operator = (const DelegateMemento &right) { + SetMementoFrom(right); + return *this; + } + inline bool operator <(const DelegateMemento &right) { + return IsLess(right); + } + inline bool operator >(const DelegateMemento &right) { + return right.IsLess(*this); + } + DelegateMemento (const DelegateMemento &right) : + m_pFunction(right.m_pFunction), m_pthis(right.m_pthis) +#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) + , m_pStaticFunction (right.m_pStaticFunction) +#endif + {} +protected: + void SetMementoFrom(const DelegateMemento &right) { + m_pFunction = right.m_pFunction; + m_pthis = right.m_pthis; +#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) + m_pStaticFunction = right.m_pStaticFunction; +#endif + } +}; + + +// ClosurePtr<> +// +// A private wrapper class that adds function signatures to DelegateMemento. +// It's the class that does most of the actual work. +// The signatures are specified by: +// GenericMemFunc: must be a type of GenericClass member function pointer. +// StaticFuncPtr: must be a type of function pointer with the same signature +// as GenericMemFunc. +// UnvoidStaticFuncPtr: is the same as StaticFuncPtr, except on VC6 +// where it never returns void (returns DefaultVoid instead). + +// An outer class, FastDelegateN<>, handles the invoking and creates the +// necessary typedefs. +// This class does everything else. + +namespace detail { + +template < class GenericMemFunc, class StaticFuncPtr, class UnvoidStaticFuncPtr> +class ClosurePtr : public DelegateMemento { +public: + // These functions are for setting the delegate to a member function. + + // Here's the clever bit: we convert an arbitrary member function into a + // standard form. XMemFunc should be a member function of class X, but I can't + // enforce that here. It needs to be enforced by the wrapper class. + template < class X, class XMemFunc > + inline void bindmemfunc(X *pthis, XMemFunc function_to_bind ) { + m_pthis = SimplifyMemFunc< sizeof(function_to_bind) > + ::Convert(pthis, function_to_bind, m_pFunction); +#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) + m_pStaticFunction = 0; +#endif + } + // For const member functions, we only need a const class pointer. + // Since we know that the member function is const, it's safe to + // remove the const qualifier from the 'this' pointer with a const_cast. + // VC6 has problems if we just overload 'bindmemfunc', so we give it a different name. + template < class X, class XMemFunc> + inline void bindconstmemfunc(const X *pthis, XMemFunc function_to_bind) { + m_pthis= SimplifyMemFunc< sizeof(function_to_bind) > + ::Convert(const_cast(pthis), function_to_bind, m_pFunction); +#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) + m_pStaticFunction = 0; +#endif + } +#ifdef FASTDELEGATE_GCC_BUG_8271 // At present, GCC doesn't recognize constness of MFPs in templates + template < class X, class XMemFunc> + inline void bindmemfunc(const X *pthis, XMemFunc function_to_bind) { + bindconstmemfunc(pthis, function_to_bind); +#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) + m_pStaticFunction = 0; +#endif + } +#endif + // These functions are required for invoking the stored function + inline GenericClass *GetClosureThis() const { return m_pthis; } + inline GenericMemFunc GetClosureMemPtr() const { return reinterpret_cast(m_pFunction); } + +// There are a few ways of dealing with static function pointers. +// There's a standard-compliant, but tricky method. +// There's also a straightforward hack, that won't work on DOS compilers using the +// medium memory model. It's so evil that I can't recommend it, but I've +// implemented it anyway because it produces very nice asm code. + +#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) + +// ClosurePtr<> - Safe version +// +// This implementation is standard-compliant, but a bit tricky. +// I store the function pointer inside the class, and the delegate then +// points to itself. Whenever the delegate is copied, these self-references +// must be transformed, and this complicates the = and == operators. +public: + // The next two functions are for operator ==, =, and the copy constructor. + // We may need to convert the m_pthis pointers, so that + // they remain as self-references. + template< class DerivedClass > + inline void CopyFrom (DerivedClass *pParent, const DelegateMemento &x) { + SetMementoFrom(x); + if (m_pStaticFunction!=0) { + // transform self references... + m_pthis=reinterpret_cast(pParent); + } + } + // For static functions, the 'static_function_invoker' class in the parent + // will be called. The parent then needs to call GetStaticFunction() to find out + // the actual function to invoke. + template < class DerivedClass, class ParentInvokerSig > + inline void bindstaticfunc(DerivedClass *pParent, ParentInvokerSig static_function_invoker, + StaticFuncPtr function_to_bind ) { + if (function_to_bind==0) { // cope with assignment to 0 + m_pFunction=0; + } else { + bindmemfunc(pParent, static_function_invoker); + } + m_pStaticFunction=reinterpret_cast(function_to_bind); + } + inline UnvoidStaticFuncPtr GetStaticFunction() const { + return reinterpret_cast(m_pStaticFunction); + } +#else + +// ClosurePtr<> - Evil version +// +// For compilers where data pointers are at least as big as code pointers, it is +// possible to store the function pointer in the this pointer, using another +// horrible_cast. Invocation isn't any faster, but it saves 4 bytes, and +// speeds up comparison and assignment. If C++ provided direct language support +// for delegates, they would produce asm code that was almost identical to this. +// Note that the Sun C++ and MSVC documentation explicitly state that they +// support static_cast between void * and function pointers. + + template< class DerivedClass > + inline void CopyFrom (DerivedClass *pParent, const DelegateMemento &right) { + SetMementoFrom(right); + } + // For static functions, the 'static_function_invoker' class in the parent + // will be called. The parent then needs to call GetStaticFunction() to find out + // the actual function to invoke. + // ******** EVIL, EVIL CODE! ******* + template < class DerivedClass, class ParentInvokerSig> + inline void bindstaticfunc(DerivedClass *pParent, ParentInvokerSig static_function_invoker, + StaticFuncPtr function_to_bind) { + if (function_to_bind==0) { // cope with assignment to 0 + m_pFunction=0; + } else { + // We'll be ignoring the 'this' pointer, but we need to make sure we pass + // a valid value to bindmemfunc(). + bindmemfunc(pParent, static_function_invoker); + } + + // WARNING! Evil hack. We store the function in the 'this' pointer! + // Ensure that there's a compilation failure if function pointers + // and data pointers have different sizes. + // If you get this error, you need to #undef FASTDELEGATE_USESTATICFUNCTIONHACK. + typedef int ERROR_CantUseEvilMethod[sizeof(GenericClass *)==sizeof(function_to_bind) ? 1 : -1]; + m_pthis = horrible_cast(function_to_bind); + // MSVC, SunC++ and DMC accept the following (non-standard) code: +// m_pthis = static_cast(static_cast(function_to_bind)); + // BCC32, Comeau and DMC accept this method. MSVC7.1 needs __int64 instead of long +// m_pthis = reinterpret_cast(reinterpret_cast(function_to_bind)); + } + // ******** EVIL, EVIL CODE! ******* + // This function will be called with an invalid 'this' pointer!! + // We're just returning the 'this' pointer, converted into + // a function pointer! + inline UnvoidStaticFuncPtr GetStaticFunction() const { + // Ensure that there's a compilation failure if function pointers + // and data pointers have different sizes. + // If you get this error, you need to #undef FASTDELEGATE_USESTATICFUNCTIONHACK. + typedef int ERROR_CantUseEvilMethod[sizeof(UnvoidStaticFuncPtr)==sizeof(this) ? 1 : -1]; + return horrible_cast(this); + } +#endif // !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) + + // Does the closure contain this static function? + inline bool IsEqualToStaticFuncPtr(StaticFuncPtr funcptr){ + if (funcptr==0) return empty(); + // For the Evil method, if it doesn't actually contain a static function, this will return an arbitrary + // value that is not equal to any valid function pointer. + else return funcptr==reinterpret_cast(GetStaticFunction()); + } +}; + + +} // namespace detail + +//////////////////////////////////////////////////////////////////////////////// +// Fast Delegates, part 3: +// +// Wrapper classes to ensure type safety +// +//////////////////////////////////////////////////////////////////////////////// + + +// Once we have the member function conversion templates, it's easy to make the +// wrapper classes. So that they will work with as many compilers as possible, +// the classes are of the form +// FastDelegate3 +// They can cope with any combination of parameters. The max number of parameters +// allowed is 8, but it is trivial to increase this limit. +// Note that we need to treat const member functions seperately. +// All this class does is to enforce type safety, and invoke the delegate with +// the correct list of parameters. + +// Because of the weird rule about the class of derived member function pointers, +// you sometimes need to apply a downcast to the 'this' pointer. +// This is the reason for the use of "implicit_cast(pthis)" in the code below. +// If CDerivedClass is derived from CBaseClass, but doesn't override SimpleVirtualFunction, +// without this trick you'd need to write: +// MyDelegate(static_cast(&d), &CDerivedClass::SimpleVirtualFunction); +// but with the trick you can write +// MyDelegate(&d, &CDerivedClass::SimpleVirtualFunction); + +// RetType is the type the compiler uses in compiling the template. For VC6, +// it cannot be void. DesiredRetType is the real type which is returned from +// all of the functions. It can be void. + +// Implicit conversion to "bool" is achieved using the safe_bool idiom, +// using member data pointers (MDP). This allows "if (dg)..." syntax +// Because some compilers (eg codeplay) don't have a unique value for a zero +// MDP, an extra padding member is added to the SafeBool struct. +// Some compilers (eg VC6) won't implicitly convert from 0 to an MDP, so +// in that case the static function constructor is not made explicit; this +// allows "if (dg==0) ..." to compile. + +//N=0 +template +class FastDelegate0 { +private: + typedef typename detail::DefaultVoidToVoid::type DesiredRetType; + typedef DesiredRetType (*StaticFunctionPtr)(); + typedef RetType (*UnvoidStaticFunctionPtr)(); + typedef RetType (detail::GenericClass::*GenericMemFn)(); + typedef detail::ClosurePtr ClosureType; + ClosureType m_Closure; +public: + // Typedefs to aid generic programming + typedef FastDelegate0 type; + + // Construction and comparison functions + FastDelegate0() { clear(); } + FastDelegate0(const FastDelegate0 &x) { + m_Closure.CopyFrom(this, x.m_Closure); } + void operator = (const FastDelegate0 &x) { + m_Closure.CopyFrom(this, x.m_Closure); } + bool operator ==(const FastDelegate0 &x) const { + return m_Closure.IsEqual(x.m_Closure); } + bool operator !=(const FastDelegate0 &x) const { + return !m_Closure.IsEqual(x.m_Closure); } + bool operator <(const FastDelegate0 &x) const { + return m_Closure.IsLess(x.m_Closure); } + bool operator >(const FastDelegate0 &x) const { + return x.m_Closure.IsLess(m_Closure); } + // Binding to non-const member functions + template < class X, class Y > + FastDelegate0(Y *pthis, DesiredRetType (X::* function_to_bind)() ) { + m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } + template < class X, class Y > + inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)()) { + m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } + // Binding to const member functions. + template < class X, class Y > + FastDelegate0(const Y *pthis, DesiredRetType (X::* function_to_bind)() const) { + m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } + template < class X, class Y > + inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)() const) { + m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } + // Static functions. We convert them into a member function call. + // This constructor also provides implicit conversion + FastDelegate0(DesiredRetType (*function_to_bind)() ) { + bind(function_to_bind); } + // for efficiency, prevent creation of a temporary + void operator = (DesiredRetType (*function_to_bind)() ) { + bind(function_to_bind); } + inline void bind(DesiredRetType (*function_to_bind)()) { + m_Closure.bindstaticfunc(this, &FastDelegate0::InvokeStaticFunction, + function_to_bind); } + // Invoke the delegate + RetType operator() () const { + return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(); } + // Implicit conversion to "bool" using the safe_bool idiom +private: + typedef struct SafeBoolStruct { + int a_data_pointer_to_this_is_0_on_buggy_compilers; + StaticFunctionPtr m_nonzero; + } UselessTypedef; + typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; +public: + operator unspecified_bool_type() const { + return empty()? 0: &SafeBoolStruct::m_nonzero; + } + // necessary to allow ==0 to work despite the safe_bool idiom + inline bool operator==(StaticFunctionPtr funcptr) { + return m_Closure.IsEqualToStaticFuncPtr(funcptr); } + inline bool operator!=(StaticFunctionPtr funcptr) { + return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } + inline bool operator ! () const { // Is it bound to anything? + return !m_Closure; } + inline bool empty() const { + return !m_Closure; } + void clear() { m_Closure.clear();} + // Conversion to and from the DelegateMemento storage class + const DelegateMemento & GetMemento() { return m_Closure; } + void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } + +private: // Invoker for static functions + RetType InvokeStaticFunction() const { + return (*(m_Closure.GetStaticFunction()))(); } +}; + +//N=1 +template +class FastDelegate1 { +private: + typedef typename detail::DefaultVoidToVoid::type DesiredRetType; + typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1); + typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1); + typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1); + typedef detail::ClosurePtr ClosureType; + ClosureType m_Closure; +public: + // Typedefs to aid generic programming + typedef FastDelegate1 type; + + // Construction and comparison functions + FastDelegate1() { clear(); } + FastDelegate1(const FastDelegate1 &x) { + m_Closure.CopyFrom(this, x.m_Closure); } + void operator = (const FastDelegate1 &x) { + m_Closure.CopyFrom(this, x.m_Closure); } + bool operator ==(const FastDelegate1 &x) const { + return m_Closure.IsEqual(x.m_Closure); } + bool operator !=(const FastDelegate1 &x) const { + return !m_Closure.IsEqual(x.m_Closure); } + bool operator <(const FastDelegate1 &x) const { + return m_Closure.IsLess(x.m_Closure); } + bool operator >(const FastDelegate1 &x) const { + return x.m_Closure.IsLess(m_Closure); } + // Binding to non-const member functions + template < class X, class Y > + FastDelegate1(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1) ) { + m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } + template < class X, class Y > + inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1)) { + m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } + // Binding to const member functions. + template < class X, class Y > + FastDelegate1(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1) const) { + m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } + template < class X, class Y > + inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1) const) { + m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } + // Static functions. We convert them into a member function call. + // This constructor also provides implicit conversion + FastDelegate1(DesiredRetType (*function_to_bind)(Param1 p1) ) { + bind(function_to_bind); } + // for efficiency, prevent creation of a temporary + void operator = (DesiredRetType (*function_to_bind)(Param1 p1) ) { + bind(function_to_bind); } + inline void bind(DesiredRetType (*function_to_bind)(Param1 p1)) { + m_Closure.bindstaticfunc(this, &FastDelegate1::InvokeStaticFunction, + function_to_bind); } + // Invoke the delegate + RetType operator() (Param1 p1) const { + return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1); } + // Implicit conversion to "bool" using the safe_bool idiom +private: + typedef struct SafeBoolStruct { + int a_data_pointer_to_this_is_0_on_buggy_compilers; + StaticFunctionPtr m_nonzero; + } UselessTypedef; + typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; +public: + operator unspecified_bool_type() const { + return empty()? 0: &SafeBoolStruct::m_nonzero; + } + // necessary to allow ==0 to work despite the safe_bool idiom + inline bool operator==(StaticFunctionPtr funcptr) { + return m_Closure.IsEqualToStaticFuncPtr(funcptr); } + inline bool operator!=(StaticFunctionPtr funcptr) { + return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } + inline bool operator ! () const { // Is it bound to anything? + return !m_Closure; } + inline bool empty() const { + return !m_Closure; } + void clear() { m_Closure.clear();} + // Conversion to and from the DelegateMemento storage class + const DelegateMemento & GetMemento() { return m_Closure; } + void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } + +private: // Invoker for static functions + RetType InvokeStaticFunction(Param1 p1) const { + return (*(m_Closure.GetStaticFunction()))(p1); } +}; + +//N=2 +template +class FastDelegate2 { +private: + typedef typename detail::DefaultVoidToVoid::type DesiredRetType; + typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2); + typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2); + typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2); + typedef detail::ClosurePtr ClosureType; + ClosureType m_Closure; +public: + // Typedefs to aid generic programming + typedef FastDelegate2 type; + + // Construction and comparison functions + FastDelegate2() { clear(); } + FastDelegate2(const FastDelegate2 &x) { + m_Closure.CopyFrom(this, x.m_Closure); } + void operator = (const FastDelegate2 &x) { + m_Closure.CopyFrom(this, x.m_Closure); } + bool operator ==(const FastDelegate2 &x) const { + return m_Closure.IsEqual(x.m_Closure); } + bool operator !=(const FastDelegate2 &x) const { + return !m_Closure.IsEqual(x.m_Closure); } + bool operator <(const FastDelegate2 &x) const { + return m_Closure.IsLess(x.m_Closure); } + bool operator >(const FastDelegate2 &x) const { + return x.m_Closure.IsLess(m_Closure); } + // Binding to non-const member functions + template < class X, class Y > + FastDelegate2(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2) ) { + m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } + template < class X, class Y > + inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2)) { + m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } + // Binding to const member functions. + template < class X, class Y > + FastDelegate2(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2) const) { + m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } + template < class X, class Y > + inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2) const) { + m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } + // Static functions. We convert them into a member function call. + // This constructor also provides implicit conversion + FastDelegate2(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2) ) { + bind(function_to_bind); } + // for efficiency, prevent creation of a temporary + void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2) ) { + bind(function_to_bind); } + inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2)) { + m_Closure.bindstaticfunc(this, &FastDelegate2::InvokeStaticFunction, + function_to_bind); } + // Invoke the delegate + RetType operator() (Param1 p1, Param2 p2) const { + return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2); } + // Implicit conversion to "bool" using the safe_bool idiom +private: + typedef struct SafeBoolStruct { + int a_data_pointer_to_this_is_0_on_buggy_compilers; + StaticFunctionPtr m_nonzero; + } UselessTypedef; + typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; +public: + operator unspecified_bool_type() const { + return empty()? 0: &SafeBoolStruct::m_nonzero; + } + // necessary to allow ==0 to work despite the safe_bool idiom + inline bool operator==(StaticFunctionPtr funcptr) { + return m_Closure.IsEqualToStaticFuncPtr(funcptr); } + inline bool operator!=(StaticFunctionPtr funcptr) { + return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } + inline bool operator ! () const { // Is it bound to anything? + return !m_Closure; } + inline bool empty() const { + return !m_Closure; } + void clear() { m_Closure.clear();} + // Conversion to and from the DelegateMemento storage class + const DelegateMemento & GetMemento() { return m_Closure; } + void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } + +private: // Invoker for static functions + RetType InvokeStaticFunction(Param1 p1, Param2 p2) const { + return (*(m_Closure.GetStaticFunction()))(p1, p2); } +}; + +//N=3 +template +class FastDelegate3 { +private: + typedef typename detail::DefaultVoidToVoid::type DesiredRetType; + typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3); + typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3); + typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3); + typedef detail::ClosurePtr ClosureType; + ClosureType m_Closure; +public: + // Typedefs to aid generic programming + typedef FastDelegate3 type; + + // Construction and comparison functions + FastDelegate3() { clear(); } + FastDelegate3(const FastDelegate3 &x) { + m_Closure.CopyFrom(this, x.m_Closure); } + void operator = (const FastDelegate3 &x) { + m_Closure.CopyFrom(this, x.m_Closure); } + bool operator ==(const FastDelegate3 &x) const { + return m_Closure.IsEqual(x.m_Closure); } + bool operator !=(const FastDelegate3 &x) const { + return !m_Closure.IsEqual(x.m_Closure); } + bool operator <(const FastDelegate3 &x) const { + return m_Closure.IsLess(x.m_Closure); } + bool operator >(const FastDelegate3 &x) const { + return x.m_Closure.IsLess(m_Closure); } + // Binding to non-const member functions + template < class X, class Y > + FastDelegate3(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3) ) { + m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } + template < class X, class Y > + inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3)) { + m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } + // Binding to const member functions. + template < class X, class Y > + FastDelegate3(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3) const) { + m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } + template < class X, class Y > + inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3) const) { + m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } + // Static functions. We convert them into a member function call. + // This constructor also provides implicit conversion + FastDelegate3(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3) ) { + bind(function_to_bind); } + // for efficiency, prevent creation of a temporary + void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3) ) { + bind(function_to_bind); } + inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3)) { + m_Closure.bindstaticfunc(this, &FastDelegate3::InvokeStaticFunction, + function_to_bind); } + // Invoke the delegate + RetType operator() (Param1 p1, Param2 p2, Param3 p3) const { + return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3); } + // Implicit conversion to "bool" using the safe_bool idiom +private: + typedef struct SafeBoolStruct { + int a_data_pointer_to_this_is_0_on_buggy_compilers; + StaticFunctionPtr m_nonzero; + } UselessTypedef; + typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; +public: + operator unspecified_bool_type() const { + return empty()? 0: &SafeBoolStruct::m_nonzero; + } + // necessary to allow ==0 to work despite the safe_bool idiom + inline bool operator==(StaticFunctionPtr funcptr) { + return m_Closure.IsEqualToStaticFuncPtr(funcptr); } + inline bool operator!=(StaticFunctionPtr funcptr) { + return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } + inline bool operator ! () const { // Is it bound to anything? + return !m_Closure; } + inline bool empty() const { + return !m_Closure; } + void clear() { m_Closure.clear();} + // Conversion to and from the DelegateMemento storage class + const DelegateMemento & GetMemento() { return m_Closure; } + void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } + +private: // Invoker for static functions + RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3) const { + return (*(m_Closure.GetStaticFunction()))(p1, p2, p3); } +}; + +//N=4 +template +class FastDelegate4 { +private: + typedef typename detail::DefaultVoidToVoid::type DesiredRetType; + typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4); + typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4); + typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4); + typedef detail::ClosurePtr ClosureType; + ClosureType m_Closure; +public: + // Typedefs to aid generic programming + typedef FastDelegate4 type; + + // Construction and comparison functions + FastDelegate4() { clear(); } + FastDelegate4(const FastDelegate4 &x) { + m_Closure.CopyFrom(this, x.m_Closure); } + void operator = (const FastDelegate4 &x) { + m_Closure.CopyFrom(this, x.m_Closure); } + bool operator ==(const FastDelegate4 &x) const { + return m_Closure.IsEqual(x.m_Closure); } + bool operator !=(const FastDelegate4 &x) const { + return !m_Closure.IsEqual(x.m_Closure); } + bool operator <(const FastDelegate4 &x) const { + return m_Closure.IsLess(x.m_Closure); } + bool operator >(const FastDelegate4 &x) const { + return x.m_Closure.IsLess(m_Closure); } + // Binding to non-const member functions + template < class X, class Y > + FastDelegate4(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4) ) { + m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } + template < class X, class Y > + inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4)) { + m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } + // Binding to const member functions. + template < class X, class Y > + FastDelegate4(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const) { + m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } + template < class X, class Y > + inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const) { + m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } + // Static functions. We convert them into a member function call. + // This constructor also provides implicit conversion + FastDelegate4(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4) ) { + bind(function_to_bind); } + // for efficiency, prevent creation of a temporary + void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4) ) { + bind(function_to_bind); } + inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4)) { + m_Closure.bindstaticfunc(this, &FastDelegate4::InvokeStaticFunction, + function_to_bind); } + // Invoke the delegate + RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4) const { + return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4); } + // Implicit conversion to "bool" using the safe_bool idiom +private: + typedef struct SafeBoolStruct { + int a_data_pointer_to_this_is_0_on_buggy_compilers; + StaticFunctionPtr m_nonzero; + } UselessTypedef; + typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; +public: + operator unspecified_bool_type() const { + return empty()? 0: &SafeBoolStruct::m_nonzero; + } + // necessary to allow ==0 to work despite the safe_bool idiom + inline bool operator==(StaticFunctionPtr funcptr) { + return m_Closure.IsEqualToStaticFuncPtr(funcptr); } + inline bool operator!=(StaticFunctionPtr funcptr) { + return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } + inline bool operator ! () const { // Is it bound to anything? + return !m_Closure; } + inline bool empty() const { + return !m_Closure; } + void clear() { m_Closure.clear();} + // Conversion to and from the DelegateMemento storage class + const DelegateMemento & GetMemento() { return m_Closure; } + void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } + +private: // Invoker for static functions + RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const { + return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4); } +}; + +//N=5 +template +class FastDelegate5 { +private: + typedef typename detail::DefaultVoidToVoid::type DesiredRetType; + typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5); + typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5); + typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5); + typedef detail::ClosurePtr ClosureType; + ClosureType m_Closure; +public: + // Typedefs to aid generic programming + typedef FastDelegate5 type; + + // Construction and comparison functions + FastDelegate5() { clear(); } + FastDelegate5(const FastDelegate5 &x) { + m_Closure.CopyFrom(this, x.m_Closure); } + void operator = (const FastDelegate5 &x) { + m_Closure.CopyFrom(this, x.m_Closure); } + bool operator ==(const FastDelegate5 &x) const { + return m_Closure.IsEqual(x.m_Closure); } + bool operator !=(const FastDelegate5 &x) const { + return !m_Closure.IsEqual(x.m_Closure); } + bool operator <(const FastDelegate5 &x) const { + return m_Closure.IsLess(x.m_Closure); } + bool operator >(const FastDelegate5 &x) const { + return x.m_Closure.IsLess(m_Closure); } + // Binding to non-const member functions + template < class X, class Y > + FastDelegate5(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) ) { + m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } + template < class X, class Y > + inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5)) { + m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } + // Binding to const member functions. + template < class X, class Y > + FastDelegate5(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const) { + m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } + template < class X, class Y > + inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const) { + m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } + // Static functions. We convert them into a member function call. + // This constructor also provides implicit conversion + FastDelegate5(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) ) { + bind(function_to_bind); } + // for efficiency, prevent creation of a temporary + void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) ) { + bind(function_to_bind); } + inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5)) { + m_Closure.bindstaticfunc(this, &FastDelegate5::InvokeStaticFunction, + function_to_bind); } + // Invoke the delegate + RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const { + return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4, p5); } + // Implicit conversion to "bool" using the safe_bool idiom +private: + typedef struct SafeBoolStruct { + int a_data_pointer_to_this_is_0_on_buggy_compilers; + StaticFunctionPtr m_nonzero; + } UselessTypedef; + typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; +public: + operator unspecified_bool_type() const { + return empty()? 0: &SafeBoolStruct::m_nonzero; + } + // necessary to allow ==0 to work despite the safe_bool idiom + inline bool operator==(StaticFunctionPtr funcptr) { + return m_Closure.IsEqualToStaticFuncPtr(funcptr); } + inline bool operator!=(StaticFunctionPtr funcptr) { + return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } + inline bool operator ! () const { // Is it bound to anything? + return !m_Closure; } + inline bool empty() const { + return !m_Closure; } + void clear() { m_Closure.clear();} + // Conversion to and from the DelegateMemento storage class + const DelegateMemento & GetMemento() { return m_Closure; } + void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } + +private: // Invoker for static functions + RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const { + return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4, p5); } +}; + +//N=6 +template +class FastDelegate6 { +private: + typedef typename detail::DefaultVoidToVoid::type DesiredRetType; + typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6); + typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6); + typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6); + typedef detail::ClosurePtr ClosureType; + ClosureType m_Closure; +public: + // Typedefs to aid generic programming + typedef FastDelegate6 type; + + // Construction and comparison functions + FastDelegate6() { clear(); } + FastDelegate6(const FastDelegate6 &x) { + m_Closure.CopyFrom(this, x.m_Closure); } + void operator = (const FastDelegate6 &x) { + m_Closure.CopyFrom(this, x.m_Closure); } + bool operator ==(const FastDelegate6 &x) const { + return m_Closure.IsEqual(x.m_Closure); } + bool operator !=(const FastDelegate6 &x) const { + return !m_Closure.IsEqual(x.m_Closure); } + bool operator <(const FastDelegate6 &x) const { + return m_Closure.IsLess(x.m_Closure); } + bool operator >(const FastDelegate6 &x) const { + return x.m_Closure.IsLess(m_Closure); } + // Binding to non-const member functions + template < class X, class Y > + FastDelegate6(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) ) { + m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } + template < class X, class Y > + inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6)) { + m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } + // Binding to const member functions. + template < class X, class Y > + FastDelegate6(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const) { + m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } + template < class X, class Y > + inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const) { + m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } + // Static functions. We convert them into a member function call. + // This constructor also provides implicit conversion + FastDelegate6(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) ) { + bind(function_to_bind); } + // for efficiency, prevent creation of a temporary + void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) ) { + bind(function_to_bind); } + inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6)) { + m_Closure.bindstaticfunc(this, &FastDelegate6::InvokeStaticFunction, + function_to_bind); } + // Invoke the delegate + RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const { + return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4, p5, p6); } + // Implicit conversion to "bool" using the safe_bool idiom +private: + typedef struct SafeBoolStruct { + int a_data_pointer_to_this_is_0_on_buggy_compilers; + StaticFunctionPtr m_nonzero; + } UselessTypedef; + typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; +public: + operator unspecified_bool_type() const { + return empty()? 0: &SafeBoolStruct::m_nonzero; + } + // necessary to allow ==0 to work despite the safe_bool idiom + inline bool operator==(StaticFunctionPtr funcptr) { + return m_Closure.IsEqualToStaticFuncPtr(funcptr); } + inline bool operator!=(StaticFunctionPtr funcptr) { + return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } + inline bool operator ! () const { // Is it bound to anything? + return !m_Closure; } + inline bool empty() const { + return !m_Closure; } + void clear() { m_Closure.clear();} + // Conversion to and from the DelegateMemento storage class + const DelegateMemento & GetMemento() { return m_Closure; } + void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } + +private: // Invoker for static functions + RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const { + return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4, p5, p6); } +}; + +//N=7 +template +class FastDelegate7 { +private: + typedef typename detail::DefaultVoidToVoid::type DesiredRetType; + typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7); + typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7); + typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7); + typedef detail::ClosurePtr ClosureType; + ClosureType m_Closure; +public: + // Typedefs to aid generic programming + typedef FastDelegate7 type; + + // Construction and comparison functions + FastDelegate7() { clear(); } + FastDelegate7(const FastDelegate7 &x) { + m_Closure.CopyFrom(this, x.m_Closure); } + void operator = (const FastDelegate7 &x) { + m_Closure.CopyFrom(this, x.m_Closure); } + bool operator ==(const FastDelegate7 &x) const { + return m_Closure.IsEqual(x.m_Closure); } + bool operator !=(const FastDelegate7 &x) const { + return !m_Closure.IsEqual(x.m_Closure); } + bool operator <(const FastDelegate7 &x) const { + return m_Closure.IsLess(x.m_Closure); } + bool operator >(const FastDelegate7 &x) const { + return x.m_Closure.IsLess(m_Closure); } + // Binding to non-const member functions + template < class X, class Y > + FastDelegate7(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) ) { + m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } + template < class X, class Y > + inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7)) { + m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } + // Binding to const member functions. + template < class X, class Y > + FastDelegate7(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const) { + m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } + template < class X, class Y > + 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) { + m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } + // Static functions. We convert them into a member function call. + // This constructor also provides implicit conversion + FastDelegate7(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) ) { + bind(function_to_bind); } + // for efficiency, prevent creation of a temporary + void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) ) { + bind(function_to_bind); } + inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7)) { + m_Closure.bindstaticfunc(this, &FastDelegate7::InvokeStaticFunction, + function_to_bind); } + // Invoke the delegate + RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const { + return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4, p5, p6, p7); } + // Implicit conversion to "bool" using the safe_bool idiom +private: + typedef struct SafeBoolStruct { + int a_data_pointer_to_this_is_0_on_buggy_compilers; + StaticFunctionPtr m_nonzero; + } UselessTypedef; + typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; +public: + operator unspecified_bool_type() const { + return empty()? 0: &SafeBoolStruct::m_nonzero; + } + // necessary to allow ==0 to work despite the safe_bool idiom + inline bool operator==(StaticFunctionPtr funcptr) { + return m_Closure.IsEqualToStaticFuncPtr(funcptr); } + inline bool operator!=(StaticFunctionPtr funcptr) { + return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } + inline bool operator ! () const { // Is it bound to anything? + return !m_Closure; } + inline bool empty() const { + return !m_Closure; } + void clear() { m_Closure.clear();} + // Conversion to and from the DelegateMemento storage class + const DelegateMemento & GetMemento() { return m_Closure; } + void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } + +private: // Invoker for static functions + RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const { + return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4, p5, p6, p7); } +}; + +//N=8 +template +class FastDelegate8 { +private: + typedef typename detail::DefaultVoidToVoid::type DesiredRetType; + typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8); + typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8); + typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8); + typedef detail::ClosurePtr ClosureType; + ClosureType m_Closure; +public: + // Typedefs to aid generic programming + typedef FastDelegate8 type; + + // Construction and comparison functions + FastDelegate8() { clear(); } + FastDelegate8(const FastDelegate8 &x) { + m_Closure.CopyFrom(this, x.m_Closure); } + void operator = (const FastDelegate8 &x) { + m_Closure.CopyFrom(this, x.m_Closure); } + bool operator ==(const FastDelegate8 &x) const { + return m_Closure.IsEqual(x.m_Closure); } + bool operator !=(const FastDelegate8 &x) const { + return !m_Closure.IsEqual(x.m_Closure); } + bool operator <(const FastDelegate8 &x) const { + return m_Closure.IsLess(x.m_Closure); } + bool operator >(const FastDelegate8 &x) const { + return x.m_Closure.IsLess(m_Closure); } + // Binding to non-const member functions + template < class X, class Y > + FastDelegate8(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) ) { + m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } + template < class X, class Y > + 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)) { + m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } + // Binding to const member functions. + template < class X, class Y > + 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) { + m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } + template < class X, class Y > + 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) { + m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } + // Static functions. We convert them into a member function call. + // This constructor also provides implicit conversion + FastDelegate8(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) ) { + bind(function_to_bind); } + // for efficiency, prevent creation of a temporary + void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) ) { + bind(function_to_bind); } + inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8)) { + m_Closure.bindstaticfunc(this, &FastDelegate8::InvokeStaticFunction, + function_to_bind); } + // Invoke the delegate + RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const { + return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4, p5, p6, p7, p8); } + // Implicit conversion to "bool" using the safe_bool idiom +private: + typedef struct SafeBoolStruct { + int a_data_pointer_to_this_is_0_on_buggy_compilers; + StaticFunctionPtr m_nonzero; + } UselessTypedef; + typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; +public: + operator unspecified_bool_type() const { + return empty()? 0: &SafeBoolStruct::m_nonzero; + } + // necessary to allow ==0 to work despite the safe_bool idiom + inline bool operator==(StaticFunctionPtr funcptr) { + return m_Closure.IsEqualToStaticFuncPtr(funcptr); } + inline bool operator!=(StaticFunctionPtr funcptr) { + return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } + inline bool operator ! () const { // Is it bound to anything? + return !m_Closure; } + inline bool empty() const { + return !m_Closure; } + void clear() { m_Closure.clear();} + // Conversion to and from the DelegateMemento storage class + const DelegateMemento & GetMemento() { return m_Closure; } + void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } + +private: // Invoker for static functions + RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const { + return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4, p5, p6, p7, p8); } +}; + + +//////////////////////////////////////////////////////////////////////////////// +// Fast Delegates, part 4: +// +// FastDelegate<> class (Original author: Jody Hagins) +// Allows boost::function style syntax like: +// FastDelegate< double (int, long) > +// instead of: +// FastDelegate2< int, long, double > +// +//////////////////////////////////////////////////////////////////////////////// + +#ifdef FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX + +// Declare FastDelegate as a class template. It will be specialized +// later for all number of arguments. +template +class FastDelegate; + +//N=0 +// Specialization to allow use of +// FastDelegate< R ( ) > +// instead of +// FastDelegate0 < R > +template +class FastDelegate< R ( ) > + // Inherit from FastDelegate0 so that it can be treated just like a FastDelegate0 + : public FastDelegate0 < R > +{ +public: + // Make using the base type a bit easier via typedef. + typedef FastDelegate0 < R > BaseType; + + // Allow users access to the specific type of this delegate. + typedef FastDelegate SelfType; + + // Mimic the base class constructors. + FastDelegate() : BaseType() { } + + template < class X, class Y > + FastDelegate(Y * pthis, + R (X::* function_to_bind)( )) + : BaseType(pthis, function_to_bind) { } + + template < class X, class Y > + FastDelegate(const Y *pthis, + R (X::* function_to_bind)( ) const) + : BaseType(pthis, function_to_bind) + { } + + FastDelegate(R (*function_to_bind)( )) + : BaseType(function_to_bind) { } + void operator = (const BaseType &x) { + *static_cast(this) = x; } +}; + +//N=1 +// Specialization to allow use of +// FastDelegate< R ( Param1 ) > +// instead of +// FastDelegate1 < Param1, R > +template +class FastDelegate< R ( Param1 ) > + // Inherit from FastDelegate1 so that it can be treated just like a FastDelegate1 + : public FastDelegate1 < Param1, R > +{ +public: + // Make using the base type a bit easier via typedef. + typedef FastDelegate1 < Param1, R > BaseType; + + // Allow users access to the specific type of this delegate. + typedef FastDelegate SelfType; + + // Mimic the base class constructors. + FastDelegate() : BaseType() { } + + template < class X, class Y > + FastDelegate(Y * pthis, + R (X::* function_to_bind)( Param1 p1 )) + : BaseType(pthis, function_to_bind) { } + + template < class X, class Y > + FastDelegate(const Y *pthis, + R (X::* function_to_bind)( Param1 p1 ) const) + : BaseType(pthis, function_to_bind) + { } + + FastDelegate(R (*function_to_bind)( Param1 p1 )) + : BaseType(function_to_bind) { } + void operator = (const BaseType &x) { + *static_cast(this) = x; } +}; + +//N=2 +// Specialization to allow use of +// FastDelegate< R ( Param1, Param2 ) > +// instead of +// FastDelegate2 < Param1, Param2, R > +template +class FastDelegate< R ( Param1, Param2 ) > + // Inherit from FastDelegate2 so that it can be treated just like a FastDelegate2 + : public FastDelegate2 < Param1, Param2, R > +{ +public: + // Make using the base type a bit easier via typedef. + typedef FastDelegate2 < Param1, Param2, R > BaseType; + + // Allow users access to the specific type of this delegate. + typedef FastDelegate SelfType; + + // Mimic the base class constructors. + FastDelegate() : BaseType() { } + + template < class X, class Y > + FastDelegate(Y * pthis, + R (X::* function_to_bind)( Param1 p1, Param2 p2 )) + : BaseType(pthis, function_to_bind) { } + + template < class X, class Y > + FastDelegate(const Y *pthis, + R (X::* function_to_bind)( Param1 p1, Param2 p2 ) const) + : BaseType(pthis, function_to_bind) + { } + + FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2 )) + : BaseType(function_to_bind) { } + void operator = (const BaseType &x) { + *static_cast(this) = x; } +}; + +//N=3 +// Specialization to allow use of +// FastDelegate< R ( Param1, Param2, Param3 ) > +// instead of +// FastDelegate3 < Param1, Param2, Param3, R > +template +class FastDelegate< R ( Param1, Param2, Param3 ) > + // Inherit from FastDelegate3 so that it can be treated just like a FastDelegate3 + : public FastDelegate3 < Param1, Param2, Param3, R > +{ +public: + // Make using the base type a bit easier via typedef. + typedef FastDelegate3 < Param1, Param2, Param3, R > BaseType; + + // Allow users access to the specific type of this delegate. + typedef FastDelegate SelfType; + + // Mimic the base class constructors. + FastDelegate() : BaseType() { } + + template < class X, class Y > + FastDelegate(Y * pthis, + R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3 )) + : BaseType(pthis, function_to_bind) { } + + template < class X, class Y > + FastDelegate(const Y *pthis, + R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3 ) const) + : BaseType(pthis, function_to_bind) + { } + + FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3 )) + : BaseType(function_to_bind) { } + void operator = (const BaseType &x) { + *static_cast(this) = x; } +}; + +//N=4 +// Specialization to allow use of +// FastDelegate< R ( Param1, Param2, Param3, Param4 ) > +// instead of +// FastDelegate4 < Param1, Param2, Param3, Param4, R > +template +class FastDelegate< R ( Param1, Param2, Param3, Param4 ) > + // Inherit from FastDelegate4 so that it can be treated just like a FastDelegate4 + : public FastDelegate4 < Param1, Param2, Param3, Param4, R > +{ +public: + // Make using the base type a bit easier via typedef. + typedef FastDelegate4 < Param1, Param2, Param3, Param4, R > BaseType; + + // Allow users access to the specific type of this delegate. + typedef FastDelegate SelfType; + + // Mimic the base class constructors. + FastDelegate() : BaseType() { } + + template < class X, class Y > + FastDelegate(Y * pthis, + R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4 )) + : BaseType(pthis, function_to_bind) { } + + template < class X, class Y > + FastDelegate(const Y *pthis, + R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4 ) const) + : BaseType(pthis, function_to_bind) + { } + + FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4 )) + : BaseType(function_to_bind) { } + void operator = (const BaseType &x) { + *static_cast(this) = x; } +}; + +//N=5 +// Specialization to allow use of +// FastDelegate< R ( Param1, Param2, Param3, Param4, Param5 ) > +// instead of +// FastDelegate5 < Param1, Param2, Param3, Param4, Param5, R > +template +class FastDelegate< R ( Param1, Param2, Param3, Param4, Param5 ) > + // Inherit from FastDelegate5 so that it can be treated just like a FastDelegate5 + : public FastDelegate5 < Param1, Param2, Param3, Param4, Param5, R > +{ +public: + // Make using the base type a bit easier via typedef. + typedef FastDelegate5 < Param1, Param2, Param3, Param4, Param5, R > BaseType; + + // Allow users access to the specific type of this delegate. + typedef FastDelegate SelfType; + + // Mimic the base class constructors. + FastDelegate() : BaseType() { } + + template < class X, class Y > + FastDelegate(Y * pthis, + R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5 )) + : BaseType(pthis, function_to_bind) { } + + template < class X, class Y > + FastDelegate(const Y *pthis, + R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5 ) const) + : BaseType(pthis, function_to_bind) + { } + + FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5 )) + : BaseType(function_to_bind) { } + void operator = (const BaseType &x) { + *static_cast(this) = x; } +}; + +//N=6 +// Specialization to allow use of +// FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6 ) > +// instead of +// FastDelegate6 < Param1, Param2, Param3, Param4, Param5, Param6, R > +template +class FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6 ) > + // Inherit from FastDelegate6 so that it can be treated just like a FastDelegate6 + : public FastDelegate6 < Param1, Param2, Param3, Param4, Param5, Param6, R > +{ +public: + // Make using the base type a bit easier via typedef. + typedef FastDelegate6 < Param1, Param2, Param3, Param4, Param5, Param6, R > BaseType; + + // Allow users access to the specific type of this delegate. + typedef FastDelegate SelfType; + + // Mimic the base class constructors. + FastDelegate() : BaseType() { } + + template < class X, class Y > + FastDelegate(Y * pthis, + R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6 )) + : BaseType(pthis, function_to_bind) { } + + template < class X, class Y > + FastDelegate(const Y *pthis, + R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6 ) const) + : BaseType(pthis, function_to_bind) + { } + + FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6 )) + : BaseType(function_to_bind) { } + void operator = (const BaseType &x) { + *static_cast(this) = x; } +}; + +//N=7 +// Specialization to allow use of +// FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7 ) > +// instead of +// FastDelegate7 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, R > +template +class FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7 ) > + // Inherit from FastDelegate7 so that it can be treated just like a FastDelegate7 + : public FastDelegate7 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, R > +{ +public: + // Make using the base type a bit easier via typedef. + typedef FastDelegate7 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, R > BaseType; + + // Allow users access to the specific type of this delegate. + typedef FastDelegate SelfType; + + // Mimic the base class constructors. + FastDelegate() : BaseType() { } + + template < class X, class Y > + FastDelegate(Y * pthis, + R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7 )) + : BaseType(pthis, function_to_bind) { } + + template < class X, class Y > + FastDelegate(const Y *pthis, + R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7 ) const) + : BaseType(pthis, function_to_bind) + { } + + FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7 )) + : BaseType(function_to_bind) { } + void operator = (const BaseType &x) { + *static_cast(this) = x; } +}; + +//N=8 +// Specialization to allow use of +// FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8 ) > +// instead of +// FastDelegate8 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, R > +template +class FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8 ) > + // Inherit from FastDelegate8 so that it can be treated just like a FastDelegate8 + : public FastDelegate8 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, R > +{ +public: + // Make using the base type a bit easier via typedef. + typedef FastDelegate8 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, R > BaseType; + + // Allow users access to the specific type of this delegate. + typedef FastDelegate SelfType; + + // Mimic the base class constructors. + FastDelegate() : BaseType() { } + + template < class X, class Y > + FastDelegate(Y * pthis, + R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8 )) + : BaseType(pthis, function_to_bind) { } + + template < class X, class Y > + FastDelegate(const Y *pthis, + R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8 ) const) + : BaseType(pthis, function_to_bind) + { } + + FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8 )) + : BaseType(function_to_bind) { } + void operator = (const BaseType &x) { + *static_cast(this) = x; } +}; + + +#endif //FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX + +//////////////////////////////////////////////////////////////////////////////// +// Fast Delegates, part 5: +// +// MakeDelegate() helper function +// +// MakeDelegate(&x, &X::func) returns a fastdelegate of the type +// necessary for calling x.func() with the correct number of arguments. +// This makes it possible to eliminate many typedefs from user code. +// +//////////////////////////////////////////////////////////////////////////////// + +// Also declare overloads of a MakeDelegate() global function to +// reduce the need for typedefs. +// We need seperate overloads for const and non-const member functions. +// Also, because of the weird rule about the class of derived member function pointers, +// implicit downcasts may need to be applied later to the 'this' pointer. +// That's why two classes (X and Y) appear in the definitions. Y must be implicitly +// castable to X. + +// Workaround for VC6. VC6 needs void return types converted into DefaultVoid. +// GCC 3.2 and later won't compile this unless it's preceded by 'typename', +// but VC6 doesn't allow 'typename' in this context. +// So, I have to use a macro. + +#ifdef FASTDLGT_VC6 +#define FASTDLGT_RETTYPE detail::VoidToDefaultVoid::type +#else +#define FASTDLGT_RETTYPE RetType +#endif + +//N=0 +template +FastDelegate0 MakeDelegate(Y* x, RetType (X::*func)()) { + return FastDelegate0(x, func); +} + +template +FastDelegate0 MakeDelegate(Y* x, RetType (X::*func)() const) { + return FastDelegate0(x, func); +} + +//N=1 +template +FastDelegate1 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1)) { + return FastDelegate1(x, func); +} + +template +FastDelegate1 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1) const) { + return FastDelegate1(x, func); +} + +//N=2 +template +FastDelegate2 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2)) { + return FastDelegate2(x, func); +} + +template +FastDelegate2 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2) const) { + return FastDelegate2(x, func); +} + +//N=3 +template +FastDelegate3 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3)) { + return FastDelegate3(x, func); +} + +template +FastDelegate3 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3) const) { + return FastDelegate3(x, func); +} + +//N=4 +template +FastDelegate4 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4)) { + return FastDelegate4(x, func); +} + +template +FastDelegate4 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const) { + return FastDelegate4(x, func); +} + +//N=5 +template +FastDelegate5 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5)) { + return FastDelegate5(x, func); +} + +template +FastDelegate5 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const) { + return FastDelegate5(x, func); +} + +//N=6 +template +FastDelegate6 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6)) { + return FastDelegate6(x, func); +} + +template +FastDelegate6 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const) { + return FastDelegate6(x, func); +} + +//N=7 +template +FastDelegate7 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7)) { + return FastDelegate7(x, func); +} + +template +FastDelegate7 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const) { + return FastDelegate7(x, func); +} + +//N=8 +template +FastDelegate8 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8)) { + return FastDelegate8(x, func); +} + +template +FastDelegate8 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const) { + return FastDelegate8(x, func); +} + + + // clean up after ourselves... +#undef FASTDLGT_RETTYPE + +} // namespace fastdelegate + +#endif // !defined(FASTDELEGATE_H) + diff --git a/modules/core/include/dpl/3rdparty/fastdelegate/FastDelegateBind.h b/modules/core/include/dpl/3rdparty/fastdelegate/FastDelegateBind.h new file mode 100644 index 0000000..083a807 --- /dev/null +++ b/modules/core/include/dpl/3rdparty/fastdelegate/FastDelegateBind.h @@ -0,0 +1,243 @@ +// FastDelegateBind.h +// Helper file for FastDelegates. Provides bind() function, enabling +// FastDelegates to be rapidly compared to programs using boost::function and boost::bind. +// +// Documentation is found at http://www.codeproject.com/cpp/FastDelegate.asp +// +// Original author: Jody Hagins. +// Minor changes by Don Clugston. +// +// Warning: The arguments to 'bind' are ignored! No actual binding is performed. +// The behaviour is equivalent to boost::bind only when the basic placeholder +// arguments _1, _2, _3, etc are used in order. +// +// HISTORY: +// 1.4 Dec 2004. Initial release as part of FastDelegate 1.4. + + +#ifndef FASTDELEGATEBIND_H +#define FASTDELEGATEBIND_H +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +//////////////////////////////////////////////////////////////////////////////// +// FastDelegate bind() +// +// bind() helper function for boost compatibility. +// (Original author: Jody Hagins). +// +// Add another helper, so FastDelegate can be a dropin replacement +// for boost::bind (in a fair number of cases). +// Note the elipses, because boost::bind() takes place holders +// but FastDelegate does not care about them. Getting the place holder +// mechanism to work, and play well with boost is a bit tricky, so +// we do the "easy" thing... +// Assume we have the following code... +// using boost::bind; +// bind(&Foo:func, &foo, _1, _2); +// we should be able to replace the "using" with... +// using fastdelegate::bind; +// and everything should work fine... +//////////////////////////////////////////////////////////////////////////////// + +#ifdef FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX + +namespace fastdelegate { + +//N=0 +template +FastDelegate< RetType ( ) > +bind( + RetType (X::*func)( ), + Y * y, + ...) +{ + return FastDelegate< RetType ( ) >(y, func); +} + +template +FastDelegate< RetType ( ) > +bind( + RetType (X::*func)( ) const, + Y * y, + ...) +{ + return FastDelegate< RetType ( ) >(y, func); +} + +//N=1 +template +FastDelegate< RetType ( Param1 p1 ) > +bind( + RetType (X::*func)( Param1 p1 ), + Y * y, + ...) +{ + return FastDelegate< RetType ( Param1 p1 ) >(y, func); +} + +template +FastDelegate< RetType ( Param1 p1 ) > +bind( + RetType (X::*func)( Param1 p1 ) const, + Y * y, + ...) +{ + return FastDelegate< RetType ( Param1 p1 ) >(y, func); +} + +//N=2 +template +FastDelegate< RetType ( Param1 p1, Param2 p2 ) > +bind( + RetType (X::*func)( Param1 p1, Param2 p2 ), + Y * y, + ...) +{ + return FastDelegate< RetType ( Param1 p1, Param2 p2 ) >(y, func); +} + +template +FastDelegate< RetType ( Param1 p1, Param2 p2 ) > +bind( + RetType (X::*func)( Param1 p1, Param2 p2 ) const, + Y * y, + ...) +{ + return FastDelegate< RetType ( Param1 p1, Param2 p2 ) >(y, func); +} + +//N=3 +template +FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3 ) > +bind( + RetType (X::*func)( Param1 p1, Param2 p2, Param3 p3 ), + Y * y, + ...) +{ + return FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3 ) >(y, func); +} + +template +FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3 ) > +bind( + RetType (X::*func)( Param1 p1, Param2 p2, Param3 p3 ) const, + Y * y, + ...) +{ + return FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3 ) >(y, func); +} + +//N=4 +template +FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4 ) > +bind( + RetType (X::*func)( Param1 p1, Param2 p2, Param3 p3, Param4 p4 ), + Y * y, + ...) +{ + return FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4 ) >(y, func); +} + +template +FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4 ) > +bind( + RetType (X::*func)( Param1 p1, Param2 p2, Param3 p3, Param4 p4 ) const, + Y * y, + ...) +{ + return FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4 ) >(y, func); +} + +//N=5 +template +FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5 ) > +bind( + RetType (X::*func)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5 ), + Y * y, + ...) +{ + return FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5 ) >(y, func); +} + +template +FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5 ) > +bind( + RetType (X::*func)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5 ) const, + Y * y, + ...) +{ + return FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5 ) >(y, func); +} + +//N=6 +template +FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6 ) > +bind( + RetType (X::*func)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6 ), + Y * y, + ...) +{ + return FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6 ) >(y, func); +} + +template +FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6 ) > +bind( + RetType (X::*func)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6 ) const, + Y * y, + ...) +{ + return FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6 ) >(y, func); +} + +//N=7 +template +FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7 ) > +bind( + RetType (X::*func)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7 ), + Y * y, + ...) +{ + return FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7 ) >(y, func); +} + +template +FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7 ) > +bind( + RetType (X::*func)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7 ) const, + Y * y, + ...) +{ + return FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7 ) >(y, func); +} + +//N=8 +template +FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8 ) > +bind( + RetType (X::*func)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8 ), + Y * y, + ...) +{ + return FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8 ) >(y, func); +} + +template +FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8 ) > +bind( + RetType (X::*func)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8 ) const, + Y * y, + ...) +{ + return FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8 ) >(y, func); +} + + +#endif //FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX + +} // namespace fastdelegate + +#endif // !defined(FASTDELEGATEBIND_H) + diff --git a/modules/core/include/dpl/abstract_input.h b/modules/core/include/dpl/abstract_input.h new file mode 100644 index 0000000..89ed8fc --- /dev/null +++ b/modules/core/include/dpl/abstract_input.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_input.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file of abstract input + */ +#ifndef DPL_ABSTRACT_INPUT_H +#define DPL_ABSTRACT_INPUT_H + +#include +#include + +namespace DPL +{ +class BinaryQueue; +typedef std::auto_ptr BinaryQueueAutoPtr; + +class AbstractInput +{ +public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, ReadFailed) + }; + +public: + virtual ~AbstractInput() {} + + /** + * Read binary data from input + * If no data is available method returns NULL buffer. + * In case connection was successfuly close, method returns empty buffer + * + * @param[in] size Maximum number of bytes to read from input + * @return Buffer containing read bytes + * @throw ReadFailed + */ + virtual BinaryQueueAutoPtr Read(size_t size) = 0; +}; +} // namespace DPL + +#endif // DPL_ABSTRACT_INPUT_H diff --git a/modules/core/include/dpl/abstract_input_output.h b/modules/core/include/dpl/abstract_input_output.h new file mode 100644 index 0000000..f775afc --- /dev/null +++ b/modules/core/include/dpl/abstract_input_output.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_output.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file of abstract output + */ +#ifndef DPL_ABSTRACT_INPUT_OUTPUT_H +#define DPL_ABSTRACT_INPUT_OUTPUT_H + +#include +#include + +namespace DPL +{ +class AbstractInputOutput + : public AbstractInput, + public AbstractOutput +{ +public: + virtual ~AbstractInputOutput() {} +}; + +} // namespace DPL + +#endif // DPL_ABSTRACT_INPUT_OUTPUT_H diff --git a/modules/core/include/dpl/abstract_output.h b/modules/core/include/dpl/abstract_output.h new file mode 100644 index 0000000..160907c --- /dev/null +++ b/modules/core/include/dpl/abstract_output.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_output.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file of abstract output + */ +#ifndef DPL_ABSTRACT_OUTPUT_H +#define DPL_ABSTRACT_OUTPUT_H + +#include +#include + +namespace DPL +{ +class BinaryQueue; +typedef std::auto_ptr BinaryQueueAutoPtr; + +class AbstractOutput +{ +public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, WriteFailed) + }; + +public: + virtual ~AbstractOutput() {} + + /** + * Write binary data to output + * If output is blocked, Write returns zero, if instance is a type of + * WaitableAbstractOutput one can wait for writability then + * + * @param[in] buffer Input buffer with data to be written + * @param[in] bufferSize Maximum number of bytes to write from buffer + * @return Number of bytes success successfuly written or zero if output is blocked + * @throw WriteFailed + */ + virtual size_t Write(const BinaryQueue &buffer, size_t bufferSize) = 0; +}; +} // namespace DPL + +#endif // DPL_ABSTRACT_OUTPUT_H diff --git a/modules/core/include/dpl/abstract_waitable_input.h b/modules/core/include/dpl/abstract_waitable_input.h new file mode 100644 index 0000000..6b39ea7 --- /dev/null +++ b/modules/core/include/dpl/abstract_waitable_input.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_waitable_input.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file of abstract waitable input + */ +#ifndef DPL_ABSTRACT_WAITABLE_INPUT_H +#define DPL_ABSTRACT_WAITABLE_INPUT_H + +#include +#include + +namespace DPL +{ + +class AbstractWaitableInput + : public AbstractInput +{ +public: + virtual ~AbstractWaitableInput() {} + + virtual WaitableHandle WaitableReadHandle() const = 0; +}; + +} // namespace DPL + +#endif // DPL_ABSTRACT_WAITABLE_INPUT_H diff --git a/modules/core/include/dpl/abstract_waitable_input_adapter.h b/modules/core/include/dpl/abstract_waitable_input_adapter.h new file mode 100644 index 0000000..a9d396a --- /dev/null +++ b/modules/core/include/dpl/abstract_waitable_input_adapter.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_waitable_input.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file of abstract waitable input + */ +#ifndef DPL_ABSTRACT_WAITABLE_INPUT_ADAPTER_H +#define DPL_ABSTRACT_WAITABLE_INPUT_ADAPTER_H + +#include +#include +#include + +namespace DPL +{ + +class AbstractWaitableInputAdapter + : public AbstractWaitableInput +{ +private: + AbstractInput *m_input; + WaitableEvent m_waitableEvent; + +public: + explicit AbstractWaitableInputAdapter(AbstractInput *input); + + virtual BinaryQueueAutoPtr Read(size_t size); + + virtual WaitableHandle WaitableReadHandle() const; +}; + +} // namespace DPL + +#endif // DPL_ABSTRACT_WAITABLE_INPUT_ADAPTER_H diff --git a/modules/core/include/dpl/abstract_waitable_input_output.h b/modules/core/include/dpl/abstract_waitable_input_output.h new file mode 100644 index 0000000..3d3e6f2 --- /dev/null +++ b/modules/core/include/dpl/abstract_waitable_input_output.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_waitable_input_output.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file of abstract waitable input output + */ +#ifndef DPL_ABSTRACT_WAITABLE_INPUT_OUTPUT_H +#define DPL_ABSTRACT_WAITABLE_INPUT_OUTPUT_H + +#include +#include + +namespace DPL +{ + +class AbstractWaitableInputOutput + : public AbstractWaitableInput, + public AbstractWaitableOutput +{ +public: + virtual ~AbstractWaitableInputOutput() {} +}; + +} // namespace DPL + +#endif // DPL_ABSTRACT_WAITABLE_INPUT_OUTPUT_H diff --git a/modules/core/include/dpl/abstract_waitable_input_output_adapter.h b/modules/core/include/dpl/abstract_waitable_input_output_adapter.h new file mode 100644 index 0000000..6ac2228 --- /dev/null +++ b/modules/core/include/dpl/abstract_waitable_input_output_adapter.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_waitable_input_output.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file of abstract waitable input output + */ +#ifndef DPL_ABSTRACT_WAITABLE_INPUT_OUTPUT_ADAPTER_H +#define DPL_ABSTRACT_WAITABLE_INPUT_OUTPUT_ADAPTER_H + +#include +#include +#include + +namespace DPL +{ + +class AbstractWaitableInputOutputAdapter + : public AbstractWaitableInputAdapter, + public AbstractWaitableOutputAdapter +{ +public: + explicit AbstractWaitableInputOutputAdapter(AbstractInputOutput *inputOutput); +}; + +} // namespace DPL + +#endif // DPL_ABSTRACT_WAITABLE_INPUT_OUTPUT_ADAPTER_H diff --git a/modules/core/include/dpl/abstract_waitable_output.h b/modules/core/include/dpl/abstract_waitable_output.h new file mode 100644 index 0000000..6cc8d23 --- /dev/null +++ b/modules/core/include/dpl/abstract_waitable_output.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_waitable_output.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file of abstract waitable output + */ +#ifndef DPL_ABSTRACT_WAITABLE_OUTPUT_H +#define DPL_ABSTRACT_WAITABLE_OUTPUT_H + +#include +#include + +namespace DPL +{ + +class AbstractWaitableOutput + : public AbstractOutput +{ +public: + virtual ~AbstractWaitableOutput() {} + + virtual WaitableHandle WaitableWriteHandle() const = 0; +}; + +} // namespace DPL + +#endif // DPL_ABSTRACT_WAITABLE_OUTPUT_H diff --git a/modules/core/include/dpl/abstract_waitable_output_adapter.h b/modules/core/include/dpl/abstract_waitable_output_adapter.h new file mode 100644 index 0000000..64fc3b3 --- /dev/null +++ b/modules/core/include/dpl/abstract_waitable_output_adapter.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_waitable_output.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file of abstract waitable output + */ +#ifndef DPL_ABSTRACT_WAITABLE_OUTPUT_ADAPTER_H +#define DPL_ABSTRACT_WAITABLE_OUTPUT_ADAPTER_H + +#include +#include +#include + +namespace DPL +{ + +class AbstractWaitableOutputAdapter + : public AbstractWaitableOutput +{ +private: + AbstractOutput *m_output; + WaitableEvent m_waitableEvent; + +public: + explicit AbstractWaitableOutputAdapter(AbstractOutput *output); + + virtual size_t Write(const BinaryQueue &buffer, size_t bufferSize); + + virtual WaitableHandle WaitableWriteHandle() const; +}; + +} // namespace DPL + +#endif // DPL_ABSTRACT_WAITABLE_OUTPUT_ADAPTER_H diff --git a/modules/core/include/dpl/address.h b/modules/core/include/dpl/address.h new file mode 100644 index 0000000..7b1d8e8 --- /dev/null +++ b/modules/core/include/dpl/address.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file address.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file of address + */ +#ifndef DPL_ADDRESS_H +#define DPL_ADDRESS_H + +#include +#include + +namespace DPL +{ +class Address +{ +public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, InvalidAddress) + }; + +private: + std::string m_address; + unsigned short m_port; + +public: + Address(); + Address(const std::string &address); + Address(const std::string &address, unsigned short port); + + virtual ~Address(); + + std::string GetAddress() const; + unsigned short GetPort() const; + + std::string ToString() const; + + bool operator<(const Address &addr) const; +}; + +} // namespace DPL + +#endif // DPL_ADDRESS_H diff --git a/modules/core/include/dpl/aligned.h b/modules/core/include/dpl/aligned.h new file mode 100644 index 0000000..902deb6 --- /dev/null +++ b/modules/core/include/dpl/aligned.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file aligned.h + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of aligned attribute from gcc + */ +#ifndef DPL_ALIGNED_H +#define DPL_ALIGNED_H + +#define DPL_ALIGNED(n) __attribute__((aligned(n))) + +#endif // DPL_ALIGNED_H diff --git a/modules/core/include/dpl/application.h b/modules/core/include/dpl/application.h new file mode 100644 index 0000000..f2c309e --- /dev/null +++ b/modules/core/include/dpl/application.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file application.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of MVC application support + */ +#ifndef DPL_APPLICATION_H +#define DPL_APPLICATION_H + +#include +#include +#include +#include +#include + +namespace DPL +{ +class Application +{ +public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, TooManyInstances) + DECLARE_EXCEPTION_TYPE(Base, FrameworkError) + }; + +private: + static int app_create(void *data); + static int app_terminate(void *data); + static int app_pause(void *data); + static int app_resume(void *data); + static int app_reset(bundle *b, void *data); + +protected: + int m_argc; + char **m_argv; + std::string m_applicationName; + + bool m_mainWindowVisible; + + virtual void OnCreate(); + virtual void OnStart(); + virtual void OnStop(); + virtual void OnResume(); + virtual void OnPause(); + virtual void OnRelaunch(); + virtual void OnReset(bundle *b); + virtual void OnTerminate(); + virtual void OnLowMemory(); + virtual void OnLowBattery(); + virtual void OnLanguageChanged(); + +public: + Application(int argc, char **argv, const std::string &applicationName, bool showMainWindow = true); + virtual ~Application(); + + /** + * @brief Execute application and start message processing + */ + virtual int Exec(); + + /* + * @brief Sends quit message to application message loop + */ + virtual void Quit(); +}; + +class ApplicationExt : public Application +{ +public: + ApplicationExt(int argc, char **argv, const std::string &applicationName, bool showMainWindow = true); + virtual ~ApplicationExt(); + + /** + * @brief Execute application and start message processing + */ + virtual int Exec(); + + /* + * @brief Sends quit message to application message loop + */ + virtual void Quit(); +private: + static DPL::Atomic m_useCount; +}; + +} // namespace DPL + +#endif // DPL_APPLICATION_H diff --git a/modules/core/include/dpl/apply.h b/modules/core/include/dpl/apply.h new file mode 100644 index 0000000..f441072 --- /dev/null +++ b/modules/core/include/dpl/apply.h @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file apply.h + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief Implementation file for Apply functionality. + */ +#ifndef DPL_APPLY_H_ +#define DPL_APPLY_H_ + +#ifndef __GXX_EXPERIMENTAL_CXX0X__ // C++11 compatibility check +# include +#else + +#include +#include + +namespace DPL +{ +enum class ExtraArgsInsertPolicy +{ + /** + * Extra arguments will be add at the end of the argument list + * passed to operation call. + */ + Append, + + /** + * Extra arguments will be add at the begining of the argument list + * passed to operation call. + */ + Prepend +}; + +template +struct _ApplyDispatchByPolicy; + +template +Result Apply(Operation op, + const std::tuple& t, + ArgsE && ... extra) +{ + return _ApplyDispatchByPolicy:: + template Apply(op, t, std::forward(extra) ...); +} + +template +struct _ApplyTuple +{ + template + static Result Apply(Operation op, + const std::tuple& t1, + const std::tuple& t2, + Args && ... args) + { + return _ApplyTuple:: + template Apply(op, + t1, + t2, + std::get(t1), + std::forward(args) ...); + } +}; + +template +struct _ApplyTuple<0, M> +{ + template + static Result Apply(Operation op, + const std::tuple& t1, + const std::tuple& t2, + Args && ... args) + { + return _ApplyTuple<0, M - 1>:: + template Apply(op, + t1, + t2, + std::get(t2), + std::forward(args) ...); + } +}; + +template<> +struct _ApplyTuple<0, 0> +{ + template + static Result Apply(Operation op, + const std::tuple&, + const std::tuple&, + Args && ... args) + { + return op(std::forward(args) ...); + } +}; + +template +struct _ApplyArgs +{ + template + static Result Apply(Operation op, + const std::tuple& t, + Args && ... args) + { + return _ApplyArgs:: + template Apply(op, + t, + std::get(t), + std::forward(args) ...); + } +}; + +template<> +struct _ApplyArgs<0> +{ + template + static Result Apply(Operation op, + const std::tuple&, + Args && ... args) + { + return op(std::forward(args) ...); + } +}; + +template<> +struct _ApplyDispatchByPolicy +{ + template + static Result Apply(Operation op, + const std::tuple& t, + ArgsE && ... extra) + { + return _ApplyArgs:: + template Apply(op, + t, + std::forward(extra) ...); + } +}; + +template<> +struct _ApplyDispatchByPolicy +{ + template + static Result Apply(Operation op, + const std::tuple& t, + ArgsE && ... extra) + { + return _ApplyTuple:: + template Apply(op, + t, + std::make_tuple(std::forward(extra) ...)); + } +}; +} // namespace DPL + +#endif // __GXX_EXPERIMENTAL_CXX0X__ + +#endif // DPL_APPLY_H_ diff --git a/modules/core/include/dpl/assert.h b/modules/core/include/dpl/assert.h new file mode 100644 index 0000000..f0b62f7 --- /dev/null +++ b/modules/core/include/dpl/assert.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 + +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 diff --git a/modules/core/include/dpl/atomic.h b/modules/core/include/dpl/atomic.h new file mode 100644 index 0000000..33ea8a9 --- /dev/null +++ b/modules/core/include/dpl/atomic.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file atomic.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file of atomic + */ +#ifndef DPL_ATOMIC_H +#define DPL_ATOMIC_H + +#pragma GCC system_header +#include + +namespace DPL +{ +class Atomic +{ +public: + typedef gint ValueType; + +private: + volatile ValueType m_value; + +public: + Atomic(ValueType value = static_cast(0)); + + ValueType ExchangeAndAdd(ValueType value); + bool CompareAndExchange(ValueType oldValue, ValueType newValue); + bool operator--(); + void operator++(); + + operator ValueType() const; +}; +} // namespace DPL + +#endif // DPL_ATOMIC_H diff --git a/modules/core/include/dpl/binary_queue.h b/modules/core/include/dpl/binary_queue.h new file mode 100644 index 0000000..ae85ceb --- /dev/null +++ b/modules/core/include/dpl/binary_queue.h @@ -0,0 +1,284 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file binary_queue.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file of binary queue + */ +#ifndef DPL_BINARY_QUEUE_H +#define DPL_BINARY_QUEUE_H + +#include +#include +#include +#include +#include + +namespace DPL +{ +/** + * Binary stream implemented as constant size bucket list + * + * @todo Add optimized implementation for FlattenConsume + */ +class BinaryQueue + : public AbstractInputOutput +{ +public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, OutOfData) + }; + + typedef void (*BufferDeleter)(const void *buffer, size_t bufferSize, void *userParam); + static void BufferDeleterFree(const void *buffer, size_t bufferSize, void *userParam); + + class BucketVisitor + { + public: + /** + * Destructor + */ + virtual ~BucketVisitor(); + + /** + * Visit bucket + * + * @return none + * @param[in] buffer Constant pointer to bucket data buffer + * @param[in] bufferSize Number of bytes in bucket + */ + virtual void OnVisitBucket(const void *buffer, size_t bufferSize) = 0; + }; + +private: + struct Bucket + : private Noncopyable + { + const void *buffer; + const void *ptr; + size_t size; + size_t left; + + BufferDeleter deleter; + void *param; + + Bucket(const void *buffer, size_t bufferSize, BufferDeleter deleter, void *userParam); + virtual ~Bucket(); + }; + + typedef std::list BucketList; + BucketList m_buckets; + size_t m_size; + + static void DeleteBucket(Bucket *bucket); + + class BucketVisitorCall + { + private: + BucketVisitor *m_visitor; + + public: + BucketVisitorCall(BucketVisitor *visitor); + virtual ~BucketVisitorCall(); + + void operator()(Bucket *bucket) const; + }; + +public: + /** + * Construct empty binary queue + */ + BinaryQueue(); + + /** + * Construct binary queue via bare copy of other binary queue + * + * @param[in] other Other binary queue to copy from + * @warning One cannot assume that bucket structure is preserved during copy + */ + BinaryQueue(const BinaryQueue &other); + + /** + * Destructor + */ + virtual ~BinaryQueue(); + + /** + * Construct binary queue via bare copy of other binary queue + * + * @param[in] other Other binary queue to copy from + * @warning One cannot assume that bucket structure is preserved during copy + */ + const BinaryQueue &operator=(const BinaryQueue &other); + + /** + * Append copy of @a bufferSize bytes from memory pointed by @a buffer + * to the end of binary queue. Uses default deleter based on free. + * + * @return none + * @param[in] buffer Pointer to buffer to copy data from + * @param[in] bufferSize Number of bytes to copy + * @exception std::bad_alloc Cannot allocate memory to hold additional data + * @see BinaryQueue::BufferDeleterFree + */ + void AppendCopy(const void *buffer, size_t bufferSize); + + /** + * Append @a bufferSize bytes from memory pointed by @a buffer + * to the end of binary queue. Uses custom provided deleter. + * Responsibility for deleting provided buffer is transfered to BinaryQueue. + * + * @return none + * @param[in] buffer Pointer to data buffer + * @param[in] bufferSize Number of bytes available in buffer + * @param[in] deleter Pointer to deleter procedure used to free provided buffer + * @param[in] userParam User parameter passed to deleter routine + * @exception std::bad_alloc Cannot allocate memory to hold additional data + */ + void AppendUnmanaged(const void *buffer, size_t bufferSize, BufferDeleter deleter = &BinaryQueue::BufferDeleterFree, void *userParam = NULL); + + /** + * Append copy of other binary queue to the end of this binary queue + * + * @return none + * @param[in] other Constant reference to other binary queue to copy data from + * @exception std::bad_alloc Cannot allocate memory to hold additional data + * @warning One cannot assume that bucket structure is preserved during copy + */ + void AppendCopyFrom(const BinaryQueue &other); + + /** + * Move bytes from other binary queue to the end of this binary queue. + * This also removes all bytes from other binary queue. + * This method is designed to be as fast as possible (only pointer swaps) + * and is suggested over making copies of binary queues. + * Bucket structure is preserved after operation. + * + * @return none + * @param[in] other Reference to other binary queue to move data from + * @exception std::bad_alloc Cannot allocate memory to hold additional data + */ + void AppendMoveFrom(BinaryQueue &other); + + /** + * Append copy of binary queue to the end of other binary queue + * + * @return none + * @param[in] other Constant reference to other binary queue to copy data to + * @exception std::bad_alloc Cannot allocate memory to hold additional data + * @warning One cannot assume that bucket structure is preserved during copy + */ + void AppendCopyTo(BinaryQueue &other) const; + + /** + * Move bytes from binary queue to the end of other binary queue. + * This also removes all bytes from binary queue. + * This method is designed to be as fast as possible (only pointer swaps) + * and is suggested over making copies of binary queues. + * Bucket structure is preserved after operation. + * + * @return none + * @param[in] other Reference to other binary queue to move data to + * @exception std::bad_alloc Cannot allocate memory to hold additional data + */ + void AppendMoveTo(BinaryQueue &other); + + /** + * Retrieve total size of all data contained in binary queue + * + * @return Number of bytes in binary queue + */ + size_t Size() const; + + /** + * Remove all data from binary queue + * + * @return none + */ + void Clear(); + + /** + * Check if binary queue is empty + * + * @return true if binary queue is empty, false otherwise + */ + bool Empty() const; + + /** + * Remove @a size bytes from beginning of binary queue + * + * @return none + * @param[in] size Number of bytes to remove + * @exception BinaryQueue::Exception::OutOfData Number of bytes is larger + * than available bytes in binary queue + */ + void Consume(size_t size); + + /** + * Retrieve @a bufferSize bytes from beginning of binary queue and copy them + * to user supplied buffer + * + * @return none + * @param[in] buffer Pointer to user buffer to receive bytes + * @param[in] bufferSize Size of user buffer pointed by @a buffer + * @exception BinaryQueue::Exception::OutOfData Number of bytes to flatten + * is larger than available bytes in binary queue + */ + void Flatten(void *buffer, size_t bufferSize) const; + + /** + * Retrieve @a bufferSize bytes from beginning of binary queue, copy them + * to user supplied buffer, and remove from binary queue + * + * @return none + * @param[in] buffer Pointer to user buffer to receive bytes + * @param[in] bufferSize Size of user buffer pointed by @a buffer + * @exception BinaryQueue::Exception::OutOfData Number of bytes to flatten + * is larger than available bytes in binary queue + */ + void FlattenConsume(void *buffer, size_t bufferSize); + + /** + * Visit each buffer with data using visitor object + * + * @return none + * @param[in] visitor Pointer to bucket visitor + * @see BinaryQueue::BucketVisitor + */ + void VisitBuckets(BucketVisitor *visitor) const; + + /** + * IAbstractInput interface + */ + virtual BinaryQueueAutoPtr Read(size_t size); + + /** + * IAbstractOutput interface + */ + virtual size_t Write(const BinaryQueue &buffer, size_t bufferSize); +}; + +/** + * Binary queue auto pointer + */ +typedef std::auto_ptr BinaryQueueAutoPtr; +} // namespace DPL + +#endif // DPL_BINARY_QUEUE_H diff --git a/modules/core/include/dpl/bool_operator.h b/modules/core/include/dpl/bool_operator.h new file mode 100644 index 0000000..ccb17f8 --- /dev/null +++ b/modules/core/include/dpl/bool_operator.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 diff --git a/modules/core/include/dpl/char_traits.h b/modules/core/include/dpl/char_traits.h new file mode 100644 index 0000000..1b50c51 --- /dev/null +++ b/modules/core/include/dpl/char_traits.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file char_traits.h + * @author Piotr Marcinkiewicz (p.marcinkiew@samsung.com) + * @version 1.0 + * @brief Char traits are used to create basic_string extended with additional features + * Current char traits could be extended in feature to boost performance + */ +#ifndef DPL_CHAR_TRAITS +#define DPL_CHAR_TRAITS + +#include +#include +#include +#include +#include + +namespace DPL +{ + +typedef std::char_traits CharTraits; + +} // namespace DPL + +#endif // DPL_CHAR_TRAITS diff --git a/modules/core/include/dpl/colors.h b/modules/core/include/dpl/colors.h new file mode 100644 index 0000000..efc104d --- /dev/null +++ b/modules/core/include/dpl/colors.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file colors.h + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + * @brief Some constants with definition of colors for Console + * and html output + */ + +#ifndef DPL_COLORS_H +#define DPL_COLORS_H + +namespace DPL +{ + +namespace Colors +{ + +namespace Text +{ + +extern const char* BOLD_GREEN_BEGIN; +extern const char* BOLD_GREEN_END; +extern const char* PURPLE_BEGIN; +extern const char* PURPLE_END; +extern const char* RED_BEGIN; +extern const char* RED_END; +extern const char* GREEN_BEGIN; +extern const char* GREEN_END; +extern const char* CYAN_BEGIN; +extern const char* CYAN_END; +extern const char* BOLD_RED_BEGIN; +extern const char* BOLD_RED_END; +extern const char* BOLD_YELLOW_BEGIN; +extern const char* BOLD_YELLOW_END; +extern const char* BOLD_GOLD_BEGIN; +extern const char* BOLD_GOLD_END; +extern const char* BOLD_WHITE_BEGIN; +extern const char* BOLD_WHITE_END; + +} //namespace Text + +namespace Html +{ + +extern const char* BOLD_GREEN_BEGIN; +extern const char* BOLD_GREEN_END; +extern const char* PURPLE_BEGIN; +extern const char* PURPLE_END; +extern const char* RED_BEGIN; +extern const char* RED_END; +extern const char* GREEN_BEGIN; +extern const char* GREEN_END; +extern const char* CYAN_BEGIN; +extern const char* CYAN_END; +extern const char* BOLD_RED_BEGIN; +extern const char* BOLD_RED_END; +extern const char* BOLD_YELLOW_BEGIN; +extern const char* BOLD_YELLOW_END; +extern const char* BOLD_GOLD_BEGIN; +extern const char* BOLD_GOLD_END; +extern const char* BOLD_WHITE_BEGIN; +extern const char* BOLD_WHITE_END; + +} //namespace Html + +} //namespace Colors + +} //namespace DPL + +#endif /* DPL_COLORS_H */ diff --git a/modules/core/include/dpl/copy.h b/modules/core/include/dpl/copy.h new file mode 100644 index 0000000..d91fbbc --- /dev/null +++ b/modules/core/include/dpl/copy.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file copy.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of copy + */ +#ifndef DPL_COPY_H +#define DPL_COPY_H + +#include +#include +#include + +namespace DPL +{ +/** + * Copy failed exception + */ +DECLARE_EXCEPTION_TYPE(Exception, CopyFailed) + +/** + * Copy all bytes abstract waitable input to abstract waitable output + * + * @param[in] input Abstract waitable input to copy from + * @param[in] output Abstract waitable output to copy to + * @throw CopyFailed An error occurred while copying. Look into exception trace for details. + */ +void Copy(AbstractWaitableInput *input, AbstractWaitableOutput *output); + +/** + * Copy exactly totalBytes bytes abstract waitable input to abstract waitable output + * + * @param[in] input Abstract waitable input to copy from + * @param[in] output Abstract waitable output to copy to + * @throw CopyFailed An error occurred while copying. Look into exception trace for details. + */ +void Copy(AbstractWaitableInput *input, AbstractWaitableOutput *output, size_t totalBytes); +} // namespace DPL + +#endif // DPL_COPY_H diff --git a/modules/core/include/dpl/enable_shared_from_this.h b/modules/core/include/dpl/enable_shared_from_this.h new file mode 100644 index 0000000..ed84130 --- /dev/null +++ b/modules/core/include/dpl/enable_shared_from_this.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file enable_shared_from_this.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of shared pointer RAII + */ +#ifndef DPL_ENABLE_SHARED_FROM_THIS_H +#define DPL_ENABLE_SHARED_FROM_THIS_H + +#include +#include +#include + +namespace DPL +{ +template +class EnableSharedFromThis : private Noncopyable +{ + +private: + // A weak pointer to shared counter + SharedCounter *m_counter; + Class *m_ptr; + +public: + DPL::SharedPtr SharedFromThis() + { + Assert(m_counter != NULL && "Pointer is not shared!"); + return SharedPtr(m_counter, m_ptr); + } + + DPL::SharedPtr SharedFromThis() const + { + Assert(m_counter != NULL && "Pointer is not shared!"); + return SharedPtr(m_counter, m_ptr); + } + + // For internal SharedPtr usage only. Do not call directly. + void _Internal_AcceptSharedPtr(SharedCounter *counter, Class *ptr) + { + m_counter = counter; + m_ptr = ptr; + } + + EnableSharedFromThis() + : m_counter(NULL), + m_ptr(NULL) + { + } + + virtual ~EnableSharedFromThis() + { + } +}; +} // namespace DPL + +#endif // DPL_ENABLE_SHARED_FROM_THIS_H diff --git a/modules/core/include/dpl/errno_string.h b/modules/core/include/dpl/errno_string.h new file mode 100644 index 0000000..d3da348 --- /dev/null +++ b/modules/core/include/dpl/errno_string.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file errno_string.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of errno string + */ +#ifndef DPL_ERRNO_STRING_H +#define DPL_ERRNO_STRING_H + +#include +#include +#include + +namespace DPL +{ +DECLARE_EXCEPTION_TYPE(DPL::Exception, InvalidErrnoValue) + +std::string GetErrnoString(int error = errno); +} // namespace DPL + +#endif // DPL_ERRNO_STRING_H diff --git a/modules/core/include/dpl/exception.h b/modules/core/include/dpl/exception.h new file mode 100644 index 0000000..a2e3dcf --- /dev/null +++ b/modules/core/include/dpl/exception.h @@ -0,0 +1,357 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file exception.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief Header file for base exception + */ +#ifndef DPL_EXCEPTION_H +#define DPL_EXCEPTION_H + +#include +#include +#include +#include +#include +#include + +namespace DPL +{ +void LogUnhandledException(const std::string &str); +void LogUnhandledException(const std::string &str, const char *filename, int line, const char *function); +} + +namespace DPL +{ +class Exception +{ +private: + static unsigned int m_exceptionCount; + static Exception* m_lastException; + static void (*m_terminateHandler)(); + + static void AddRef(Exception* exception) + { + if (!m_exceptionCount) + m_terminateHandler = std::set_terminate(&TerminateHandler); + + ++m_exceptionCount; + m_lastException = exception; + } + + static void UnRef(Exception* e) + { + if (m_lastException == e) + m_lastException = NULL; + + --m_exceptionCount; + + if (!m_exceptionCount) + { + std::set_terminate(m_terminateHandler); + m_terminateHandler = NULL; + } + } + + static void TerminateHandler() + { + if (m_lastException != NULL) + { + DisplayKnownException(*m_lastException); + abort(); + } + else + { + DisplayUnknownException(); + abort(); + } + } + + Exception *m_reason; + std::string m_path; + std::string m_function; + int m_line; + +protected: + std::string m_message; + std::string m_className; + +public: + static std::string KnownExceptionToString(const Exception &e) + { + std::ostringstream message; + message << "\033[1;5;31m\n=== Unhandled DPL exception occurred ===\033[m\n\n"; + message << "\033[1;33mException trace:\033[m\n\n"; + message << e.DumpToString(); + message << "\033[1;31m\n=== Will now abort ===\033[m\n"; + + return message.str(); + } + + static std::string UnknownExceptionToString() + { + std::ostringstream message; + message << "\033[1;5;31m\n=== Unhandled non-DPL exception occurred ===\033[m\n\n"; + message << "\033[1;31m\n=== Will now abort ===\033[m\n"; + + return message.str(); + } + + static void DisplayKnownException(const Exception& e) + { + LogUnhandledException(KnownExceptionToString(e).c_str()); + } + + static void DisplayUnknownException() + { + LogUnhandledException(UnknownExceptionToString().c_str()); + } + + Exception(const Exception &other) + { + // Deep copy + if (other.m_reason != NULL) + m_reason = new Exception(*other.m_reason); + else + m_reason = NULL; + + m_message = other.m_message; + m_path = other.m_path; + m_function = other.m_function; + m_line = other.m_line; + + m_className = other.m_className; + + AddRef(this); + } + + const Exception &operator =(const Exception &other) + { + if (this == &other) + return *this; + + // Deep copy + if (other.m_reason != NULL) + m_reason = new Exception(*other.m_reason); + else + m_reason = NULL; + + m_message = other.m_message; + m_path = other.m_path; + m_function = other.m_function; + m_line = other.m_line; + + m_className = other.m_className; + + AddRef(this); + + return *this; + } + + Exception(const char *path, const char *function, int line, const std::string &message) + : m_reason(NULL), + m_path(path), + m_function(function), + m_line(line), + m_message(message) + { + AddRef(this); + } + + Exception(const char *path, const char *function, int line, const Exception &reason, const std::string &message) + : m_reason(new Exception(reason)), + m_path(path), + m_function(function), + m_line(line), + m_message(message) + { + AddRef(this); + } + + virtual ~Exception() throw() + { + if (m_reason != NULL) + { + delete m_reason; + m_reason = NULL; + } + + UnRef(this); + } + + void Dump() const + { + // Show reason first + if (m_reason != NULL) + m_reason->Dump(); + + // Afterward, dump exception + const char *file = strchr(m_path.c_str(), '/'); + + if (file == NULL) + file = m_path.c_str(); + else + ++file; + + printf("\033[0;36m[%s:%i]\033[m %s() \033[4;35m%s\033[m: %s\033[m\n", + file, m_line, + m_function.c_str(), + m_className.c_str(), + m_message.empty() ? "" : m_message.c_str()); + } + + std::string DumpToString() const + { + std::string ret; + if (m_reason != NULL) + ret = m_reason->DumpToString(); + + const char *file = strchr(m_path.c_str(), '/'); + + if (file == NULL) + file = m_path.c_str(); + else + ++file; + + char buf[1024]; + snprintf(buf, sizeof(buf), "\033[0;36m[%s:%i]\033[m %s() \033[4;35m%s\033[m: %s\033[m\n", + file, m_line, + m_function.c_str(), + m_className.c_str(), + m_message.empty() ? "" : m_message.c_str()); + + buf[sizeof(buf)-1] = '\n'; + ret += buf; + + return ret; + } + + Exception *GetReason() const + { + return m_reason; + } + + std::string GetPath() const + { + return m_path; + } + + std::string GetFunction() const + { + return m_function; + } + + int GetLine() const + { + return m_line; + } + + std::string GetMessage() const + { + return m_message; + } + + std::string GetClassName() const + { + return m_className; + } +}; +} // namespace DPL + +#define Try try + +#define Throw(ClassName) \ + throw ClassName(__FILE__, __FUNCTION__, __LINE__) + +#define ThrowMsg(ClassName, Message) \ + do \ + { \ + std::ostringstream dplLoggingStream; \ + dplLoggingStream << Message; \ + throw ClassName(__FILE__, __FUNCTION__, __LINE__, dplLoggingStream.str()); \ + }while(0) + +#define ReThrow(ClassName) \ + throw ClassName(__FILE__, __FUNCTION__, __LINE__, _rethrown_exception) + +#define ReThrowMsg(ClassName, Message) \ + throw ClassName(__FILE__, __FUNCTION__, __LINE__, _rethrown_exception, Message) + +#define Catch(ClassName) \ + catch (const ClassName &_rethrown_exception) + +#define DECLARE_EXCEPTION_TYPE(BaseClass, Class) \ + class Class \ + : public BaseClass \ + { \ + public: \ + Class(const char *path, const char *function, int line, const std::string &message = std::string()) \ + : BaseClass(path, function, line, message) \ + { \ + BaseClass::m_className = #Class; \ + } \ + \ + Class(const char *path, const char *function, int line, const DPL::Exception &reason, const std::string &message = std::string()) \ + : BaseClass(path, function, line, reason, message) \ + { \ + BaseClass::m_className = #Class; \ + } \ + }; + +#define UNHANDLED_EXCEPTION_HANDLER_BEGIN try + +#define UNHANDLED_EXCEPTION_HANDLER_END \ + catch (const DPL::Exception &exception) \ + { \ + std::ostringstream msg; \ + msg << DPL::Exception::KnownExceptionToString(exception); \ + DPL::LogUnhandledException(msg.str(), __FILE__, __LINE__, __FUNCTION__); \ + abort(); \ + } \ + catch (std::exception& e) \ + { \ + std::ostringstream msg; \ + msg << e.what(); \ + msg << "\n"; \ + msg << DPL::Exception::UnknownExceptionToString(); \ + DPL::LogUnhandledException(msg.str(), __FILE__, __LINE__, __FUNCTION__); \ + abort(); \ + } \ + catch (...) \ + { \ + std::ostringstream msg; \ + msg << DPL::Exception::UnknownExceptionToString(); \ + DPL::LogUnhandledException(msg.str(), __FILE__, __LINE__, __FUNCTION__); \ + abort(); \ + } + +namespace DPL +{ +namespace CommonException +{ +/** + * Internal exception definitions + * + * These should normally not happen. + * Usually, exception trace with internal error includes + * important messages. + */ +DECLARE_EXCEPTION_TYPE(Exception, InternalError) ///< Unexpected error from underlying libraries or kernel +} +} + +#endif // DPL_EXCEPTION_H diff --git a/modules/core/include/dpl/fast_delegate.h b/modules/core/include/dpl/fast_delegate.h new file mode 100644 index 0000000..501c801 --- /dev/null +++ b/modules/core/include/dpl/fast_delegate.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 +#include + +namespace DPL +{ +using namespace fastdelegate; +} // namespace DPL + +#endif // DPL_FAST_DELEGATE_H diff --git a/modules/core/include/dpl/file_input.h b/modules/core/include/dpl/file_input.h new file mode 100644 index 0000000..d1e4641 --- /dev/null +++ b/modules/core/include/dpl/file_input.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file file_input.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of file input + */ +#ifndef DPL_FILE_INPUT_H +#define DPL_FILE_INPUT_H + +#include +#include +#include + +namespace DPL +{ +class FileInput + : private Noncopyable, + public AbstractWaitableInput +{ +public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, OpenFailed) + DECLARE_EXCEPTION_TYPE(Base, CloseFailed) + }; + +protected: + int m_fd; + +public: + FileInput(); + FileInput(const std::string &fileName); + virtual ~FileInput(); + + void Open(const std::string &fileName); + void Close(); + + // AbstractInput + virtual BinaryQueueAutoPtr Read(size_t size); + + // AbstractWaitableInput + virtual WaitableHandle WaitableReadHandle() const; +}; +} // namespace DPL + +#endif // DPL_FILE_INPUT_H diff --git a/modules/core/include/dpl/file_input_mapping.h b/modules/core/include/dpl/file_input_mapping.h new file mode 100644 index 0000000..fd2d206 --- /dev/null +++ b/modules/core/include/dpl/file_input_mapping.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 +#include + +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 diff --git a/modules/core/include/dpl/file_output.h b/modules/core/include/dpl/file_output.h new file mode 100644 index 0000000..48532dc --- /dev/null +++ b/modules/core/include/dpl/file_output.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file file_output.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of file output + */ +#ifndef DPL_FILE_OUTPUT_H +#define DPL_FILE_OUTPUT_H + +#include +#include +#include + +namespace DPL +{ +class FileOutput + : private Noncopyable, + public AbstractWaitableOutput +{ +public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, OpenFailed) + DECLARE_EXCEPTION_TYPE(Base, CloseFailed) + }; + +protected: + int m_fd; + +public: + FileOutput(); + FileOutput(const std::string &fileName); + virtual ~FileOutput(); + + void Open(const std::string &fileName); + void Close(); + + // AbstractOutput + virtual size_t Write(const BinaryQueue &buffer, size_t bufferSize); + + // AbstracWaitableOutput + virtual WaitableHandle WaitableWriteHandle() const; +}; +} // namespace DPL + +#endif // DPL_FILE_OUTPUT_H diff --git a/modules/core/include/dpl/foreach.h b/modules/core/include/dpl/foreach.h new file mode 100644 index 0000000..0923609 --- /dev/null +++ b/modules/core/include/dpl/foreach.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file foreach.h + * @author Bartosz Janiak (b.janiak@samsung.com) + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of foreach macro for stl containers + */ +#ifndef DPL_FOREACH_H +#define DPL_FOREACH_H + +#include + +namespace DPL +{ +namespace Private +{ + +/* + * Used to detect type of valid reference to value object. + */ +template +T& ValueReference(T& t) +{ + return(t); +} + +template +const T& ValueReference(const T& t) +{ + return(t); +} + + +} //Private +} //DPL + + +#define DPL_FOREACH_IMPL(temporaryName, iterator, container) \ + __typeof__ (DPL::Private::ValueReference((container))) & \ + temporaryName = (container); \ + for (__typeof__ (temporaryName.begin()) iterator = \ + temporaryName.begin(); \ + (iterator) != temporaryName.end(); ++iterator) + +#define FOREACH(iterator, container) \ + DPL_FOREACH_IMPL( \ + DPL_MACRO_CONCAT(foreachContainerReference, __COUNTER__), \ + iterator, \ + container) + +#endif // DPL_FOREACH_H diff --git a/modules/core/include/dpl/framework_appcore.h b/modules/core/include/dpl/framework_appcore.h new file mode 100644 index 0000000..034134a --- /dev/null +++ b/modules/core/include/dpl/framework_appcore.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file framework_appcore.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the forward header file for APPCORE framework + */ +#pragma GCC system_header +#include diff --git a/modules/core/include/dpl/framework_efl.h b/modules/core/include/dpl/framework_efl.h new file mode 100644 index 0000000..6246587 --- /dev/null +++ b/modules/core/include/dpl/framework_efl.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file framework_efl.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the forward header file for EFL framework + */ +#pragma GCC system_header +#include +#include +#include diff --git a/modules/core/include/dpl/framework_vconf.h b/modules/core/include/dpl/framework_vconf.h new file mode 100644 index 0000000..8de9b31 --- /dev/null +++ b/modules/core/include/dpl/framework_vconf.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file framework_vconf.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the forward header file for VCONF + */ +#pragma GCC system_header +#include +#include diff --git a/modules/core/include/dpl/generic_event.h b/modules/core/include/dpl/generic_event.h new file mode 100644 index 0000000..371717a --- /dev/null +++ b/modules/core/include/dpl/generic_event.h @@ -0,0 +1,514 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file generic_event.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of MVC generic event + */ +#ifndef DPL_GENERIC_EVENT_H +#define DPL_GENERIC_EVENT_H + +namespace DPL +{ + +class EventSender +{ +public: + explicit EventSender(void *sender) + : m_sender(sender) + { + } + + void* GetSender() const + { + return m_sender; + } + +private: + void *m_sender; +}; + +class GenericEvent +{ +protected: + void *m_sender; + +public: + explicit GenericEvent(const EventSender &sender) + : m_sender(sender.GetSender()) + { + } + + virtual ~GenericEvent() + { + } + + void *GetSender() const + { + return m_sender; + } +}; + +class GenericEvent0 + : public GenericEvent +{ +public: + explicit GenericEvent0(const EventSender &sender) + : GenericEvent(sender) + { + } + + virtual ~GenericEvent0() + { + } + +}; + +template +class GenericEvent1 + : public GenericEvent0 +{ +public: + typedef Arg0Type Arg0; + +protected: + Arg0 m_arg0; + +public: + explicit GenericEvent1(const EventSender &sender) + : GenericEvent0(sender) + { + } + + GenericEvent1(Arg0 arg0, const EventSender &sender) + : GenericEvent0(sender), + m_arg0(arg0) + { + } + + virtual ~GenericEvent1() + { + } + + Arg0 GetArg0() const + { + return m_arg0; + } +}; + +template +class GenericEvent2 + : public GenericEvent1 +{ +public: + typedef Arg0Type Arg0; + typedef Arg1Type Arg1; + +protected: + Arg1 m_arg1; + +public: + explicit GenericEvent2(const EventSender &sender) + : GenericEvent1(sender) + { + } + + GenericEvent2(Arg0 arg0, Arg1 arg1, const EventSender &sender) + : GenericEvent1(arg0, sender), + m_arg1(arg1) + { + } + + virtual ~GenericEvent2() + { + } + + Arg1 GetArg1() const + { + return m_arg1; + } +}; + +template +class GenericEvent3 + : public GenericEvent2 +{ +public: + typedef Arg0Type Arg0; + typedef Arg1Type Arg1; + typedef Arg2Type Arg2; + +protected: + Arg2 m_arg2; + +public: + explicit GenericEvent3(const EventSender &sender) + : GenericEvent2(sender) + { + } + + GenericEvent3(Arg0 arg0, Arg1 arg1, Arg2 arg2, const EventSender &sender) + : GenericEvent2(arg0, arg1, sender), + m_arg2(arg2) + { + } + + virtual ~GenericEvent3() + { + } + + Arg2 GetArg2() const + { + return m_arg2; + } +}; + +template +class GenericEvent4 + : public GenericEvent3 +{ +public: + typedef Arg0Type Arg0; + typedef Arg1Type Arg1; + typedef Arg2Type Arg2; + typedef Arg3Type Arg3; + +protected: + Arg3 m_arg3; + +public: + explicit GenericEvent4(const EventSender &sender) + : GenericEvent3(sender) + { + } + + GenericEvent4(Arg0 arg0, Arg1 arg1, Arg2 arg2, Arg3 arg3, const EventSender &sender) + : GenericEvent3(arg0, arg1, arg2, sender), + m_arg3(arg3) + { + } + + virtual ~GenericEvent4() + { + } + + Arg3 GetArg3() const + { + return m_arg3; + } +}; + +template +class GenericEvent5 + : public GenericEvent4 +{ +public: + typedef Arg0Type Arg0; + typedef Arg1Type Arg1; + typedef Arg2Type Arg2; + typedef Arg3Type Arg3; + typedef Arg4Type Arg4; + +protected: + Arg4 m_arg4; + +public: + explicit GenericEvent5(const EventSender &sender) + : GenericEvent4(sender) + { + } + + GenericEvent5(Arg0 arg0, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, const EventSender &sender) + : GenericEvent4(arg0, arg1, arg2, arg3, sender), + m_arg4(arg4) + { + } + + virtual ~GenericEvent5() + { + } + + Arg4 GetArg4() const + { + return m_arg4; + } +}; + +template +class GenericEvent6 + : public GenericEvent5 +{ +public: + typedef Arg0Type Arg0; + typedef Arg1Type Arg1; + typedef Arg2Type Arg2; + typedef Arg3Type Arg3; + typedef Arg4Type Arg4; + typedef Arg5Type Arg5; + +protected: + Arg5 m_arg5; + +public: + explicit GenericEvent6(const EventSender &sender) + : GenericEvent5(sender) + { + } + + GenericEvent6(Arg0 arg0, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, const EventSender &sender) + : GenericEvent5(arg0, arg1, arg2, arg3, arg4, sender), + m_arg5(arg5) + { + } + + virtual ~GenericEvent6() + { + } + + Arg5 GetArg5() const + { + return m_arg5; + } +}; + +template +class GenericEvent7 + : public GenericEvent6 +{ +public: + typedef Arg0Type Arg0; + typedef Arg1Type Arg1; + typedef Arg2Type Arg2; + typedef Arg3Type Arg3; + typedef Arg4Type Arg4; + typedef Arg5Type Arg5; + typedef Arg6Type Arg6; + +protected: + Arg6 m_arg6; + +public: + explicit GenericEvent7(const EventSender &sender) + : GenericEvent6(sender) + { + } + + GenericEvent7(Arg0 arg0, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, const EventSender &sender) + : GenericEvent6(arg0, arg1, arg2, arg3, arg4, arg5, sender), + m_arg6(arg6) + { + } + + virtual ~GenericEvent7() + { + } + + Arg6 GetArg6() const + { + return m_arg6; + } +}; + +template +class GenericEvent8 + : public GenericEvent7 +{ +public: + typedef Arg0Type Arg0; + typedef Arg1Type Arg1; + typedef Arg2Type Arg2; + typedef Arg3Type Arg3; + typedef Arg4Type Arg4; + typedef Arg5Type Arg5; + typedef Arg6Type Arg6; + typedef Arg7Type Arg7; + +protected: + Arg7 m_arg7; + +public: + explicit GenericEvent8(const EventSender &sender) + : GenericEvent7(sender) + { + } + + GenericEvent8(Arg0 arg0, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, const EventSender &sender) + : GenericEvent7(arg0, arg1, arg2, arg3, arg4, arg5, arg6, sender), + m_arg7(arg7) + { + } + + virtual ~GenericEvent8() + { + } + + Arg7 GetArg7() const + { + return m_arg7; + } +}; + +} // namespace DPL + +#define DECLARE_GENERIC_EVENT_0(ClassName) \ + class ClassName \ + : public DPL::GenericEvent0 \ + { \ + public: \ + explicit ClassName(const DPL::EventSender &sender = DPL::EventSender(NULL)) \ + : DPL::GenericEvent0(sender) \ + { \ + } \ + }; + +#define DECLARE_GENERIC_EVENT_1(ClassName, Arg0Type) \ + class ClassName \ + : public DPL::GenericEvent1 \ + { \ + public: \ + explicit ClassName(const DPL::EventSender &sender = DPL::EventSender(NULL)) \ + : DPL::GenericEvent1(sender) \ + { \ + } \ + \ + explicit ClassName(Arg0Type arg0, \ + const DPL::EventSender &sender = DPL::EventSender(NULL)) \ + : DPL::GenericEvent1(arg0, sender) \ + { \ + } \ + }; + +#define DECLARE_GENERIC_EVENT_2(ClassName, Arg0Type, Arg1Type) \ + class ClassName \ + : public DPL::GenericEvent2 \ + { \ + public: \ + explicit ClassName(const DPL::EventSender &sender = DPL::EventSender(NULL)) \ + : DPL::GenericEvent2(sender) \ + { \ + } \ + \ + ClassName(Arg0Type arg0, Arg1Type arg1, \ + const DPL::EventSender &sender = DPL::EventSender(NULL)) \ + : DPL::GenericEvent2(arg0, arg1, sender) \ + { \ + } \ + }; + +#define DECLARE_GENERIC_EVENT_3(ClassName, Arg0Type, Arg1Type, Arg2Type) \ + class ClassName \ + : public DPL::GenericEvent3 \ + { \ + public: \ + explicit ClassName(const DPL::EventSender &sender = DPL::EventSender(NULL)) \ + : DPL::GenericEvent3(sender) \ + { \ + } \ + \ + ClassName(Arg0Type arg0, Arg1Type arg1, Arg2Type arg2, \ + const DPL::EventSender &sender = DPL::EventSender(NULL)) \ + : DPL::GenericEvent3(arg0, arg1, arg2, sender) \ + { \ + } \ + }; + +#define DECLARE_GENERIC_EVENT_4(ClassName, Arg0Type, Arg1Type, Arg2Type, Arg3Type) \ + class ClassName \ + : public DPL::GenericEvent4 \ + { \ + public: \ + explicit ClassName(const DPL::EventSender &sender = DPL::EventSender(NULL)) \ + : DPL::GenericEvent4(sender) \ + { \ + } \ + \ + ClassName(Arg0Type arg0, Arg1Type arg1, Arg2Type arg2, Arg3Type arg3, \ + const DPL::EventSender &sender = DPL::EventSender(NULL)) \ + : DPL::GenericEvent4(arg0, arg1, arg2, arg3, sender) \ + { \ + } \ + }; + +#define DECLARE_GENERIC_EVENT_5(ClassName, Arg0Type, Arg1Type, Arg2Type, Arg3Type, Arg4Type) \ + class ClassName \ + : public DPL::GenericEvent5 \ + { \ + public: \ + explicit ClassName(const DPL::EventSender &sender = DPL::EventSender(NULL)) \ + : DPL::GenericEvent5(sender) \ + { \ + } \ + \ + ClassName(Arg0Type arg0, Arg1Type arg1, Arg2Type arg2, Arg3Type arg3, Arg4Type arg4, \ + const DPL::EventSender &sender = DPL::EventSender(NULL)) \ + : DPL::GenericEvent5(arg0, arg1, arg2, arg3, arg4, sender) \ + { \ + } \ + }; + +#define DECLARE_GENERIC_EVENT_6(ClassName, Arg0Type, Arg1Type, Arg2Type, Arg3Type, Arg4Type, Arg5Type) \ + class ClassName \ + : public DPL::GenericEvent6 \ + { \ + public: \ + explicit ClassName(const DPL::EventSender &sender = DPL::EventSender(NULL)) \ + : DPL::GenericEvent6(sender) \ + { \ + } \ + \ + ClassName(Arg0Type arg0, Arg1Type arg1, Arg2Type arg2, Arg3Type arg3, Arg4Type arg4, Arg5Type arg5, \ + const DPL::EventSender &sender = DPL::EventSender(NULL)) \ + : DPL::GenericEvent6(arg0, arg1, arg2, arg3, arg4, arg5, sender) \ + { \ + } \ + }; + +#define DECLARE_GENERIC_EVENT_7(ClassName, Arg0Type, Arg1Type, Arg2Type, Arg3Type, Arg4Type, Arg5Type, Arg6Type) \ + class ClassName \ + : public DPL::GenericEvent7 \ + { \ + public: \ + explicit ClassName(const DPL::EventSender &sender = DPL::EventSender(NULL)) \ + : DPL::GenericEvent7(sender) \ + { \ + } \ + \ + ClassName(Arg0Type arg0, Arg1Type arg1, Arg2Type arg2, Arg3Type arg3, Arg4Type arg4, Arg5Type arg5, Arg6Type arg6, \ + const DPL::EventSender &sender = DPL::EventSender(NULL)) \ + : DPL::GenericEvent7(arg0, arg1, arg2, arg3, arg4, arg5, arg6, sender) \ + { \ + } \ + }; + +#define DECLARE_GENERIC_EVENT_8(ClassName, Arg0Type, Arg1Type, Arg2Type, Arg3Type, Arg4Type, Arg5Type, Arg6Type, Arg7Type) \ + class ClassName \ + : public DPL::GenericEvent8 \ + { \ + public: \ + explicit ClassName(const DPL::EventSender &sender = DPL::EventSender(NULL)) \ + : DPL::GenericEvent8(sender) \ + { \ + } \ + \ + ClassName(Arg0Type arg0, Arg1Type arg1, Arg2Type arg2, Arg3Type arg3, Arg4Type arg4, Arg5Type arg5, Arg6Type arg6, Arg7Type arg7, \ + const DPL::EventSender &sender = DPL::EventSender(NULL)) \ + : DPL::GenericEvent8(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, sender) \ + { \ + } \ + }; + +#endif // DPL_GENERIC_EVENT_H diff --git a/modules/core/include/dpl/lexical_cast.h b/modules/core/include/dpl/lexical_cast.h new file mode 100644 index 0000000..57eb5e0 --- /dev/null +++ b/modules/core/include/dpl/lexical_cast.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file lexical_cast.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief Header file for lexical cast + */ +#ifndef DPL_LEXICAL_CAST_H +#define DPL_LEXICAL_CAST_H + +#include + +namespace DPL +{ +template +TargetType lexical_cast(const SourceType &data) +{ + TargetType result; + + std::ostringstream out; + out << data; + + std::istringstream in(out.str()); + in >> result; + + return result; +} +} // namespace DPL + +#endif // DPL_LEXICAL_CAST_H diff --git a/modules/core/include/dpl/main.h b/modules/core/include/dpl/main.h new file mode 100644 index 0000000..62bd7e0 --- /dev/null +++ b/modules/core/include/dpl/main.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file main.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of main for EFL + */ +#ifndef DPL_MAIN_H +#define DPL_MAIN_H + +#include +#include +#include +#include +#include +#include + +namespace DPL +{ +class Main + : public WaitableHandleWatchSupport +{ +public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, CreateFailed) + }; + +protected: + Ecore_Fd_Handler *m_invokerHandler; + + static Eina_Bool StaticDispatchInvoker(void *data, Ecore_Fd_Handler *fd_handler); + static Eina_Bool StaticDispatchReadWatcher(void *data, Ecore_Fd_Handler *fd_handler); + static Eina_Bool StaticDispatchWriteWatcher(void *data, Ecore_Fd_Handler *fd_handler); + + typedef std::list EcoreFdHandlerList; + + EcoreFdHandlerList m_readWatchersList; + EcoreFdHandlerList m_writeWatchersList; + + void DispatchInvoker(); + void DispatchReadWatcher(WaitableHandle waitableHandle); + void DispatchWriteWatcher(WaitableHandle waitableHandle); + + void ReloadWatchList(); + + // WaitableHandleWatchSupport + virtual Thread *GetInvokerThread(); + virtual void HandleDirectInvoker(); + +#ifdef DPL_ENABLE_GLIB_LOOP_INTEGRATION_WORKAROUND + // GLIB loop intergration workaround + typedef int (*EcoreSelectType)(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); + EcoreSelectType m_oldEcoreSelect; + + static int EcoreSelectInterceptor(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); +#endif // DPL_ENABLE_GLIB_LOOP_INTEGRATION_WORKAROUND + +public: + explicit Main(); + virtual ~Main(); +}; + +/** + * Main singleton + */ +typedef Singleton
MainSingleton; +} // namespace DPL + +#endif // DPL_MAIN_H diff --git a/modules/core/include/dpl/mutex.h b/modules/core/include/dpl/mutex.h new file mode 100644 index 0000000..fbc0c5b --- /dev/null +++ b/modules/core/include/dpl/mutex.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file mutex.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of mutex + */ +#ifndef DPL_MUTEX_H +#define DPL_MUTEX_H + +#include +#include +#include + +namespace DPL +{ +class Mutex + : private Noncopyable +{ +public: + class ScopedLock + : private Noncopyable + { + private: + Mutex *m_mutex; + + public: + explicit ScopedLock(Mutex *mutex); + ~ScopedLock(); + }; + + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, CreateFailed) + DECLARE_EXCEPTION_TYPE(Base, LockFailed) + DECLARE_EXCEPTION_TYPE(Base, UnlockFailed) + }; + +private: + mutable pthread_mutex_t m_mutex; + + void Lock() const; + void Unlock() const; + +public: + Mutex(); + ~Mutex(); +}; + +} // namespace DPL + +#endif // DPL_MUTEX_H diff --git a/modules/core/include/dpl/named_base_pipe.h b/modules/core/include/dpl/named_base_pipe.h new file mode 100644 index 0000000..ab7630b --- /dev/null +++ b/modules/core/include/dpl/named_base_pipe.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file named_base_pipe.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of named base pipe + */ +#ifndef DPL_NAMED_BASE_PIPE_H +#define DPL_NAMED_BASE_PIPE_H + +#include + +namespace DPL +{ +class NamedBasePipe +{ +public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, AlreadyExist) + DECLARE_EXCEPTION_TYPE(Base, CreateFailed) + DECLARE_EXCEPTION_TYPE(Base, DestroyFailed) + }; + +public: + virtual ~NamedBasePipe(); + + static void Create(const std::string &fileName); + static void Destroy(const std::string &fileName); +}; +} // namespace DPL + +#endif // DPL_NAMED_BASE_PIPE_H diff --git a/modules/core/include/dpl/named_input_pipe.h b/modules/core/include/dpl/named_input_pipe.h new file mode 100644 index 0000000..247890d --- /dev/null +++ b/modules/core/include/dpl/named_input_pipe.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file named_input_pipe.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of named input pipe + */ +#ifndef DPL_NAMED_PIPE_H +#define DPL_NAMED_PIPE_H + +#include +#include +#include +#include + +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 diff --git a/modules/core/include/dpl/named_output_pipe.h b/modules/core/include/dpl/named_output_pipe.h new file mode 100644 index 0000000..9855a81 --- /dev/null +++ b/modules/core/include/dpl/named_output_pipe.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file named_output_pipe.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of named output pipe + */ +#ifndef DPL_NAMED_OUTPUT_PIPE_H +#define DPL_NAMED_OUTPUT_PIPE_H + +#include +#include +#include +#include + +namespace DPL +{ +class NamedOutputPipe + : private Noncopyable, + public NamedBasePipe, + public AbstractWaitableOutput +{ +public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, OpenFailed) + DECLARE_EXCEPTION_TYPE(Base, CloseFailed) + }; + +protected: + int m_fifo; + +public: + NamedOutputPipe(); + virtual ~NamedOutputPipe(); + + void Open(const std::string &fileName); + void Close(); + + // AbstractOutput + virtual size_t Write(const BinaryQueue &buffer, size_t bufferSize); + + // AbstracWaitableOutput + virtual WaitableHandle WaitableWriteHandle() const; +}; +} // namespace DPL + +#endif // DPL_NAMED_OUTPUT_PIPE_H diff --git a/modules/core/include/dpl/noncopyable.h b/modules/core/include/dpl/noncopyable.h new file mode 100644 index 0000000..2cc95d4 --- /dev/null +++ b/modules/core/include/dpl/noncopyable.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file noncopyable + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of noncopyable + */ +#ifndef DPL_NONCOPYABLE_H +#define DPL_NONCOPYABLE_H + +namespace DPL +{ +class Noncopyable +{ +private: + Noncopyable(const Noncopyable &); + const Noncopyable &operator=(const Noncopyable &); +public: + Noncopyable(); + virtual ~Noncopyable(); +}; + +} // namespace DPL + +#endif // DPL_NONCOPYABLE_H diff --git a/modules/core/include/dpl/noreturn.h b/modules/core/include/dpl/noreturn.h new file mode 100644 index 0000000..93845b7 --- /dev/null +++ b/modules/core/include/dpl/noreturn.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 diff --git a/modules/core/include/dpl/once.h b/modules/core/include/dpl/once.h new file mode 100644 index 0000000..2b9039e --- /dev/null +++ b/modules/core/include/dpl/once.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file once.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of once + */ +#ifndef DPL_ONCE_H +#define DPL_ONCE_H + +#include +#include +#include +#include + +namespace DPL +{ +class Once + : private Noncopyable +{ +public: + typedef FastDelegate Delegate; + + void Call(Delegate delegate); + +private: + Atomic m_atomic; + Mutex m_mutex; +}; +} // namespace DPL + +#endif // DPL_ONCE_H diff --git a/modules/core/include/dpl/optional.h b/modules/core/include/dpl/optional.h new file mode 100644 index 0000000..0a0736c --- /dev/null +++ b/modules/core/include/dpl/optional.h @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 + +namespace DPL +{ + +template +class Optional +{ + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, NullReference) + }; + +public: + Optional() : + m_null(true), + m_value() + { + } + + Optional(const Type& t) : + m_null(false), + m_value(t) + { + } + + bool IsNull() const + { + return m_null; + } + + Type& operator*() + { + if (m_null) Throw(typename Exception::NullReference); + return m_value; + } + + const Type& operator*() const + { + if (m_null) Throw(typename Exception::NullReference); + return m_value; + } + + const Type* operator->() const + { + if (m_null) Throw(typename Exception::NullReference); + return &m_value; + } + + Type* operator->() + { + if (m_null) Throw(typename Exception::NullReference); + return &m_value; + } + + bool operator!() const + { + return m_null; + } + + Optional& operator=(const Type& other) + { + m_null = false; + m_value = other; + return *this; + } + + bool operator==(const Optional& aSecond) const + { + return LogicalOperator(*this, aSecond, std::equal_to(), std::equal_to()); + } + + bool operator==(const Type& aSecond) const + { + return Optional(aSecond) == *this; + } + + bool operator!=(const Optional& aSecond) const + { + return !(*this == aSecond); + } + + bool operator<(const Optional& aSecond) const + { + return LogicalOperator(*this, aSecond, std::less(), std::less()); + } + + bool operator>(const Optional& aSecond) const + { + return LogicalOperator(*this, aSecond, std::greater(), std::greater()); + } + + bool operator<=(const Optional& aSecond) const + { + return *this == aSecond || *this < aSecond; + } + + bool operator>=(const Optional& aSecond) const + { + return *this == aSecond || *this > aSecond; + } + + static Optional Null; + +private: + bool m_null; + Type m_value; + + template + static bool LogicalOperator(const Optional& aFirst, const Optional& aSecond, + taComparator aComparator, taNullComparator aNullComparator) + { + if (aFirst.m_null == aSecond.m_null) + { + if (aFirst.m_null) + { + return taEquality; + } + else + { + return aComparator(aFirst.m_value, aSecond.m_value); + } + } + else + { + return aNullComparator(aFirst.m_null, aSecond.m_null); + } + } +}; + +template +Optional Optional::Null = Optional(); + +} //namespace DPL + +template +std::ostream& operator<<(std::ostream& aStream, const DPL::Optional& aOptional) +{ + if (aOptional.IsNull()) + { + return aStream << "null optional"; + } + else + { + return aStream << *aOptional; + } +} + +#endif // DPL_OPTIONAL_VALUE_H diff --git a/modules/core/include/dpl/optional_typedefs.h b/modules/core/include/dpl/optional_typedefs.h new file mode 100644 index 0000000..153e4df --- /dev/null +++ b/modules/core/include/dpl/optional_typedefs.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef DPL_OPTIONAL_TYPEDEFS_H +#define DPL_OPTIONAL_TYPEDEFS_H + +#include +#include + +namespace DPL +{ + +typedef Optional OptionalString; +typedef Optional OptionalInt; +typedef Optional OptionalBool; +typedef Optional OptionalFloat; + +} //namespace DPL + +#endif /* DPL_OPTIONAL_TYPEDEFS_H */ + diff --git a/modules/core/include/dpl/preprocessor.h b/modules/core/include/dpl/preprocessor.h new file mode 100644 index 0000000..83a41e3 --- /dev/null +++ b/modules/core/include/dpl/preprocessor.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 diff --git a/modules/core/include/dpl/read_write_mutex.h b/modules/core/include/dpl/read_write_mutex.h new file mode 100644 index 0000000..1e224de --- /dev/null +++ b/modules/core/include/dpl/read_write_mutex.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file read_write_mutex.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of read write mutex + */ +#ifndef DPL_READ_WRITE_MUTEX_H +#define DPL_READ_WRITE_MUTEX_H + +#include +#include +#include + +namespace DPL +{ +class ReadWriteMutex + : private Noncopyable +{ +public: + class ScopedReadLock + : private Noncopyable + { + private: + ReadWriteMutex *m_mutex; + + public: + ScopedReadLock(ReadWriteMutex *mutex); + virtual ~ScopedReadLock(); + }; + + class ScopedWriteLock + : private Noncopyable + { + private: + ReadWriteMutex *m_mutex; + + public: + ScopedWriteLock(ReadWriteMutex *mutex); + virtual ~ScopedWriteLock(); + }; + + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, CreateFailed) + DECLARE_EXCEPTION_TYPE(Base, DestroyFailed) + DECLARE_EXCEPTION_TYPE(Base, ReadLockFailed) + DECLARE_EXCEPTION_TYPE(Base, WriteLockFailed) + DECLARE_EXCEPTION_TYPE(Base, UnlockFailed) + }; + +private: + mutable pthread_rwlock_t m_rwlock; + + void ReadLock() const; + void WriteLock() const; + void Unlock() const; + +public: + explicit ReadWriteMutex(); + virtual ~ReadWriteMutex(); +}; + +} // namespace DPL + +#endif // DPL_READ_WRITE_MUTEX_H diff --git a/modules/core/include/dpl/recursive_mutex.h b/modules/core/include/dpl/recursive_mutex.h new file mode 100644 index 0000000..ec1e23c --- /dev/null +++ b/modules/core/include/dpl/recursive_mutex.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file recursive_mutex.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of recursive mutex + */ +#ifndef DPL_RECURSIVE_MUTEX_H +#define DPL_RECURSIVE_MUTEX_H + +#include +#include +#include + +namespace DPL +{ +class RecursiveMutex + : private Noncopyable +{ +public: + class ScopedLock + : private Noncopyable + { + private: + RecursiveMutex *m_mutex; + + public: + ScopedLock(RecursiveMutex *mutex); + virtual ~ScopedLock(); + }; + + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, CreateFailed) + DECLARE_EXCEPTION_TYPE(Base, DestroyFailed) + DECLARE_EXCEPTION_TYPE(Base, LockFailed) + DECLARE_EXCEPTION_TYPE(Base, UnlockFailed) + }; + +private: + mutable pthread_mutex_t m_mutex; + + void Lock() const; + void Unlock() const; + +public: + explicit RecursiveMutex(); + virtual ~RecursiveMutex(); +}; + +} // namespace DPL + +#endif // DPL_RECURSIVE_MUTEX_H diff --git a/modules/core/include/dpl/scoped_array.h b/modules/core/include/dpl/scoped_array.h new file mode 100644 index 0000000..fa0c540 --- /dev/null +++ b/modules/core/include/dpl/scoped_array.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*! + * @file 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 + +#include +#include + +namespace DPL +{ +template +struct ScopedArrayPolicy +{ + typedef Class* Type; + static Type NullValue() { return NULL; } + static void Destroy(Type ptr) { delete [] ptr; } +}; + +template +class ScopedArray : public ScopedResource > +{ + typedef ScopedArrayPolicy Policy; + typedef ScopedResource BaseType; + + public: + explicit ScopedArray(Class *ptr = Policy::NullValue()) : BaseType(ptr) { } + + Class &operator [](std::ptrdiff_t k) const + { + Assert(this->m_value != Policy::NullValue() && + "Dereference of scoped NULL array!"); + Assert(k >= 0 && "Negative array index"); + + return this->m_value[k]; + } +}; +} // namespace DPL + +#endif // DPL_SCOPED_PTR_H diff --git a/modules/core/include/dpl/scoped_close.h b/modules/core/include/dpl/scoped_close.h new file mode 100644 index 0000000..e51b7b4 --- /dev/null +++ b/modules/core/include/dpl/scoped_close.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*! + * @file scoped_close.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of scoped close RAII + */ +#ifndef DPL_SCOPED_CLOSE_H +#define DPL_SCOPED_CLOSE_H + +#include +#include +#include +#include +#include +#include + +namespace DPL +{ +struct ScopedClosePolicy +{ + typedef int Type; + static Type NullValue() { return -1; } + static void Destroy(Type handle) + { + if (handle != -1) + { + if (TEMP_FAILURE_RETRY(::fsync(handle)) == -1) + { + std::string errString = GetErrnoString(); + LogPedantic("Failed to fsync scoped close error: " + << errString); + } + + if (::close(handle) == -1) + { + std::string errString = GetErrnoString(); + LogPedantic("Failed to scoped close error: " + << errString); + } + } + } +}; + +class ScopedClose : public ScopedResource +{ + typedef ScopedClosePolicy Policy; + typedef ScopedResource BaseType; + typedef ScopedClosePolicy::Type Type; + + public: + explicit ScopedClose(Type handle = Policy::NullValue()) : + BaseType(handle) + { } +}; +} // namespace DPL + +#endif // DPL_SCOPED_CLOSE_H diff --git a/modules/core/include/dpl/scoped_fclose.h b/modules/core/include/dpl/scoped_fclose.h new file mode 100644 index 0000000..9758b8d --- /dev/null +++ b/modules/core/include/dpl/scoped_fclose.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*! + * @file scoped_fclose.h + * @author Piotr Marcinkiewicz (p.marcinkiew@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of scoped fclose RAII + */ +#ifndef DPL_SCOPED_FCLOSE_H +#define DPL_SCOPED_FCLOSE_H + + +#include +#include +#include +#include +#include +#include +#include + +namespace DPL +{ +struct ScopedFClosePolicy +{ + typedef FILE* Type; + static Type NullValue() { return NULL; } + static void Destroy(Type file) + { + if (file != NULL) + { + // Try to flush first + if (TEMP_FAILURE_RETRY(fflush(file)) != 0) + { + std::string errString = GetErrnoString(); + LogPedantic("Failed to fflush scoped fclose error: " + << errString); + } + + // fclose cannot be retried, try to close once + if (fclose(file) != 0) + { + std::string errString = GetErrnoString(); + LogPedantic("Failed scoped fclose error: " << errString); + } + } + } +}; + +class ScopedFClose : public ScopedResource +{ + typedef ScopedFClosePolicy Policy; + typedef ScopedResource BaseType; + + public: + explicit ScopedFClose(FILE* argFileStream = Policy::NullValue()) : + BaseType(argFileStream) + {} +}; +} // namespace DPL + +#endif // DPL_SCOPED_FCLOSE_H diff --git a/modules/core/include/dpl/scoped_free.h b/modules/core/include/dpl/scoped_free.h new file mode 100644 index 0000000..7b3bd5a --- /dev/null +++ b/modules/core/include/dpl/scoped_free.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*! + * @file scoped_free.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of scoped free RAII + */ + +#ifndef DPL_SCOPED_FREE_H +#define DPL_SCOPED_FREE_H + +#include +#include + +#include + +namespace DPL +{ +template +struct ScopedFreePolicy +{ + typedef Class* Type; + static Type NullValue() { return NULL; } + static void Destroy(Type ptr) { free(ptr); } +}; + +template +class ScopedFree : public ScopedResource > +{ + typedef ScopedFreePolicy Policy; + typedef ScopedResource BaseType; + + public: + explicit ScopedFree(Memory *ptr = Policy::NullValue()) : BaseType(ptr) { } +}; +} // namespace DPL + +#endif // DPL_SCOPED_FREE_H diff --git a/modules/core/include/dpl/scoped_gpointer.h b/modules/core/include/dpl/scoped_gpointer.h new file mode 100644 index 0000000..2f78bec --- /dev/null +++ b/modules/core/include/dpl/scoped_gpointer.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*! + * @file 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 +#include +#include +#include + +namespace DPL +{ + +struct ScopedGPointerPolicy +{ + typedef gpointer Type; + static Type NullValue() + { + return NULL; + } + static void Destroy(Type pointer) + { + if (pointer != NULL) { + g_object_unref(pointer); + } + } +}; + +template +class ScopedGPointer : public DPL::ScopedResource +{ + typedef ScopedGPointerPolicy Policy; + typedef DPL::ScopedResource BaseType; + + public: + explicit ScopedGPointer(typename Policy::Type pointer = + Policy::NullValue()) : + BaseType(pointer) + { + } + + Class *operator->() const throw() + { + Assert(this->m_value != Policy::NullValue() && + "Dereference of scoped NULL pointer!"); + return static_cast(this->m_value); + } + + Class & operator *() const throw() + { + Assert(this->m_value != Policy::NullValue() && + "Dereference of scoped NULL pointer!"); + return *static_cast(this->m_value); + } +}; + +} // namespace DPL + +#endif // DPL_SCOPED_GPOINTER_H diff --git a/modules/core/include/dpl/scoped_ptr.h b/modules/core/include/dpl/scoped_ptr.h new file mode 100644 index 0000000..3788dc1 --- /dev/null +++ b/modules/core/include/dpl/scoped_ptr.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 + +#include +#include + +namespace DPL +{ +template +struct ScopedPtrPolicy +{ + typedef Class* Type; + static Type NullValue() { return NULL; } + static void Destroy(Type ptr) { delete ptr; } +}; + +template > +class ScopedPtr : public ScopedResource +{ + typedef ClassPolicy Policy; + typedef ScopedResource BaseType; + + public: + explicit ScopedPtr(Class *ptr = Policy::NullValue()) : BaseType(ptr) { } + + Class *operator->() const throw() + { + Assert(this->m_value != Policy::NullValue() && + "Dereference of scoped NULL pointer!"); + return this->m_value; + } + + Class &operator *() const throw() + { + Assert(this->m_value != Policy::NullValue() && + "Dereference of scoped NULL pointer!"); + return *this->m_value; + } +}; +} // namespace DPL + +#endif // DPL_SCOPED_PTR_H diff --git a/modules/core/include/dpl/scoped_resource.h b/modules/core/include/dpl/scoped_resource.h new file mode 100644 index 0000000..a902d72 --- /dev/null +++ b/modules/core/include/dpl/scoped_resource.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file scoped_resource.h + * @author Piotr Marcinkiewicz (p.marcinkiew@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of scoped resource pattern + */ +#ifndef DPL_SCOPED_RESOURCE_H +#define DPL_SCOPED_RESOURCE_H + +#include + +namespace DPL +{ +template +class ScopedResource + : private Noncopyable +{ + public: + typedef typename ClassPolicy::Type ValueType; + typedef ScopedResource ThisType; + + protected: + ValueType m_value; + + public: + explicit ScopedResource(ValueType value) : m_value(value) { } + + ~ScopedResource() + { + ClassPolicy::Destroy(m_value); + } + + ValueType Get() const { return m_value; } + + void Reset(ValueType value = ClassPolicy::NullValue()) + { + ClassPolicy::Destroy(m_value); + m_value = value; + } + + ValueType Release() + { + ValueType value = m_value; + m_value = ClassPolicy::NullValue(); + return value; + } + typedef ValueType ThisType::*UnknownBoolType; + + operator UnknownBoolType() const + { + return m_value == ClassPolicy::NullValue() ? + 0 : //0 is valid here because it converts to false + &ThisType::m_value; //it converts to true + } + + bool operator !() const + { + return m_value == ClassPolicy::NullValue(); + } + +}; +} // namespace DPL + +#endif // DPL_SCOPED_RESOURCE_H diff --git a/modules/core/include/dpl/semaphore.h b/modules/core/include/dpl/semaphore.h new file mode 100644 index 0000000..420d9a5 --- /dev/null +++ b/modules/core/include/dpl/semaphore.h @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file semaphore.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of semaphore + */ +#ifndef DPL_SEMAPHORE_H +#define DPL_SEMAPHORE_H + +#include +#include +#include +#include + +namespace DPL +{ +class Semaphore + : private Noncopyable +{ +public: + class ScopedLock + : private Noncopyable + { + private: + Semaphore *m_semaphore; + + public: + explicit ScopedLock(Semaphore *semaphore); + ~ScopedLock(); + }; + + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, CreateFailed) + DECLARE_EXCEPTION_TYPE(Base, LockFailed) + DECLARE_EXCEPTION_TYPE(Base, UnlockFailed) + DECLARE_EXCEPTION_TYPE(Base, RemoveFailed) + }; + +private: + enum Type + { + Type_Unnamed, + Type_Named + }; + + Type m_type; + + mutable union + { + struct + { + sem_t handle; + } unnamed; + + struct + { + sem_t *handle; + char *name; + bool unlinkOnDestroy; + } named; + } m_semaphore; + + sem_t *InternalGet() const; + void InternalDestroy(); + + 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 diff --git a/modules/core/include/dpl/serialization.h b/modules/core/include/dpl/serialization.h new file mode 100644 index 0000000..8369665 --- /dev/null +++ b/modules/core/include/dpl/serialization.h @@ -0,0 +1,291 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file serialization.h + * @author Tomasz Swierczek (t.swierczek@samsung.com) + * @version 1.0 + * @brief Interfaces and templates used for data serialization. + */ +#ifndef SERIALIZATION_H +#define SERIALIZATION_H + +#include +#include +#include +#include + +namespace DPL { + +// Abstract data stream buffer +class IStream { + public: + virtual void Read(size_t num, void * bytes) = 0; + virtual void Write(size_t num, const void * bytes) = 0; + virtual ~IStream(){}; +}; + +// Serializable interface +class ISerializable { + public: +/* ISerializable(){}; + ISerializable(IStream&){}; */ + virtual void Serialize(IStream &) const = 0; + virtual ~ISerializable(){}; +}; + +struct Serialization { +// serialization +// normal functions + +// ISerializable objects +static void Serialize(IStream& stream, const ISerializable& object){ + object.Serialize(stream); +} +static void Serialize(IStream& stream, const ISerializable* const object){ + object->Serialize(stream); +} + +// unsigned int +static void Serialize(IStream& stream, const unsigned value){ + stream.Write(sizeof(value),&value); +} +static void Serialize(IStream& stream, const unsigned* const value){ + stream.Write(sizeof(*value),value); +} + +// int +static void Serialize(IStream& stream, const int value){ + stream.Write(sizeof(value),&value); +} +static void Serialize(IStream& stream, const int* const value){ + stream.Write(sizeof(*value),value); +} + +// bool +static void Serialize(IStream& stream, const bool value){ + stream.Write(sizeof(value),&value); +} +static void Serialize(IStream& stream, const bool* const value){ + stream.Write(sizeof(*value),value); +} + +// std::string +static void Serialize(IStream& stream, const std::string& str){ + int length = str.size(); + stream.Write(sizeof(length),&length); + stream.Write(length,str.c_str()); +} +static void Serialize(IStream& stream, const std::string* const str){ + int length = str->size(); + stream.Write(sizeof(length),&length); + stream.Write(length,str->c_str()); +} + +// STL templates + +// std::list +template +static void Serialize(IStream& stream, const std::list& list){ + int length = list.size(); + stream.Write(sizeof(length),&length); + for(typename std::list::const_iterator list_iter = list.begin(); + list_iter != list.end(); list_iter++) + { + Serialize(stream, *list_iter); + } +} +template +static void Serialize(IStream& stream, const std::list* const list){ + Serialize(stream,*list); +} + +// std::vector +template +static void Serialize(IStream& stream, const std::vector& vec){ + int length = vec.size(); + stream.Write(sizeof(length),&length); + for(typename std::vector::const_iterator vec_iter = vec.begin(); + vec_iter != vec.end(); vec_iter ++) + { + Serialize(stream, *vec_iter); + } +} +template +static void Serialize(IStream& stream, const std::vector* const vec){ + Serialize(stream,*vec); +} + +// std::pair +template +static void Serialize(IStream& stream, const std::pair& p){ + Serialize(stream, p.first); + Serialize(stream, p.second); +} +template +static void Serialize(IStream& stream, const std::pair* const p){ + Serialize(stream,*p); +} + +// std::map +template +static void Serialize(IStream& stream, const std::map& map){ + int length = map.size(); + stream.Write(sizeof(length),&length); + typename std::map::const_iterator it; + for (it = map.begin(); it != map.end(); ++it) { + Serialize(stream,(*it).first); + Serialize(stream,(*it).second); + } +} +template +static void Serialize(IStream& stream, const std::map* const map){ + Serialize(stream,*map); +} +}; // struct Serialization + +struct Deserialization { +// deserialization +// normal functions + +// ISerializable objects +// T instead of ISerializable is needed to call proper constructor +template +static void Deserialize(IStream& stream, T& object){ + object = T(stream); +} +template +static void Deserialize(IStream& stream, T*& object){ + object = new T(stream); +} + +// unsigned int +static void Deserialize(IStream& stream, unsigned& value){ + stream.Read(sizeof(value),&value); +} +static void Deserialize(IStream& stream, unsigned*& value){ + value = new unsigned; + stream.Read(sizeof(*value),value); +} + +// int +static void Deserialize(IStream& stream, int& value){ + stream.Read(sizeof(value),&value); +} +static void Deserialize(IStream& stream, int*& value){ + value = new int; + stream.Read(sizeof(*value),value); +} + +// bool +static void Deserialize(IStream& stream, bool& value){ + stream.Read(sizeof(value),&value); +} +static void Deserialize(IStream& stream, bool*& value){ + value = new bool; + stream.Read(sizeof(*value),value); +} + +// std::string +static void Deserialize(IStream& stream, std::string& str){ + int length; + stream.Read(sizeof(length),&length); + char * buf = new char[length+1]; + stream.Read(length,buf); + buf[length] = 0; + str = std::string(buf); + delete [] buf; +} +static void Deserialize(IStream& stream, std::string*& str){ + int length; + stream.Read(sizeof(length),&length); + char * buf = new char[length+1]; + stream.Read(length,buf); + buf[length] = 0; + str = new std::string(buf); + delete [] buf; +} + +// STL templates + +// std::list +template +static void Deserialize(IStream& stream, std::list& list){ + int length; + stream.Read(sizeof(length),&length); + for (int i = 0; i < length; ++i) { + T obj; + Deserialize(stream, obj); + list.push_back(obj); + } +} +template +static void Deserialize(IStream& stream, std::list*& list){ + list = new std::list; + Deserialize(stream,*list); +} + +// std::vector +template +static void Deserialize(IStream& stream, std::vector& vec){ + int length; + stream.Read(sizeof(length),&length); + for (int i = 0; i < length; ++i) { + T obj; + Deserialize(stream, obj); + vec.push_back(obj); + } +} +template +static void Deserialize(IStream& stream, std::vector*& vec){ + vec = new std::vector; + Deserialize(stream,*vec); +} + +// std::pair +template +static void Deserialize(IStream& stream, std::pair& p){ + Deserialize(stream, p.first); + Deserialize(stream, p.second); +} +template +static void Deserialize(IStream& stream, std::pair*& p){ + p = new std::pair; + Deserialize(stream,*p); +} + +// std::map +template +static void Deserialize(IStream& stream, std::map& map){ + int length; + stream.Read(sizeof(length),&length); + for (int i = 0; i < length; ++i) { + K key; + T obj; + Deserialize(stream,key); + Deserialize(stream,obj); + map[key] = obj; + } +} +template +static void Deserialize(IStream& stream, std::map*& map){ + map = new std::map; + Deserialize(stream,*map); +} +}; // struct Deserialization + +} // namespace DPL + +#endif // SERIALIZATION_H diff --git a/modules/core/include/dpl/shared_ptr.h b/modules/core/include/dpl/shared_ptr.h new file mode 100644 index 0000000..c964fd9 --- /dev/null +++ b/modules/core/include/dpl/shared_ptr.h @@ -0,0 +1,282 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 +#include +#include +#include +#include + +namespace DPL +{ +struct StaticPointerCastTag {}; +struct ConstPointerCastTag {}; +struct DynamicPointerCastTag {}; + +struct SharedCounter +{ + SharedCounter() + : ref(1) + { + } + + Atomic ref; +}; + +template +class EnableSharedFromThis; + +template +inline void _Internal_AcceptSharedPtr(SharedCounter *counter, Other *other, EnableSharedFromThis *otherBase) +{ + otherBase->_Internal_AcceptSharedPtr(counter, other); +} + +struct AnyPointer +{ + template + AnyPointer(Other *) + { + } +}; + +inline void _Internal_AcceptSharedPtr(SharedCounter *, AnyPointer, AnyPointer) +{ +} + +template +class SharedPtr +{ +public: + typedef Class ValueType; + typedef SharedPtr ThisType; + +private: + SharedCounter *m_counter; + Class *m_ptr; + + void AttachCounter(const SharedCounter *counter) + { + // Attention: R-Value const cast + m_counter = const_cast(counter); + + if (m_counter != NULL) + ++m_counter->ref; + } + + void DetachCounter() + { + if (m_counter) + { + if (!--m_counter->ref) + { + delete m_ptr; + delete m_counter; + } + + m_counter = NULL; + m_ptr = NULL; + } + } + +public: + SharedPtr() + : m_counter(NULL), + m_ptr(NULL) + { + } + + explicit SharedPtr(Class *ptr) + : m_counter(NULL), + m_ptr(ptr) + { + if (m_ptr != NULL) + { + m_counter = new SharedCounter(); + _Internal_AcceptSharedPtr(m_counter, m_ptr, m_ptr); + } + } + + SharedPtr(const SharedPtr &other) + : m_counter(NULL), + m_ptr(other.m_ptr) + { + AttachCounter(other.m_counter); + } + + SharedPtr(SharedCounter *counter, Class *ptr) + : m_counter(NULL), + m_ptr(ptr) + { + AttachCounter(counter); + } + + template + friend class SharedPtr; + + template + SharedPtr(const SharedPtr &other, const StaticPointerCastTag &) + : m_counter(NULL), + m_ptr(NULL) + { + m_ptr = static_cast(other.m_ptr); + AttachCounter(other.m_counter); + } + + template + SharedPtr(const SharedPtr &other, const ConstPointerCastTag &) + : m_counter(NULL), + m_ptr(NULL) + { + m_ptr = const_cast(other.m_ptr); + AttachCounter(other.m_counter); + } + + template + SharedPtr(const SharedPtr &other, const DynamicPointerCastTag &) + : m_counter(NULL), + m_ptr(NULL) + { + Class *ptr = dynamic_cast(other.Get()); + + if (ptr == NULL) + return; + + m_ptr = ptr; + AttachCounter(other.m_counter); + } + + virtual ~SharedPtr() + { + DetachCounter(); + } + + Class *Get() const + { + return m_counter == NULL ? NULL : m_ptr; + } + + Class *operator->() const + { + Assert(m_counter != NULL && "Dereference of shared NULL pointer!"); + return m_ptr; + } + + Class &operator *() const + { + Assert(m_counter != NULL && "Dereference of shared NULL pointer!"); + return *m_ptr; + } + + void Reset(Class *ptr = NULL) + { + DetachCounter(); + + if (ptr != NULL) + { + m_ptr = ptr; + m_counter = new SharedCounter(); + _Internal_AcceptSharedPtr(m_counter, m_ptr, m_ptr); + } + } + + SharedPtr &operator=(const SharedPtr &other) + { + if (this != &other) + { + DetachCounter(); + m_ptr = other.m_ptr; + AttachCounter(other.m_counter); + } + + return *this; + } + + Atomic::ValueType GetUseCount() const + { + if (m_counter == NULL) + return Atomic::ValueType(0); + + return m_counter->ref; + } + + DPL_IMPLEMENT_BOOL_OPERATOR(ValueType, ThisType, m_counter, m_ptr) +}; + +template +SharedPtr StaticPointerCast(const SharedPtr &ptr) +{ + return SharedPtr(ptr, StaticPointerCastTag()); +} + +template +SharedPtr ConstPointerCast(const SharedPtr &ptr) +{ + return SharedPtr(ptr, ConstPointerCastTag()); +} + +template +SharedPtr DynamicPointerCast(const SharedPtr &ptr) +{ + return SharedPtr(ptr, DynamicPointerCastTag()); +} + +template +inline bool operator ==(const SharedPtr &first, const SharedPtr &second) +{ + return first.Get() == second.Get(); +} + +template +inline bool operator !=(const SharedPtr &first, const SharedPtr &second) +{ + return first.Get() != second.Get(); +} + +template +inline bool operator <(const SharedPtr &first, const SharedPtr &second) +{ + return first.Get() < second.Get(); +} +template +inline bool operator >(const SharedPtr &first, const SharedPtr &second) +{ + return first.Get() > second.Get(); +} + +template +inline bool operator <=(const SharedPtr &first, const SharedPtr &second) +{ + return first.Get() <= second.Get(); +} + +template +inline bool operator >=(const SharedPtr &first, const SharedPtr &second) +{ + return first.Get() >= second.Get(); +} + +} // namespace DPL + +#endif // DPL_SHARED_PTR_H diff --git a/modules/core/include/dpl/single_instance.h b/modules/core/include/dpl/single_instance.h new file mode 100644 index 0000000..a480b2b --- /dev/null +++ b/modules/core/include/dpl/single_instance.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file single_instance.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of single instance + */ +#ifndef DPL_SINGLE_INSTANCE_H +#define DPL_SINGLE_INSTANCE_H + +#include +#include +#include + +namespace DPL +{ +class SingleInstance + : private Noncopyable +{ +public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, LockError) + DECLARE_EXCEPTION_TYPE(Base, ReleaseError) + }; + +private: + bool m_locked; + int m_fdLock; + +public: + SingleInstance(); + virtual ~SingleInstance(); + + bool TryLock(const std::string &lockName); + void Release(); +}; +} // namespace DPL + +#endif // DPL_SINGLE_INSTANCE_H diff --git a/modules/core/include/dpl/singleton.h b/modules/core/include/dpl/singleton.h new file mode 100644 index 0000000..24d2e64 --- /dev/null +++ b/modules/core/include/dpl/singleton.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file singleton.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of singleton + */ +#ifndef DPL_SINGLETON_H +#define DPL_SINGLETON_H + +#include +#include +#include + +namespace DPL +{ +template +class Singleton + : private Class +{ + // + // Note: + // + // To remove posibility of instantiating directly Class, + // make Class' default constructor protected + // + +private: + Singleton() + { + } + + typedef Optional OptionalThreadPtr; + 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 +Singleton& Singleton::InternalInstance() +{ + static Singleton instance; + return instance; +} + +template +Class &Singleton::Instance() +{ + Singleton& instance = Singleton::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 +void Singleton::SetThreadGuard(Thread *thread) +{ + Singleton& instance = Singleton::InternalInstance(); + instance.m_guard = OptionalThreadPtr(thread); +} + +template +void Singleton::ResetThreadGuard() +{ + Singleton& instance = Singleton::InternalInstance(); + instance.m_guard = OptionalThreadPtr::Null; +} + +#endif + +} // namespace DPL + +#endif // DPL_SINGLETON_H diff --git a/modules/core/include/dpl/singleton_impl.h b/modules/core/include/dpl/singleton_impl.h new file mode 100644 index 0000000..365ec15 --- /dev/null +++ b/modules/core/include/dpl/singleton_impl.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file singleton_impl.h + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of singleton + */ +#ifndef DPL_SINGLETON_IMPL_H +#define DPL_SINGLETON_IMPL_H + +/* + * WARNING! + * + * If some singleton's implementation uses another singletons implementation, + * those templates make the second singleton a dubleton. Be warned. Try to use + * singleton_safe_impl.h if possible. + */ + +namespace DPL +{ + +template +Singleton& Singleton::InternalInstance() +{ + static Singleton instance; + return instance; +} + +template +Class &Singleton::Instance() +{ + Singleton& instance = Singleton::InternalInstance(); + + 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 +void Singleton::SetThreadGuard(Thread *thread) +{ + Singleton& instance = Singleton::InternalInstance(); + instance.m_guard = OptionalThreadPtr(thread); +} + +template +void Singleton::ResetThreadGuard() +{ + Singleton& instance = Singleton::InternalInstance(); + instance.m_guard = OptionalThreadPtr::Null; +} + +} // namespace DPL + +#define IMPLEMENT_SINGLETON(Type) \ +template DPL::Singleton& DPL::Singleton::InternalInstance(); \ +template Type& DPL::Singleton::Instance(); \ +template void DPL::Singleton::SetThreadGuard(DPL::Thread *thread); \ +template void DPL::Singleton::ResetThreadGuard(); + +#endif // DPL_SINGLETON_IMPL_H diff --git a/modules/core/include/dpl/singleton_safe_impl.h b/modules/core/include/dpl/singleton_safe_impl.h new file mode 100644 index 0000000..8fbe009 --- /dev/null +++ b/modules/core/include/dpl/singleton_safe_impl.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file singleton_safe_impl.h + * @author Tomasz Swierczek (t.swierczek@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of singleton + */ +#ifndef DPL_SINGLETON_SAFE_IMPL_H +#define DPL_SINGLETON_SAFE_IMPL_H + +#define IMPLEMENT_SAFE_SINGLETON(Class) \ +namespace DPL { \ +template<> \ +Singleton& Singleton::InternalInstance() \ +{ \ + static Singleton instance; \ + return instance; \ +} \ + \ +template<> \ +Class &Singleton::Instance() \ +{ \ + Singleton& instance = Singleton::InternalInstance(); \ + 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::SetThreadGuard(Thread *thread) \ +{ \ + Singleton& instance = Singleton::InternalInstance(); \ + instance.m_guard = OptionalThreadPtr(thread); \ +} \ + \ +template<> \ +void Singleton::ResetThreadGuard() \ +{ \ + Singleton& instance = Singleton::InternalInstance(); \ + instance.m_guard = OptionalThreadPtr::Null; \ +} \ +template Singleton& Singleton::InternalInstance(); \ +template Class& Singleton::Instance(); \ +template void Singleton::SetThreadGuard(Thread *thread); \ +template void Singleton::ResetThreadGuard(); \ +} // namespace DPL + + +#endif // DPL_SINGLETON_SAFE_IMPL_H diff --git a/modules/core/include/dpl/sstream.h b/modules/core/include/dpl/sstream.h new file mode 100644 index 0000000..32e21d3 --- /dev/null +++ b/modules/core/include/dpl/sstream.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file sstream.h + * @author Piotr Marcinkiewicz (p.marcinkiew@samsung.com) + * @version 1.0 + * @brief String stream typedefs + */ +#ifndef DPL_CORE_INCLUDE_SSTREAM_H_ +#define DPL_CORE_INCLUDE_SSTREAM_H_ + +#include +#include + +namespace DPL +{ + +// @brief DPL IStringStream +typedef std::basic_istringstream IStringStream; + +// @brief DPL OStringStream +typedef std::basic_ostringstream OStringStream; + +} //namespace DPL + + +#endif // DPL_CORE_INCLUDE_SSTREAM_H_ diff --git a/modules/core/include/dpl/string.h b/modules/core/include/dpl/string.h new file mode 100644 index 0000000..7c35cdb --- /dev/null +++ b/modules/core/include/dpl/string.h @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file string.h + * @author Piotr Marcinkiewicz (p.marcinkiew@samsung.com) + * @version 1.0 + */ +#ifndef DPL_STRING +#define DPL_STRING + +#include +#include +#include +#include + +namespace DPL +{ +// @brief DPL string +typedef std::basic_string String; + +// @brief String exception class +class StringException +{ +public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + + // @brief Invalid init for UTF8 to UTF32 converter + DECLARE_EXCEPTION_TYPE(Base, IconvInitErrorUTF8ToUTF32) + + // @brief Invalid taStdContainerinit for UTF32 to UTF32 converter + DECLARE_EXCEPTION_TYPE(Base, IconvInitErrorUTF32ToUTF8) + + // @brief Invalid conversion for UTF8 to UTF32 converter + DECLARE_EXCEPTION_TYPE(Base, IconvConvertErrorUTF8ToUTF32) + + // @brief Invalid conversion for UTF8 to UTF32 converter + DECLARE_EXCEPTION_TYPE(Base, IconvConvertErrorUTF32ToUTF8) + + // @brief Invalid ASCII character detected in FromASCII + DECLARE_EXCEPTION_TYPE(Base, InvalidASCIICharacter) + + // @brief Invalid ASCII character detected in FromASCII + DECLARE_EXCEPTION_TYPE(Base, ICUInvalidCharacterFound) +}; + +//!\brief convert ASCII string to DPL::String +String FromASCIIString(const std::string& aString); + +//!\brief convert UTF32 string to DPL::String +String FromUTF32String(const std::wstring& aString); + +//@brief Returns String object created from UTF8 string +//@param[in] aString input UTF-8 string +String FromUTF8String(const std::string& aString); + +//@brief Returns String content as std::string +std::string ToUTF8String(const String& aString); + +//@brief Compare two unicode strings +int StringCompare(const String &left, + const String &right, + bool caseInsensitive = false); + +//@brief Splits the string into substrings. +//@param[in] str Input string +//@param[in] delimiters array or string containing a sequence of substring delimiters. Can be also a single delimiter character. +//@param[in] it InserterIterator that is used to save the generated substrings. +template +void Tokenize(const StringType& str, const Delimiters& delimiters, InserterIterator it, bool ignoreEmpty = false) +{ + typename StringType::size_type nextSearchStart = 0; + typename StringType::size_type pos; + typename StringType::size_type length; + + while ( true ) + { + pos = str.find_first_of(delimiters, nextSearchStart); + length = ((pos == StringType::npos) ? str.length() : pos) - nextSearchStart; + + if ( !ignoreEmpty || length > 0 ) + { + *it = str.substr(nextSearchStart, length); + it++; + } + + if ( pos == StringType::npos ) + return; + + nextSearchStart = pos + 1; + } +} + +} //namespace DPL + +std::ostream& operator<<(std::ostream& aStream, const DPL::String& aString); + +#endif // DPL_STRING diff --git a/modules/core/include/dpl/task.h b/modules/core/include/dpl/task.h new file mode 100644 index 0000000..7e43253 --- /dev/null +++ b/modules/core/include/dpl/task.h @@ -0,0 +1,535 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file task.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @author Radoslaw Wicik (r.wicik@samsung.com) + * @version 1.0 + * @brief Header file for abstaract task definition + */ +#ifndef DPL_TASK_H +#define DPL_TASK_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 +class TaskDecl + : public Task +{ +protected: + typedef void (Impl::*Step)(); + +private: + typedef std::list StepList; + + StepList m_steps; + StepList m_abortSteps; + typename StepList::iterator m_currentStep; + typename StepList::iterator m_nextStep; + bool m_switched; + + Impl *m_impl; + bool m_running; + +protected: + void AddStep(Step step) + { + Assert(!m_running && "AddStep is not allowed after calling NextStep!"); + Assert(m_steps.end() == std::find(m_steps.begin(), m_steps.end(), step) && "The same step started twice is not supported"); + m_steps.push_back(step); + m_nextStep = m_steps.begin(); + } + + void AddAbortStep(Step step) + { + Assert(!m_running && "AddAbortStep is not allowed after calling NextStep!"); + Assert(m_abortSteps.end() == std::find(m_abortSteps.begin(), m_abortSteps.end(), step) && "The same step started twice is not supported"); + m_abortSteps.push_front(step); + } + + void SwitchToStep(Step step) + { + /// @TODO There can be problem here if user sets the same method two times in task list. + typename StepList::iterator i = std::find(m_steps.begin(), m_steps.end(), step); + Assert(i != m_steps.end()); + m_nextStep = i; + m_switched = true; + } + + Step GetCurrentStep() const + { + if(m_currentStep == m_steps.end()) + return NULL; + + return *m_currentStep; + } + +public: + TaskDecl(Impl *impl) + : m_switched(false), + m_impl(impl), + m_running(false) + { + Assert(this == m_impl); + m_currentStep = m_steps.end(); + m_nextStep = m_steps.end(); + } + + bool NextStep() + { + m_running = true; + + Assert(m_nextStep != m_steps.end() && "Step list is empty or all steps done"); + + m_switched = false; + + Step call = *m_nextStep; + (*m_impl.*call)(); + + m_currentStep = m_nextStep; + + if (m_switched) + return true; + else + return ++m_nextStep != m_steps.end(); + } + + bool Abort() + { + m_running = true; + + m_steps.clear(); + + if (m_abortSteps.empty()) + return false; + + FOREACH (it, m_abortSteps) + m_steps.push_back(*it); + + m_nextStep = m_steps.begin(); + + m_abortSteps.clear(); + + return true; + } + + size_t GetStepCount() const + { + return static_cast(m_steps.size()); + } +}; + +template +class MultiTaskDecl + : public Task +{ +protected: + typedef void (ImplementationType::*Step)(); + typedef std::list StepList; + typedef std::stack StepStack; + +private: + static std::string StepToString(Step step) + { + std::ostringstream pseudoAddressStream; + pseudoAddressStream << std::hex << union_cast(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 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 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( + m_unsatisfiedSteps.size() + + m_satisfiedSteps.size() + + m_executingSteps.size() + + m_historicSteps.size()); + } +}; +} // namespace DPL + +#endif // DPL_TASK_H diff --git a/modules/core/include/dpl/task_list.h b/modules/core/include/dpl/task_list.h new file mode 100644 index 0000000..b010dfc --- /dev/null +++ b/modules/core/include/dpl/task_list.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 +#include + +namespace DPL +{ +class TaskList + : public Task +{ +private: + typedef std::list 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 diff --git a/modules/core/include/dpl/thread.h b/modules/core/include/dpl/thread.h new file mode 100644 index 0000000..b49ee09 --- /dev/null +++ b/modules/core/include/dpl/thread.h @@ -0,0 +1,389 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file thread.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of thread + */ +#ifndef DPL_THREAD_H +#define DPL_THREAD_H + +#include +//#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DPL +{ +class Thread + : private Noncopyable, + public WaitableHandleWatchSupport +{ +public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, CreateFailed) + DECLARE_EXCEPTION_TYPE(Base, DestroyFailed) + DECLARE_EXCEPTION_TYPE(Base, RunFailed) + DECLARE_EXCEPTION_TYPE(Base, QuitFailed) + DECLARE_EXCEPTION_TYPE(Base, UnmanagedThread) + }; + + typedef void (*EventDeleteProc)(void *event, void *userParam); + typedef void (*EventDispatchProc)(void *event, void *userParam); + +protected: + /** + * Main thread entry + * The method is intended to be overloaded with custom code. + * Default implementation just executes Exec method to process + * all thread exents + */ + virtual int ThreadEntry(); + + /** + * Start processing of thread events + */ + int Exec(); + +private: + struct InternalEvent + { + void *event; + void *userParam; + EventDispatchProc eventDispatchProc; + EventDeleteProc eventDeleteProc; + + InternalEvent(void *eventArg, + void *userParamArg, + EventDispatchProc eventDispatchProcArg, + EventDeleteProc eventDeleteProcArg) + : event(eventArg), + userParam(userParamArg), + eventDispatchProc(eventDispatchProcArg), + eventDeleteProc(eventDeleteProcArg) + { + } + }; + + struct InternalTimedEvent + : InternalEvent + { + unsigned long dueTimeMiliseconds; + unsigned long registerTimeMiliseconds; + + InternalTimedEvent(void *eventArg, + void *userParamArg, + unsigned long dueTimeMilisecondsArg, + unsigned long registerTimeMilisecondsArg, + EventDispatchProc eventDispatchProcArg, + EventDeleteProc eventDeleteProcArg) + : InternalEvent(eventArg, + userParamArg, + eventDispatchProcArg, + eventDeleteProcArg), + dueTimeMiliseconds(dueTimeMilisecondsArg), + registerTimeMiliseconds(registerTimeMilisecondsArg) + { + } + + bool operator<(const InternalTimedEvent &other) + { + return registerTimeMiliseconds + dueTimeMiliseconds > other.registerTimeMiliseconds + other.dueTimeMiliseconds; + } + }; + + // Internal event list + typedef std::list InternalEventList; + + // Internal timed event list + typedef std::vector InternalTimedEventVector; + + // State managment + pthread_t m_thread; + volatile bool m_abandon; + volatile bool m_running; + Mutex m_stateMutex; + WaitableEvent m_quitEvent; + + // Event processing + Mutex m_eventMutex; + InternalEventList m_eventList; + WaitableEvent m_eventInvoker; + + // Timed events processing + Mutex m_timedEventMutex; + InternalTimedEventVector m_timedEventVector; + WaitableEvent m_timedEventInvoker; + + // WaitableHandleWatchSupport + virtual Thread *GetInvokerThread(); + virtual void HandleDirectInvoker(); + bool m_directInvoke; + + // Internals + unsigned long GetCurrentTimeMiliseconds() const; + void ProcessEvents(); + void ProcessTimedEvents(); + + static void *StaticThreadEntry(void *param); + +public: + explicit Thread(); + virtual ~Thread(); + + /** + * Run thread. Does nothing if thread is already running + */ + void Run(); + + /** + * Send quit message to thread and wait for its end + * Does nothing is thread is not running + */ + void Quit(); + + /** + * Current thread retrieval + * Returns DPL thread handle or NULL if it is main program thread + */ + static Thread *GetCurrentThread(); + + /** + * Low-level event push, usually used only by EventSupport + */ + void PushEvent(void *event, EventDispatchProc eventDispatchProc, EventDeleteProc eventDeleteProc, void *userParam); + + /** + * Low-level timed event push, usually used only by EventSupport + */ + void PushTimedEvent(void *event, double dueTimeSeconds, EventDispatchProc eventDispatchProc, EventDeleteProc eventDeleteProc, void *userParam); + + /** + * Sleep for a number of seconds + */ + static void Sleep(uint64_t seconds); + + /** + * Sleep for a number of miliseconds + */ + static void MiliSleep(uint64_t miliseconds); + + /** + * Sleep for a number of microseconds + */ + static void MicroSleep(uint64_t microseconds); + + /** + * Sleep for a number of nanoseconds + */ + static void NanoSleep(uint64_t nanoseconds); +}; + +extern bool g_TLSforMainCreated; + +// In case of using TLV in main thread, pthread_exit(NULL) has to be called in +// this thread explicitly. +// On the other hand, possibly, because of the kernel bug, there exist +// a problem, if any other thread than main exist during pthread_exit call +// (process can become non-responsive) +// TODO further investigation is required. +template +class ThreadLocalVariable + : public Noncopyable +{ +public: + typedef Type ValueType; + + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, NullReference) + }; + +private: + pthread_key_t m_key; + + struct ManagedValue + { + ValueType value; + Optional guardKey; + }; + + static void MainThreadExitClean() + { + // There is a possible bug in kernel. If this function is called + // before ALL threads are closed, process will hang! + // Because of that, by default this function has to be called in well + // known "threads state". + + // pthread_exit(NULL); + } + + static void InternalDestroy(void *specific) + { + // Destroy underlying type + ManagedValue *instance = static_cast(specific); + if(instance->guardKey.IsNull()) + { + delete instance; + } + else + { + int result = pthread_setspecific(*(instance->guardKey), instance); + + Assert(result == 0 && + "Failed to set thread local variable"); + } + } + + Type &Reference(bool allowInstantiate = false) + { + ManagedValue *instance = + static_cast(pthread_getspecific(m_key)); + + if (!instance) + { + // Check if it is allowed to instantiate + if (!allowInstantiate) + Throw(typename Exception::NullReference); + + // checking, if specific data is created for Main thread + // If yes, pthread_exit(NULL) is required + if (!g_TLSforMainCreated) + { + if (Thread::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(pthread_getspecific(m_key)); + + if (!specific) + return; + + // TODO Should be an assert? is it developers fault to Reset Guarded + // value? + specific->guardKey = Optional::Null; + + InternalDestroy(specific); + + int result = pthread_setspecific(m_key, NULL); + + Assert(result == 0 && + "Failed to reset thread local variable"); + } + + // GuardValue(true) allows to defer destroy (by pthread internal + // functionality) thread specific value until GuardValue(false) will be + // called. + void GuardValue(bool guard) + { + ManagedValue *instance = + static_cast(pthread_getspecific(m_key)); + + Assert(instance && "Failed to get the value"); + + instance->guardKey = guard ? m_key : Optional::Null; + } +}; +} // namespace DPL + +#endif // DPL_THREAD_H diff --git a/modules/core/include/dpl/type_list.h b/modules/core/include/dpl/type_list.h new file mode 100644 index 0000000..e5c0f77 --- /dev/null +++ b/modules/core/include/dpl/type_list.h @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file type_list.h + * @author Bartosz Janiak (b.janiak@samsung.com) + * @version 1.0 + * @brief Generic type list template + */ +#ifndef DPL_TYPE_LIST_H +#define DPL_TYPE_LIST_H + +#include + +namespace DPL +{ +class TypeListGuard +{ +public: + template + struct Element + { + struct ERROR_TypeListElementIndexIsOutOfBounds; + typedef ERROR_TypeListElementIndexIsOutOfBounds Type; + }; + + static const size_t Size = 0; +}; + +template +class TypeList +{ +private: + class DummyClass + { + }; + + template + struct TypeCounter : public TypeCounter + { + }; + + template + struct TypeCounter + { + static const size_t Size = Enum; + }; + +public: + typedef TailType Tail; + typedef HeadType Head; + typedef TypeList ThisType; + + template + struct Element + { + typedef typename TailType::template Element::Type Type; + }; + + template + struct Element<0, DummyType> + { + typedef HeadType Type; + }; + + template + struct Contains + { + typedef typename TailType::template Contains::Yes Yes; + }; + + template + struct Contains + { + typedef int Yes; + }; + + static const size_t Size = TypeCounter::Size; +}; + +template +struct TypeListDecl +{ + typedef TypeList::Type> Type; +}; + +template<> +struct TypeListDecl +{ + typedef TypeListGuard Type; +}; +} // namespace DPL + +#endif // DPL_TYPE_LIST_H diff --git a/modules/core/include/dpl/union_cast.h b/modules/core/include/dpl/union_cast.h new file mode 100644 index 0000000..9576dbb --- /dev/null +++ b/modules/core/include/dpl/union_cast.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file union_cast.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief Header file for union cast + */ +#ifndef DPL_UNION_CAST_H +#define DPL_UNION_CAST_H + +#include + +namespace DPL +{ +template +TargetType union_cast(const SourceType &data) +{ + union + { + SourceType source; + TargetType target; + } cast; + + std::memset(&cast, 0, sizeof(cast)); + + cast.source = data; + return cast.target; +} +} // namespace DPL + +#endif // DPL_UNION_CAST_H diff --git a/modules/core/include/dpl/unused.h b/modules/core/include/dpl/unused.h new file mode 100644 index 0000000..18729db --- /dev/null +++ b/modules/core/include/dpl/unused.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 diff --git a/modules/core/include/dpl/waitable_event.h b/modules/core/include/dpl/waitable_event.h new file mode 100644 index 0000000..ee53dfc --- /dev/null +++ b/modules/core/include/dpl/waitable_event.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file waitable_event.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of waitable event + */ +#ifndef DPL_WAITABLE_EVENT_H +#define DPL_WAITABLE_EVENT_H + +#include +#include +#include +#include + +namespace DPL +{ + +class WaitableEvent + : private Noncopyable +{ +public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, CreateFailed) + DECLARE_EXCEPTION_TYPE(Base, DestroyFailed) + DECLARE_EXCEPTION_TYPE(Base, SignalFailed) + DECLARE_EXCEPTION_TYPE(Base, ResetFailed) + }; + +private: + int m_pipe[2]; + +public: + WaitableEvent(); + virtual ~WaitableEvent(); + + WaitableHandle GetHandle() const; + + void Signal() const; + void Reset() const; +}; + +} // namespace DPL + +#endif // DPL_WAITABLE_EVENT_H diff --git a/modules/core/include/dpl/waitable_handle.h b/modules/core/include/dpl/waitable_handle.h new file mode 100644 index 0000000..865cca4 --- /dev/null +++ b/modules/core/include/dpl/waitable_handle.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file waitable_handle.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file of waitable handle + */ +#ifndef DPL_WAITABLE_HANDLE_H +#define DPL_WAITABLE_HANDLE_H + +#include +#include +#include + +namespace DPL +{ + +/** + * Waitable unix wait handle definition + */ +typedef int WaitableHandle; + +/** + * Waitable handle list + */ +typedef std::vector WaitableHandleList; + +/** + * Wait mode + */ +class WaitMode +{ +public: + enum Type + { + Read, ///< Wait for readability state changes + Write ///< Wait for writability state changes + }; +}; + +/** + * Waitable handle list ex + */ +typedef std::vector > WaitableHandleListEx; + +/** + * Waitable handle index list + */ +typedef std::vector WaitableHandleIndexList; + +/** + * Wait exceptions + */ +DECLARE_EXCEPTION_TYPE(DPL::Exception, WaitFailed) + +/** + * Wait for single handle readability + * Convience function. + * + * @return Signaled waitable handle index list + * @throw WaitFailed Fatal error occurred while waiting for signal + */ +WaitableHandleIndexList WaitForSingleHandle(WaitableHandle handle, unsigned long miliseconds = 0xFFFFFFFF); + +/** + * Wait for single handle + * Convience function. + * + * @return Signaled waitable handle index list + * @throw WaitFailed Fatal error occurred while waiting for signal + */ +WaitableHandleIndexList WaitForSingleHandle(WaitableHandle handle, WaitMode::Type mode, unsigned long miliseconds = 0xFFFFFFFF); + +/** + * Wait for multiple handles readability + * + * @return Signaled waitable handle index list + * @throw WaitFailed Fatal error occurred while waiting for signal + */ +WaitableHandleIndexList WaitForMultipleHandles(const WaitableHandleList &handleList, unsigned long miliseconds = 0xFFFFFFFF); + +/** + * Wait for multiple handles readability + * + * @return Signaled waitable handle index list + * @throw WaitFailed Fatal error occurred while waiting for signal + */ +WaitableHandleIndexList WaitForMultipleHandles(const WaitableHandleListEx &handleListEx, unsigned long miliseconds = 0xFFFFFFFF); + +} // namespace DPL + +#endif // DPL_WAITABLE_HANDLE_H diff --git a/modules/core/include/dpl/waitable_handle_watch_support.h b/modules/core/include/dpl/waitable_handle_watch_support.h new file mode 100644 index 0000000..0ff29b1 --- /dev/null +++ b/modules/core/include/dpl/waitable_handle_watch_support.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file waitable_handle_watch_support.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of waitable handle watch support + */ +#ifndef DPL_WAITABLE_HANDLE_WATCH_SUPPORT_H +#define DPL_WAITABLE_HANDLE_WATCH_SUPPORT_H + +#include +#include +#include +#include +#include +#include + +namespace DPL +{ + +class Thread; + +class WaitableHandleWatchSupport +{ +public: + class WaitableHandleListener + { + public: + virtual ~WaitableHandleListener() {} + + virtual void OnWaitableHandleEvent(WaitableHandle waitableHandle, WaitMode::Type mode) = 0; + }; + +protected: + // Invoker waitable handle + // Signaled by Add/Remove methods + // After being signaled one must call Handle invoke to reset invoker + WaitableHandle WaitableInvokerHandle() const; + + // Waitable handle ex list + WaitableHandleListEx WaitableWatcherHandles() const; + + // Perform actions for signaled waitable handle + // Called in execution context, after + void HandleWatcher(WaitableHandle waitableHandle, WaitMode::Type mode); + + // Perform actions after invoker was signaled + void InvokerFinished(); + + // Get invoker context + virtual Thread *GetInvokerThread() = 0; + + // Invoke direct invoker + virtual void HandleDirectInvoker() = 0; + +private: + // Waitable event watchers + struct WaitableHandleWatcher + { + WaitableHandleListener *listener; + WaitMode::Type mode; + + WaitableHandleWatcher(WaitableHandleListener *l, WaitMode::Type m) + : listener(l), + mode(m) + { + } + }; + + typedef std::list WaitableHandleListenerList; + + struct WaitableHandleWatchers + { + WaitableHandleListenerList listeners; + size_t readListenersCount; + size_t writeListenersCount; + + WaitableHandleWatchers() + : readListenersCount(0), + writeListenersCount(0) + { + } + }; + + typedef std::map WaitableHandleWatchersMap; + + // Waitable event watch support + mutable RecursiveMutex m_watchersMutex; + WaitableHandleWatchersMap m_watchersMap; + WaitableEvent m_watchersInvoker; + WaitableEvent m_watchersInvokerCommit; + + // Invoke call + void CommitInvoker(); + +public: + /** + * Constructor + */ + explicit WaitableHandleWatchSupport(); + + /** + * Destructor + */ + virtual ~WaitableHandleWatchSupport(); + + /** + * Adds listener for specific waitable event + * + * @param[in] listener Listener to attach + * @param[in] waitableHandle Waitable handle to listen for changes + * @param[in] mode Type of changes to listen to + * @return none + * @see WaitMode::Type + */ + void AddWaitableHandleWatch(WaitableHandleListener *listener, WaitableHandle waitableHandle, WaitMode::Type mode); + + /** + * Remove listener for specific waitable event + * + * @param[in] listener Listener to detach + * @param[in] waitableHandle Waitable handle to unlisten for changes + * @param[in] mode Type of changes to unlisten to + * @return none + * @see WaitMode::Type + */ + void RemoveWaitableHandleWatch(WaitableHandleListener *listener, WaitableHandle waitableHandle, WaitMode::Type mode); + + /** + * Retrieve inherited context + * + * @return Inherited waitable handle watch support + */ + static WaitableHandleWatchSupport *InheritedContext(); +}; + +} // namespace DPL + +#endif // DPL_WAITABLE_HANDLE_WATCH_SUPPORT_H diff --git a/modules/core/include/dpl/workaround.h b/modules/core/include/dpl/workaround.h new file mode 100644 index 0000000..19c26ef --- /dev/null +++ b/modules/core/include/dpl/workaround.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file workaround.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file of workaround + */ +#ifndef DPL_WORKAROUND_H +#define DPL_WORKAROUND_H + +/** + * Define following macro to track invalid waitable handles + * in WaitForSingle/WaitForMultiple functions + */ +#define DPL_ENABLE_WAITABLE_HANDLE_BADF_CHECK + +/** + * Define following macro to enable workaround for problem + * with GLIB loop integration and EBADF error handling + */ +#define DPL_ENABLE_GLIB_LOOP_INTEGRATION_WORKAROUND + +/** + * Define following macro to enable workaround for problem + * with invalid conversions in htons/ntohs macros + */ +#define DPL_ENABLE_HTONS_NTOHS_I386_WORKAROUND + +#endif // DPL_WORKAROUND_H diff --git a/modules/core/include/dpl/zip_input.h b/modules/core/include/dpl/zip_input.h new file mode 100644 index 0000000..f4b8e34 --- /dev/null +++ b/modules/core/include/dpl/zip_input.h @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file zip_input.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file of zip input + */ +#ifndef DPL_ZIP_INPUT_H +#define DPL_ZIP_INPUT_H + +#include +#include +#include +#include +#include +#include + +namespace DPL +{ +class ZipInput + : private Noncopyable +{ +public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, OpenFailed) + DECLARE_EXCEPTION_TYPE(Base, ReadGlobalInfoFailed) + DECLARE_EXCEPTION_TYPE(Base, ReadGlobalCommentFailed) + DECLARE_EXCEPTION_TYPE(Base, SeekFileFailed) + DECLARE_EXCEPTION_TYPE(Base, FileInfoFailed) + DECLARE_EXCEPTION_TYPE(Base, OpenFileFailed) + DECLARE_EXCEPTION_TYPE(Base, ReadFileFailed) + }; + + typedef std::pair FileHandle; + + struct 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 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 diff --git a/modules/core/src/DESCRIPTION b/modules/core/src/DESCRIPTION new file mode 100644 index 0000000..9043c93 --- /dev/null +++ b/modules/core/src/DESCRIPTION @@ -0,0 +1 @@ +Source files diff --git a/modules/core/src/abstract_waitable_input_adapter.cpp b/modules/core/src/abstract_waitable_input_adapter.cpp new file mode 100644 index 0000000..e7964ea --- /dev/null +++ b/modules/core/src/abstract_waitable_input_adapter.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_waitable_input_adapter.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of abstract waitable input adapter + */ +#include + +namespace DPL +{ + +AbstractWaitableInputAdapter::AbstractWaitableInputAdapter(AbstractInput *input) + : m_input(input) +{ + m_waitableEvent.Signal(); +} + +BinaryQueueAutoPtr AbstractWaitableInputAdapter::Read(size_t size) +{ + return m_input->Read(size); +} + +WaitableHandle AbstractWaitableInputAdapter::WaitableReadHandle() const +{ + return m_waitableEvent.GetHandle(); +} + +} // namespace DPL diff --git a/modules/core/src/abstract_waitable_input_output_adapter.cpp b/modules/core/src/abstract_waitable_input_output_adapter.cpp new file mode 100644 index 0000000..d07737b --- /dev/null +++ b/modules/core/src/abstract_waitable_input_output_adapter.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_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 + +namespace DPL +{ + +AbstractWaitableInputOutputAdapter::AbstractWaitableInputOutputAdapter(AbstractInputOutput *inputOutput) + : AbstractWaitableInputAdapter(inputOutput), + AbstractWaitableOutputAdapter(inputOutput) +{ +} + +} // namespace DPL diff --git a/modules/core/src/abstract_waitable_output_adapter.cpp b/modules/core/src/abstract_waitable_output_adapter.cpp new file mode 100644 index 0000000..f849579 --- /dev/null +++ b/modules/core/src/abstract_waitable_output_adapter.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_waitable_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 + +namespace DPL +{ + +AbstractWaitableOutputAdapter::AbstractWaitableOutputAdapter(AbstractOutput *output) + : m_output(output) +{ + m_waitableEvent.Signal(); +} + +size_t AbstractWaitableOutputAdapter::Write(const BinaryQueue &buffer, size_t bufferSize) +{ + return m_output->Write(buffer, bufferSize); +} + +WaitableHandle AbstractWaitableOutputAdapter::WaitableWriteHandle() const +{ + return m_waitableEvent.GetHandle(); +} + +} // namespace DPL diff --git a/modules/core/src/address.cpp b/modules/core/src/address.cpp new file mode 100644 index 0000000..624fe7e --- /dev/null +++ b/modules/core/src/address.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file address.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of address + */ +#include +#include +#include + +namespace DPL +{ +Address::Address() + : m_port(0) +{ +} + +Address::Address(const std::string &address) + : m_address(address), + m_port(0) +{ +} + +Address::Address(const std::string &address, unsigned short port) + : m_address(address), + m_port(port) +{ +} + +Address::~Address() +{ +} + +std::string Address::GetAddress() const +{ + return m_address; +} + +unsigned short Address::GetPort() const +{ + return m_port; +} + +std::string Address::ToString() const +{ + std::ostringstream out; + out << m_address << ":" << m_port; + return out.str(); +} + +bool Address::operator<(const Address &addr) const +{ + return ToString() < addr.ToString(); +} + +} // namespace DPL diff --git a/modules/core/src/application.cpp b/modules/core/src/application.cpp new file mode 100644 index 0000000..f4a2147 --- /dev/null +++ b/modules/core/src/application.cpp @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file application.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of MVC application support + */ +#include +#include + +namespace // anonymous +{ +static DPL::Application *g_application = NULL; +} // namespace anonymous + +namespace DPL +{ +int Application::app_create(void *data) +{ + Application *This=static_cast(data); + This->OnCreate(); + return 0; +} + +int Application::app_terminate(void *data) +{ + Application *This=static_cast(data); + This->OnTerminate(); + return 0; +} + +int Application::app_pause(void *data) +{ + Application *This=static_cast(data); + This->OnPause(); + return 0; +} + +int Application::app_resume(void *data) +{ + Application *This=static_cast(data); + This->OnResume(); + return 0; +} + +int Application::app_reset(bundle *b, void *data) +{ + Application *This=static_cast(data); + This->OnReset(b); + return 0; +} + +Application::Application(int argc, char** argv, + const std::string& applicationName, + bool showMainWindow) + : m_argc(argc), + m_argv(argv), + m_applicationName(applicationName), + m_mainWindowVisible(showMainWindow) +{ + if (g_application != NULL) + ThrowMsg(Exception::TooManyInstances, "Only single instance of Application allowed at one time!"); + + g_application = this; +} + +Application::~Application() +{ + g_application = NULL; +} + +int Application::Exec() +{ + LogPedantic("Starting application framework..."); + + struct appcore_ops ops; + ops.create = app_create; + ops.terminate = app_terminate; + ops.pause = app_pause; + ops.resume = app_resume; + ops.reset = app_reset; + ops.data=this; + + int result = appcore_efl_main(m_applicationName.c_str(), &m_argc, &m_argv, &ops); + + LogPedantic("Exited application framework"); + + return result; +} + +void Application::OnCreate() +{ + LogPedantic("On application create"); +} + +void Application::OnStart() +{ + LogPedantic("On application start"); +} + +void Application::OnStop() +{ + LogPedantic("On application stop"); +} + +void Application::OnResume() +{ + LogPedantic("On application resume"); +} + +void Application::OnPause() +{ + LogPedantic("On application pause"); +} + +void Application::OnRelaunch() +{ + LogPedantic("On application relaunch"); +} + +void Application::OnReset(bundle *b) +{ + (void)b; + LogPedantic("On application reset"); +} + +void Application::OnTerminate() +{ + LogPedantic("On application terminate"); +} + +void Application::OnLowMemory() +{ + LogPedantic("On application low memory"); +} + +void Application::OnLowBattery() +{ + LogPedantic("On application low battery"); +} + +void Application::OnLanguageChanged() +{ + LogPedantic("On application language changed"); +} + +void Application::Quit() +{ + elm_exit(); +} + +DPL::Atomic ApplicationExt::m_useCount(0); + +ApplicationExt::ApplicationExt(int argc, char** argv, const std::string& applicationName, bool showMainWindow) : + Application(argc, argv, applicationName, showMainWindow) +{ +} + +ApplicationExt::~ApplicationExt() +{ +} + +int ApplicationExt::Exec() +{ + if (0 == m_useCount.CompareAndExchange(0, 1)) + { + return Application::Exec(); + } + else + { + elm_run(); + } + return 0; +} + +void ApplicationExt::Quit() +{ + elm_exit(); +} +} // namespace DPL diff --git a/modules/core/src/apply.cpp b/modules/core/src/apply.cpp new file mode 100644 index 0000000..d299b57 --- /dev/null +++ b/modules/core/src/apply.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file apply.cpp + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of apply functionality + */ +#include + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/modules/core/src/assert.cpp b/modules/core/src/assert.cpp new file mode 100644 index 0000000..9a363dc --- /dev/null +++ b/modules/core/src/assert.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file assert.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of assert + */ +#include +#include +#include +#include + +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 diff --git a/modules/core/src/atomic.cpp b/modules/core/src/atomic.cpp new file mode 100644 index 0000000..65af06e --- /dev/null +++ b/modules/core/src/atomic.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file atomic.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of atomic + */ +#include + +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 diff --git a/modules/core/src/binary_queue.cpp b/modules/core/src/binary_queue.cpp new file mode 100644 index 0000000..42b351e --- /dev/null +++ b/modules/core/src/binary_queue.cpp @@ -0,0 +1,310 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file binary_queue.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of binary queue + */ +#include +#include +#include +#include +#include +#include +#include + +namespace DPL +{ +BinaryQueue::BinaryQueue() + : m_size(0) +{ +} + +BinaryQueue::BinaryQueue(const BinaryQueue &other) + : m_size(0) +{ + AppendCopyFrom(other); +} + +BinaryQueue::~BinaryQueue() +{ + // Remove all remainig buckets + Clear(); +} + +const BinaryQueue &BinaryQueue::operator=(const BinaryQueue &other) +{ + if (this != &other) + { + Clear(); + AppendCopyFrom(other); + } + + return *this; +} + +void BinaryQueue::AppendCopyFrom(const BinaryQueue &other) +{ + // To speed things up, always copy as one bucket + void *bufferCopy = malloc(other.m_size); + + if (bufferCopy == NULL) + throw std::bad_alloc(); + + try + { + other.Flatten(bufferCopy, other.m_size); + AppendUnmanaged(bufferCopy, other.m_size, &BufferDeleterFree, NULL); + } + catch (const std::bad_alloc &) + { + // Free allocated memory + free(bufferCopy); + throw; + } +} + +void BinaryQueue::AppendMoveFrom(BinaryQueue &other) +{ + // Copy all buckets + std::copy(other.m_buckets.begin(), other.m_buckets.end(), std::back_inserter(m_buckets)); + m_size += other.m_size; + + // Clear other, but do not free memory + other.m_buckets.clear(); + other.m_size = 0; +} + +void BinaryQueue::AppendCopyTo(BinaryQueue &other) const +{ + other.AppendCopyFrom(*this); +} + +void BinaryQueue::AppendMoveTo(BinaryQueue &other) +{ + other.AppendMoveFrom(*this); +} + +void BinaryQueue::Clear() +{ + std::for_each(m_buckets.begin(), m_buckets.end(), &DeleteBucket); + m_buckets.clear(); + m_size = 0; +} + +void BinaryQueue::AppendCopy(const void* buffer, size_t bufferSize) +{ + // Create data copy with malloc/free + void *bufferCopy = malloc(bufferSize); + + // Check if allocation succeded + if (bufferCopy == NULL) + throw std::bad_alloc(); + + // Copy user data + memcpy(bufferCopy, buffer, bufferSize); + + try + { + // Try to append new bucket + AppendUnmanaged(bufferCopy, bufferSize, &BufferDeleterFree, NULL); + } + catch (const std::bad_alloc &) + { + // Free allocated memory + free(bufferCopy); + throw; + } +} + +void BinaryQueue::AppendUnmanaged(const void* buffer, size_t bufferSize, BufferDeleter deleter, void* userParam) +{ + // Do not attach empty buckets + if (bufferSize == 0) + { + deleter(buffer, bufferSize, userParam); + return; + } + + // Just add new bucket with selected deleter + m_buckets.push_back(new Bucket(buffer, bufferSize, deleter, userParam)); + + // Increase total queue size + m_size += bufferSize; +} + +size_t BinaryQueue::Size() const +{ + return m_size; +} + +bool BinaryQueue::Empty() const +{ + return m_size == 0; +} + +void BinaryQueue::Consume(size_t size) +{ + // Check parameters + if (size > m_size) + Throw(Exception::OutOfData); + + size_t bytesLeft = size; + + // Consume data and/or remove buckets + while (bytesLeft > 0) + { + // Get consume size + size_t count = std::min(bytesLeft, m_buckets.front()->left); + + m_buckets.front()->ptr = static_cast(m_buckets.front()->ptr) + count; + m_buckets.front()->left -= count; + bytesLeft -= count; + m_size -= count; + + if (m_buckets.front()->left == 0) + { + DeleteBucket(m_buckets.front()); + m_buckets.pop_front(); + } + } +} + +void BinaryQueue::Flatten(void *buffer, size_t bufferSize) const +{ + // Check parameters + if (bufferSize == 0) + return; + + if (bufferSize > m_size) + Throw(Exception::OutOfData); + + size_t bytesLeft = bufferSize; + void *ptr = buffer; + BucketList::const_iterator bucketIterator = m_buckets.begin(); + Assert(m_buckets.end() != bucketIterator); + + // Flatten data + while (bytesLeft > 0) + { + // Get consume size + size_t count = std::min(bytesLeft, (*bucketIterator)->left); + + // Copy data to user pointer + memcpy(ptr, (*bucketIterator)->ptr, count); + + // Update flattened bytes count + bytesLeft -= count; + ptr = static_cast(ptr) + count; + + // Take next bucket + ++bucketIterator; + } +} + +void BinaryQueue::FlattenConsume(void *buffer, size_t bufferSize) +{ + // FIXME: Optimize + Flatten(buffer, bufferSize); + Consume(bufferSize); +} + +void BinaryQueue::DeleteBucket(BinaryQueue::Bucket *bucket) +{ + delete bucket; +} + +void BinaryQueue::BufferDeleterFree(const void* data, size_t dataSize, void* userParam) +{ + (void)dataSize; + (void)userParam; + + // Default free deleter + free(const_cast(data)); +} + +BinaryQueue::Bucket::Bucket(const void* data, size_t dataSize, BufferDeleter dataDeleter, void* userParam) + : buffer(data), + ptr(data), + size(dataSize), + left(dataSize), + deleter(dataDeleter), + param(userParam) +{ + Assert(data != NULL); + Assert(deleter != NULL); +} + +BinaryQueue::Bucket::~Bucket() +{ + // Invoke deleter on bucket data + deleter(buffer, size, param); +} + +BinaryQueue::BucketVisitor::~BucketVisitor() +{ +} + +BinaryQueue::BucketVisitorCall::BucketVisitorCall(BucketVisitor *visitor) + : m_visitor(visitor) +{ +} + +BinaryQueue::BucketVisitorCall::~BucketVisitorCall() +{ +} + +void BinaryQueue::BucketVisitorCall::operator()(Bucket *bucket) const +{ + m_visitor->OnVisitBucket(bucket->ptr, bucket->left); +} + +void BinaryQueue::VisitBuckets(BucketVisitor *visitor) const +{ + Assert(visitor != NULL); + + // Visit all buckets + std::for_each(m_buckets.begin(), m_buckets.end(), BucketVisitorCall(visitor)); +} + +BinaryQueueAutoPtr BinaryQueue::Read(size_t size) +{ + // Simulate input stream + size_t available = std::min(size, m_size); + + ScopedFree bufferCopy(malloc(available)); + + if (!bufferCopy) + throw std::bad_alloc(); + + BinaryQueueAutoPtr result(new BinaryQueue()); + + Flatten(bufferCopy.Get(), available); + result->AppendUnmanaged(bufferCopy.Get(), available, &BufferDeleterFree, NULL); + bufferCopy.Release(); + Consume(available); + + return result; +} + +size_t BinaryQueue::Write(const BinaryQueue &buffer, size_t bufferSize) +{ + // Simulate output stream + AppendCopyFrom(buffer); + return bufferSize; +} +} // namespace DPL diff --git a/modules/core/src/char_traits.cpp b/modules/core/src/char_traits.cpp new file mode 100644 index 0000000..13ea72e --- /dev/null +++ b/modules/core/src/char_traits.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/modules/core/src/colors.cpp b/modules/core/src/colors.cpp new file mode 100644 index 0000000..19e6d3a --- /dev/null +++ b/modules/core/src/colors.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 + + +namespace DPL +{ + +namespace Colors +{ + +namespace Text +{ + +const char* BOLD_GREEN_BEGIN = "\033[1;32m"; +const char* BOLD_GREEN_END = "\033[m"; +const char* RED_BEGIN = "\033[0;31m"; +const char* RED_END = "\033[m"; +const char* PURPLE_BEGIN = "\033[0;35m"; +const char* PURPLE_END = "\033[m"; +const char* GREEN_BEGIN = "\033[0;32m"; +const char* GREEN_END = "\033[m"; +const char* CYAN_BEGIN = "\033[0;36m"; +const char* CYAN_END = "\033[m"; +const char* BOLD_RED_BEGIN = "\033[1;31m"; +const char* BOLD_RED_END = "\033[m"; +const char* BOLD_YELLOW_BEGIN = "\033[1;33m"; +const char* BOLD_YELLOW_END = "\033[m"; +const char* BOLD_GOLD_BEGIN = "\033[0;33m"; +const char* BOLD_GOLD_END = "\033[m"; +const char* BOLD_WHITE_BEGIN = "\033[1;37m"; +const char* BOLD_WHITE_END = "\033[m"; + +} //namespace Text + +namespace Html +{ + +const char* BOLD_GREEN_BEGIN = ""; +const char* BOLD_GREEN_END = ""; +const char* PURPLE_BEGIN = ""; +const char* PURPLE_END = ""; +const char* RED_BEGIN = ""; +const char* RED_END = ""; +const char* GREEN_BEGIN = ""; +const char* GREEN_END = ""; +const char* CYAN_BEGIN = ""; +const char* CYAN_END = ""; +const char* BOLD_RED_BEGIN = ""; +const char* BOLD_RED_END = ""; +const char* BOLD_YELLOW_BEGIN = ""; +const char* BOLD_YELLOW_END = ""; +const char* BOLD_GOLD_BEGIN = ""; +const char* BOLD_GOLD_END = ""; +const char* BOLD_WHITE_BEGIN = ""; +const char* BOLD_WHITE_END = ""; + +} //namespace Html + +} //namespace Colors + +} //namespace DPL diff --git a/modules/core/src/copy.cpp b/modules/core/src/copy.cpp new file mode 100644 index 0000000..465a9b9 --- /dev/null +++ b/modules/core/src/copy.cpp @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file copy.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of copy + */ +#include +#include +#include + +namespace DPL +{ +namespace // anonymous +{ +const size_t DEFAULT_COPY_BUFFER_SIZE = 16768; +} // namespace anonymous + +void Copy(AbstractWaitableInput *input, AbstractWaitableOutput *output) +{ + Try + { + while (true) + { + BinaryQueueAutoPtr buffer; + + while (true) + { + // Try to get data immediately + buffer = input->Read(DEFAULT_COPY_BUFFER_SIZE); + + // Do we need to wait for data ? + if (!buffer.get()) + { + WaitForSingleHandle(input->WaitableReadHandle(), WaitMode::Read); + continue; + } + + if (buffer->Empty()) + return; // Done + + // Ok, to process + break; + } + + // Write out all data + while (!buffer->Empty()) + { + // Try to write all data immediately + size_t count = output->Write(*buffer, buffer->Size()); + + // Do we need to wait for writing data ? + if (count == 0) + { + WaitForSingleHandle(output->WaitableWriteHandle(), WaitMode::Write); + continue; + } + + // Consume data + buffer->Consume(count); + } + } + } + Catch (DPL::Exception) + { + ReThrow(CopyFailed); + } +} + +void Copy(AbstractWaitableInput *input, AbstractWaitableOutput *output, size_t totalBytes) +{ + Try + { + size_t bytesLeft = totalBytes; + + while (bytesLeft > 0) + { + BinaryQueueAutoPtr buffer; + + // Copy at most left bytes + size_t bytesToCopy = bytesLeft > DEFAULT_COPY_BUFFER_SIZE ? DEFAULT_COPY_BUFFER_SIZE : bytesLeft; + + while (true) + { + // Try to get data immediately + buffer = input->Read(bytesToCopy); + + // Do we need to wait for data ? + if (!buffer.get()) + { + WaitForSingleHandle(input->WaitableReadHandle(), WaitMode::Read); + continue; + } + + if (buffer->Empty()) + ThrowMsg(CopyFailed, "Unexpected end of abstract input"); + + // Ok, to process + break; + } + + // Write out all data + while (!buffer->Empty()) + { + // Try to write all data immediately + size_t count = output->Write(*buffer, buffer->Size()); + + // Do we need to wait for writing data ? + if (count == 0) + { + WaitForSingleHandle(output->WaitableWriteHandle(), WaitMode::Write); + continue; + } + + // Consume data + buffer->Consume(count); + bytesLeft -= count; + } + } + } + Catch (DPL::Exception) + { + ReThrow(CopyFailed); + } +} +} // namespace DPL diff --git a/modules/core/src/errno_string.cpp b/modules/core/src/errno_string.cpp new file mode 100644 index 0000000..1637d87 --- /dev/null +++ b/modules/core/src/errno_string.cpp @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file errno_string.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of errno string + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DPL +{ +namespace // anonymous +{ +const size_t DEFAULT_ERRNO_STRING_SIZE = 32; +} // namespace anonymous + +std::string GetErrnoString(int error) +{ + size_t size = DEFAULT_ERRNO_STRING_SIZE; + char *buffer = NULL; + + for (;;) + { + // Add one extra characted for end of string null value + char *newBuffer = static_cast(::realloc(buffer, size + 1)); + + if (!newBuffer) + { + // Failed to realloc + ::free(buffer); + throw std::bad_alloc(); + } + + // Setup reallocated buffer + buffer = newBuffer; + ::memset(buffer, 0, size + 1); + + // Try to retrieve error string +#if (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && ! _GNU_SOURCE + // The XSI-compliant version of strerror_r() is provided if: + int result = ::strerror_r(error, buffer, size); + + if (result == 0) + { + ScopedFree scopedBufferFree(buffer); + return std::string(buffer); + } +#else + errno = 0; + + // Otherwise, the GNU-specific version is provided. + char *result = ::strerror_r(error, buffer, size); + + if (result != NULL) + { + ScopedFree scopedBufferFree(buffer); + return std::string(result); + } +#endif + + // Interpret errors + switch (errno) + { + case EINVAL: + // We got an invalid errno value + ::free(buffer); + ThrowMsg(InvalidErrnoValue, "Invalid errno value: " << error); + + case ERANGE: + // Incease buffer size and retry + size <<= 1; + continue; + + default: + Assert(0 && "Invalid errno value after call to strerror_r!"); + } + } +} +} // namespace DPL diff --git a/modules/core/src/exception.cpp b/modules/core/src/exception.cpp new file mode 100644 index 0000000..9d6de98 --- /dev/null +++ b/modules/core/src/exception.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file exception.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation of exception system + */ +#include +#include +#include + +namespace DPL +{ +Exception* Exception::m_lastException = NULL; +unsigned int Exception::m_exceptionCount = 0; +void (*Exception::m_terminateHandler)() = NULL; + +void LogUnhandledException(const std::string &str) +{ + // Logging to console + printf("%s\n", str.c_str()); + + // Logging to dlog + LogPedantic(str); +} + +void LogUnhandledException(const std::string &str, const char *filename, int line, const char *function) +{ + // Logging to console + std::ostringstream msg; + msg << "\033[1;5;31m\n=== [" << filename << ":" << line << "] " << function << " ===\033[m"; + msg << str; + printf("%s\n", msg.str().c_str()); + + // Logging to dlog + DPL::Log::LogSystemSingleton::Instance().Error(str.c_str(), filename, line, function); +} +} // namespace DPL diff --git a/modules/core/src/fast_delegate.cpp b/modules/core/src/fast_delegate.cpp new file mode 100644 index 0000000..94b3ca3 --- /dev/null +++ b/modules/core/src/fast_delegate.cpp @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 diff --git a/modules/core/src/file_input.cpp b/modules/core/src/file_input.cpp new file mode 100644 index 0000000..6e536db --- /dev/null +++ b/modules/core/src/file_input.cpp @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 +#include +#include +#include +#include +#include +#include + +namespace DPL +{ +namespace // anonymous +{ +const size_t DEFAULT_READ_BUFFER_SIZE = 4096; +} // namespace anonymous + +FileInput::FileInput() + : m_fd(-1) +{ +} + +FileInput::FileInput(const std::string& fileName) + : m_fd(-1) +{ + Open(fileName); +} + +FileInput::~FileInput() +{ + Close(); +} + +void FileInput::Open(const std::string& fileName) +{ + // Open non-blocking + int fd = TEMP_FAILURE_RETRY(open(fileName.c_str(), O_RDONLY | O_NONBLOCK)); + + // Throw an exception if an error occurred + if (fd == -1) + ThrowMsg(Exception::OpenFailed, fileName); + + // Close if any existing + Close(); + + // Save new descriptor + m_fd = fd; + + LogPedantic("Opened file: " << fileName); +} + +void FileInput::Close() +{ + if (m_fd == -1) + return; + + if (TEMP_FAILURE_RETRY(close(m_fd)) == -1) + Throw(Exception::CloseFailed); + + m_fd = -1; + + LogPedantic("Closed file"); +} + +BinaryQueueAutoPtr FileInput::Read(size_t size) +{ + size_t bytesToRead = size > DEFAULT_READ_BUFFER_SIZE ? DEFAULT_READ_BUFFER_SIZE : size; + + // Malloc default read buffer size + // It is unmanaged, so it can be then attached directly to binary queue + void *buffer = malloc(bytesToRead); + + if (buffer == NULL) + throw std::bad_alloc(); + + LogPedantic("Trying to read " << bytesToRead << " bytes"); + + ssize_t result = TEMP_FAILURE_RETRY(read(m_fd, buffer, bytesToRead)); + + LogPedantic("Read " << result << " bytes from file"); + + if (result > 0) + { + // Succedded to read socket data + BinaryQueueAutoPtr binaryQueue(new BinaryQueue()); + + // Append unmanaged memory + binaryQueue->AppendUnmanaged(buffer, result, &BinaryQueue::BufferDeleterFree, NULL); + + // Return buffer + return binaryQueue; + } + else if (result == 0) + { + // Socket was gracefuly closed + free(buffer); + + // Return empty buffer + return BinaryQueueAutoPtr(new BinaryQueue()); + } + else + { + // Must first save errno value, because it may be altered + int lastErrno = errno; + + // Free buffer + free(buffer); + + // Interpret error result + (void)lastErrno; + + // FIXME: Handle specific errno + Throw(AbstractInput::Exception::ReadFailed); + } +} + +WaitableHandle FileInput::WaitableReadHandle() const +{ + return static_cast(m_fd); +} +} // namespace DPL diff --git a/modules/core/src/file_input_mapping.cpp b/modules/core/src/file_input_mapping.cpp new file mode 100644 index 0000000..2bfcd15 --- /dev/null +++ b/modules/core/src/file_input_mapping.cpp @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 +#include +#include +#include +#include +#include +#include +#include + +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(-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), + 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(address); + + LogPedantic("Created file mapping: " << fileName << + " of size: " << m_size << + " at address: " << std::hex << static_cast(m_address)); +} + +FileInputMapping::~FileInputMapping() +{ + // Close mapping + if (munmap(m_address, static_cast(m_size)) == -1) + { + int error = errno; + LogPedantic("Failed to munmap file. errno = " << error); + } + + // Close file descriptor + if (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 diff --git a/modules/core/src/file_output.cpp b/modules/core/src/file_output.cpp new file mode 100644 index 0000000..8b09042 --- /dev/null +++ b/modules/core/src/file_output.cpp @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file file_output.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of file output + */ +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DPL +{ +FileOutput::FileOutput() + : m_fd(-1) +{ +} + +FileOutput::FileOutput(const std::string& fileName) + : m_fd(-1) +{ + Open(fileName); +} + +FileOutput::~FileOutput() +{ + Close(); +} + +void FileOutput::Open(const std::string& fileName) +{ + // Open non-blocking + int fd = TEMP_FAILURE_RETRY(open(fileName.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_NONBLOCK, 0664)); + + // Throw an exception if an error occurred + if (fd == -1) + ThrowMsg(Exception::OpenFailed, fileName); + + // Close if any existing + Close(); + + // Save new descriptor + m_fd = fd; + + LogPedantic("Opened file: " << fileName); +} + +void FileOutput::Close() +{ + if (m_fd == -1) + return; + + if (TEMP_FAILURE_RETRY(close(m_fd)) == -1) + Throw(Exception::CloseFailed); + + m_fd = -1; + + LogPedantic("Closed file"); +} + +size_t FileOutput::Write(const BinaryQueue &buffer, size_t bufferSize) +{ + // Adjust write size + if (bufferSize > buffer.Size()) + bufferSize = buffer.Size(); + + // FIXME: User write visitor to write ! + // WriteVisitor visitor + + ScopedFree flattened(malloc(bufferSize)); + buffer.Flatten(flattened.Get(), bufferSize); + + LogPedantic("Trying to write " << bufferSize << " bytes"); + + ssize_t result = TEMP_FAILURE_RETRY(write(m_fd, flattened.Get(), bufferSize)); + + LogPedantic("Wrote " << result << " bytes to file"); + + if (result > 0) + { + // Successfuly written some bytes + return static_cast(result); + } + else if (result == 0) + { + // This is abnormal result + ThrowMsg(CommonException::InternalError, "Invalid write result, 0 bytes written"); + } + else + { + // Interpret error result + // FIXME: Handle errno + Throw(AbstractOutput::Exception::WriteFailed); + } +} + +WaitableHandle FileOutput::WaitableWriteHandle() const +{ + return static_cast(m_fd); +} +} // namespace DPL diff --git a/modules/core/src/generic_event.cpp b/modules/core/src/generic_event.cpp new file mode 100644 index 0000000..3ad97c4 --- /dev/null +++ b/modules/core/src/generic_event.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/modules/core/src/lexical_cast.cpp b/modules/core/src/lexical_cast.cpp new file mode 100644 index 0000000..1d9ad17 --- /dev/null +++ b/modules/core/src/lexical_cast.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file lexical_cast.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief Implementation file for lexical cast + */ +#include + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/modules/core/src/main.cpp b/modules/core/src/main.cpp new file mode 100644 index 0000000..4e8078c --- /dev/null +++ b/modules/core/src/main.cpp @@ -0,0 +1,484 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file main.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of main for EFL + */ +#include +#include +#include +#include +#include +#include +#include + +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
(data); + (void)fd_handler; + + Assert(This != NULL); + + // Late EFL event handling + if (g_lateMain == NULL) + { + LogPedantic("WARNING: Late EFL invoker dispatch!"); + } + else + { + This->DispatchInvoker(); + } + + return ECORE_CALLBACK_RENEW; +} + +Eina_Bool Main::StaticDispatchReadWatcher(void* data, Ecore_Fd_Handler* fd_handler) +{ + LogPedantic("Static ECORE dispatch read watcher"); + + Main *This = static_cast
(data); + + Assert(This != NULL); + + // Late EFL event handling + if (g_lateMain == NULL) + { + LogPedantic("WARNING: Late EFL read watcher dispatch!"); + } + else + { + This->DispatchReadWatcher(static_cast(ecore_main_fd_handler_fd_get(fd_handler))); + } + + return ECORE_CALLBACK_RENEW; +} + +Eina_Bool Main::StaticDispatchWriteWatcher(void* data, Ecore_Fd_Handler* fd_handler) +{ + LogPedantic("Static ECORE dispatch write watcher"); + + Main *This = static_cast
(data); + + Assert(This != NULL); + + // Late EFL event handling + if (g_lateMain == NULL) + { + LogPedantic("WARNING: Late EFL write watcher dispatch!"); + } + else + { + This->DispatchWriteWatcher(static_cast(ecore_main_fd_handler_fd_get(fd_handler))); + } + + return ECORE_CALLBACK_RENEW; +} + +void Main::DispatchInvoker() +{ + LogPedantic("Dispatching invoker..."); + + // Reload watch list + ReloadWatchList(); + + // Handle base invoker + WaitableHandleWatchSupport::InvokerFinished(); + + LogPedantic("Invoker dispatched"); +} + +void Main::ReloadWatchList() +{ + LogPedantic("Reloading watch list... (" << m_readWatchersList.size() << " + " << m_writeWatchersList.size() << ")"); + + // Reload list of watchers + WaitableHandleListEx waitableWatcherHandles = WaitableHandleWatchSupport::WaitableWatcherHandles(); + + // Remove not existing read watchers + EcoreFdHandlerList::iterator watchersIterator = m_readWatchersList.begin(); + WaitableHandleListEx::iterator handlesIterator; + + while (watchersIterator != m_readWatchersList.end()) + { + bool found = false; + + for (handlesIterator = waitableWatcherHandles.begin(); handlesIterator != waitableWatcherHandles.end(); ++handlesIterator) + { + if (handlesIterator->second == WaitMode::Read && + handlesIterator->first == static_cast(ecore_main_fd_handler_fd_get(*watchersIterator))) + { + found = true; + break; + } + } + + if (!found) + { + // Unregister handler + ecore_main_fd_handler_del(*watchersIterator); + + // Remove iterator + EcoreFdHandlerList::iterator next = watchersIterator; + ++next; + + m_readWatchersList.erase(watchersIterator); + watchersIterator = next; + } + else + { + ++watchersIterator; + } + } + + // Remove not existing write watchers + watchersIterator = m_writeWatchersList.begin(); + + while (watchersIterator != m_writeWatchersList.end()) + { + bool found = false; + + for (handlesIterator = waitableWatcherHandles.begin(); handlesIterator != waitableWatcherHandles.end(); ++handlesIterator) + { + if (handlesIterator->second == WaitMode::Write && + handlesIterator->first == static_cast(ecore_main_fd_handler_fd_get(*watchersIterator))) + { + found = true; + break; + } + } + + if (!found) + { + // Unregister handler + ecore_main_fd_handler_del(*watchersIterator); + + // Remove iterator + EcoreFdHandlerList::iterator next = watchersIterator; + ++next; + + m_writeWatchersList.erase(watchersIterator); + watchersIterator = next; + } + else + { + ++watchersIterator; + } + } + + // Add new read/write watchers + for (handlesIterator = waitableWatcherHandles.begin(); handlesIterator != waitableWatcherHandles.end(); ++handlesIterator) + { + if (handlesIterator->second == WaitMode::Read) + { + bool found = false; + + for (watchersIterator = m_readWatchersList.begin(); watchersIterator != m_readWatchersList.end(); ++watchersIterator) + { + if (handlesIterator->first == static_cast(ecore_main_fd_handler_fd_get(*watchersIterator))) + { + found = true; + break; + } + } + + if (!found) + { + Ecore_Fd_Handler *handler = ecore_main_fd_handler_add(handlesIterator->first, + ECORE_FD_READ, &StaticDispatchReadWatcher, this, NULL, NULL); + if (handler == NULL) + ThrowMsg(Exception::CreateFailed, "Failed to register read watcher handler!"); + + // Push new watcher to list + m_readWatchersList.push_back(handler); + } + } + else if (handlesIterator->second == WaitMode::Write) + { + bool found = false; + + for (watchersIterator = m_writeWatchersList.begin(); watchersIterator != m_writeWatchersList.end(); ++watchersIterator) + { + if (handlesIterator->first == static_cast(ecore_main_fd_handler_fd_get(*watchersIterator))) + { + found = true; + break; + } + } + + if (!found) + { + Ecore_Fd_Handler *handler = ecore_main_fd_handler_add(handlesIterator->first, + ECORE_FD_WRITE, &StaticDispatchWriteWatcher, this, NULL, NULL); + if (handler == NULL) + ThrowMsg(Exception::CreateFailed, "Failed to register write watcher handler!"); + + // Push new watcher to list + m_writeWatchersList.push_back(handler); + } + } + else + { + Assert(0); + } + } + + LogPedantic("Watch list reloaded (" << m_readWatchersList.size() << " + " << m_writeWatchersList.size() << ")"); +} + +void Main::DispatchReadWatcher(WaitableHandle waitableHandle) +{ + LogPedantic("Dispatching read watcher..."); + + // Handle watcher + WaitableHandleWatchSupport::HandleWatcher(waitableHandle, WaitMode::Read); + + LogPedantic("Watcher dispatched"); +} + +void Main::DispatchWriteWatcher(WaitableHandle waitableHandle) +{ + LogPedantic("Dispatching write watcher..."); + + // Handle watcher + WaitableHandleWatchSupport::HandleWatcher(waitableHandle, WaitMode::Write); + + LogPedantic("Watcher dispatched"); +} + +Thread *Main::GetInvokerThread() +{ + return NULL; +} + +void Main::HandleDirectInvoker() +{ + // Handle direct invoker + ReloadWatchList(); +} + +#ifdef DPL_ENABLE_GLIB_LOOP_INTEGRATION_WORKAROUND +// GLIB loop intergration workaround +int Main::EcoreSelectInterceptor(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) +{ +#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 diff --git a/modules/core/src/mutex.cpp b/modules/core/src/mutex.cpp new file mode 100644 index 0000000..7d18eda --- /dev/null +++ b/modules/core/src/mutex.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file mutex.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of mutex + */ +#include +#include +#include +#include + +namespace DPL +{ +Mutex::Mutex() +{ + if (pthread_mutex_init(&m_mutex, NULL) != 0) + { + int error = errno; + + LogPedantic("Failed to create mutex. Errno: " << error); + + ThrowMsg(Exception::CreateFailed, + "Failed to create mutex. Errno: " << error); + } +} + +Mutex::~Mutex() +{ + if (pthread_mutex_destroy(&m_mutex) != 0) + { + int error = errno; + + LogPedantic("Failed to destroy mutex. Errno: " << error); + } +} + +void Mutex::Lock() const +{ + if (pthread_mutex_lock(&m_mutex) != 0) + { + int error = errno; + + LogPedantic("Failed to lock mutex. Errno: " << error); + + ThrowMsg(Exception::LockFailed, + "Failed to lock mutex. Errno: " << error); + } +} + +void Mutex::Unlock() const +{ + if (pthread_mutex_unlock(&m_mutex) != 0) + { + int error = errno; + + LogPedantic("Failed to unlock mutex. Errno: " << error); + + ThrowMsg(Exception::UnlockFailed, + "Failed to unlock mutex. Errno: " << error); + } +} + +Mutex::ScopedLock::ScopedLock(Mutex *mutex) + : m_mutex(mutex) +{ + Assert(mutex != NULL); + m_mutex->Lock(); +} + +Mutex::ScopedLock::~ScopedLock() +{ + Try + { + m_mutex->Unlock(); + } + Catch (Mutex::Exception::UnlockFailed) + { + LogPedantic("Failed to leave mutex scoped lock"); + } +} +} // namespace DPL diff --git a/modules/core/src/named_base_pipe.cpp b/modules/core/src/named_base_pipe.cpp new file mode 100644 index 0000000..6d18bc6 --- /dev/null +++ b/modules/core/src/named_base_pipe.cpp @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file named_base_pipe.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of named base pipe + */ +#include +#include +#include +#include +#include +#include + +namespace DPL +{ +namespace // anonymous +{ +const mode_t FIFO_MODE = 0600; +} // namespace anonymous + +NamedBasePipe::~NamedBasePipe() +{ +} + +void NamedBasePipe::Create(const std::string &pipeName) +{ + // Create new fifo + int status = mkfifo(pipeName.c_str(), FIFO_MODE); + + if (status == -1) + { + // Ignore error it it already exists + if (errno == EEXIST) + ThrowMsg(Exception::AlreadyExist, pipeName); + else + ThrowMsg(Exception::CreateFailed, pipeName); + } +} + +void NamedBasePipe::Destroy(const std::string &fileName) +{ + // Destroy fifo + unlink(fileName.c_str()); // FIXME: Add error handling +} +} // namespace DPL diff --git a/modules/core/src/named_input_pipe.cpp b/modules/core/src/named_input_pipe.cpp new file mode 100644 index 0000000..bda52f2 --- /dev/null +++ b/modules/core/src/named_input_pipe.cpp @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 +#include +#include +#include +#include +#include +#include + +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 diff --git a/modules/core/src/named_output_pipe.cpp b/modules/core/src/named_output_pipe.cpp new file mode 100644 index 0000000..5dd7215 --- /dev/null +++ b/modules/core/src/named_output_pipe.cpp @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file named_output_pipe.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of named output pipe + */ +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DPL +{ +NamedOutputPipe::NamedOutputPipe() + : m_fifo(-1) +{ +} + +NamedOutputPipe::~NamedOutputPipe() +{ + Close(); +} + +void NamedOutputPipe::Open(const std::string& pipeName) +{ + // Then open it for reading or writing + int fifo = TEMP_FAILURE_RETRY(open(pipeName.c_str(), O_WRONLY | O_NONBLOCK)); + + if (fifo == -1) + ThrowMsg(Exception::OpenFailed, pipeName); + + m_fifo = fifo; +} + +void NamedOutputPipe::Close() +{ + if (m_fifo == -1) + return; + + if (TEMP_FAILURE_RETRY(close(m_fifo)) == -1) + Throw(Exception::CloseFailed); + + m_fifo = -1; +} + +size_t NamedOutputPipe::Write(const BinaryQueue &buffer, size_t bufferSize) +{ + // Adjust write size + if (bufferSize > buffer.Size()) + bufferSize = buffer.Size(); + + // FIXME: User write visitor to write ! + // WriteVisitor visitor + + ScopedFree flattened(malloc(bufferSize)); + buffer.Flatten(flattened.Get(), bufferSize); + + ssize_t result = TEMP_FAILURE_RETRY(write(m_fifo, flattened.Get(), bufferSize)); + + if (result > 0) + { + // Successfuly written some bytes + return static_cast(result); + } + else if (result == 0) + { + // This is abnormal result + ThrowMsg(CommonException::InternalError, "Invalid socket write result, 0 bytes written"); + } + else + { + // Interpret error result + // FIXME: Handle errno + Throw(AbstractOutput::Exception::WriteFailed); + } +} + +int NamedOutputPipe::WaitableWriteHandle() const +{ + return m_fifo; +} +} // namespace DPL diff --git a/modules/core/src/noncopyable.cpp b/modules/core/src/noncopyable.cpp new file mode 100644 index 0000000..d0af48a --- /dev/null +++ b/modules/core/src/noncopyable.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file noncopyable.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of noncopyable + */ +#include + +namespace DPL +{ +Noncopyable::Noncopyable() +{ +} + +Noncopyable::~Noncopyable() +{ +} +} // namespace DPL diff --git a/modules/core/src/once.cpp b/modules/core/src/once.cpp new file mode 100644 index 0000000..5ac0c1e --- /dev/null +++ b/modules/core/src/once.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file once.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of once + */ +#include + +namespace DPL +{ +void Once::Call(Delegate delegate) +{ + // First chance test + if (m_atomic == 1) + return; + + // Enter mutex + Mutex::ScopedLock lock(&m_mutex); + + // Second chance test + if (m_atomic == 1) + return; + + // Initialization: call delegate + delegate(); + + // Initialization: done + ++m_atomic; +} +} // namespace DPL diff --git a/modules/core/src/read_write_mutex.cpp b/modules/core/src/read_write_mutex.cpp new file mode 100644 index 0000000..7807f7f --- /dev/null +++ b/modules/core/src/read_write_mutex.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file read_write_mutex.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of read write mutex + */ +#include +#include + +namespace DPL +{ +ReadWriteMutex::ReadWriteMutex() +{ + if (pthread_rwlock_init(&m_rwlock, NULL) != 0) + Throw(Exception::CreateFailed); +} + +ReadWriteMutex::~ReadWriteMutex() +{ + if (pthread_rwlock_destroy(&m_rwlock) != 0) + Throw(Exception::DestroyFailed); +} + +void ReadWriteMutex::ReadLock() const +{ + if (pthread_rwlock_rdlock(&m_rwlock) != 0) + Throw(Exception::ReadLockFailed); +} + +void ReadWriteMutex::WriteLock() const +{ + if (pthread_rwlock_wrlock(&m_rwlock) != 0) + Throw(Exception::WriteLockFailed); +} + +void ReadWriteMutex::Unlock() const +{ + if (pthread_rwlock_unlock(&m_rwlock) != 0) + Throw(Exception::UnlockFailed); +} + +ReadWriteMutex::ScopedReadLock::ScopedReadLock(ReadWriteMutex *mutex) + : m_mutex(mutex) +{ + Assert(mutex != NULL); + m_mutex->ReadLock(); +} + +ReadWriteMutex::ScopedReadLock::~ScopedReadLock() +{ + m_mutex->Unlock(); +} + +ReadWriteMutex::ScopedWriteLock::ScopedWriteLock(ReadWriteMutex *mutex) + : m_mutex(mutex) +{ + Assert(mutex != NULL); + m_mutex->WriteLock(); +} + +ReadWriteMutex::ScopedWriteLock::~ScopedWriteLock() +{ + m_mutex->Unlock(); +} +} // namespace DPL diff --git a/modules/core/src/recursive_mutex.cpp b/modules/core/src/recursive_mutex.cpp new file mode 100644 index 0000000..19e9dea --- /dev/null +++ b/modules/core/src/recursive_mutex.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file recursive_mutex.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of recursive mutex + */ +#include +#include + +namespace DPL +{ +RecursiveMutex::RecursiveMutex() +{ + pthread_mutexattr_t attr; + + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + + if (pthread_mutex_init(&m_mutex, &attr) != 0) + Throw(Exception::CreateFailed); +} + +RecursiveMutex::~RecursiveMutex() +{ + if (pthread_mutex_destroy(&m_mutex) != 0) + Throw(Exception::DestroyFailed); +} + +void RecursiveMutex::Lock() const +{ + if (pthread_mutex_lock(&m_mutex) != 0) + Throw(Exception::LockFailed); +} + +void RecursiveMutex::Unlock() const +{ + if (pthread_mutex_unlock(&m_mutex) != 0) + Throw(Exception::UnlockFailed); +} + +RecursiveMutex::ScopedLock::ScopedLock(RecursiveMutex *mutex) + : m_mutex(mutex) +{ + Assert(mutex != NULL); + m_mutex->Lock(); +} + +RecursiveMutex::ScopedLock::~ScopedLock() +{ + m_mutex->Unlock(); +} +} // namespace DPL diff --git a/modules/core/src/semaphore.cpp b/modules/core/src/semaphore.cpp new file mode 100644 index 0000000..82d53ff --- /dev/null +++ b/modules/core/src/semaphore.cpp @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file semaphore.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of semaphore + */ +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DPL +{ +void Semaphore::Remove(const std::string &fileName) +{ + if (sem_unlink(fileName.c_str()) == -1) { + int error = errno; + LogPedantic("Failed to unlink semaphore. Errno: " << error); + ThrowMsg(Exception::RemoveFailed, + "Failed to unlink semaphore. Errno: " << error); + } +} + +Semaphore::Semaphore(size_t maxLockCount) +{ + LogPedantic("Allocating unnamed semaphore:"); + LogPedantic(" Maximum lock count: " << maxLockCount); + + if (-1 == sem_init(&m_semaphore.unnamed.handle, + 0, + static_cast(maxLockCount))) + { + int error = errno; + + LogPedantic("Failed to create semaphore. Errno: " << error); + + ThrowMsg(Exception::CreateFailed, + "Failed to create semaphore. Errno: " << error); + } + + m_type = Type_Unnamed; +} + +Semaphore::Semaphore(const std::string &fileName, + bool allowCreate, + bool exclusiveCreate, + size_t maxLockCount, + int permissions, + bool unlinkOnDestroy) +{ + LogPedantic("Allocating named semaphore:"); + LogPedantic(" File name: " << fileName); + LogPedantic(" Maximum lock count: " << maxLockCount); + LogPedantic(" File name: " << fileName); + LogPedantic(" Allowed create: " << allowCreate); + LogPedantic(" Exclusive create: " << exclusiveCreate); + LogPedantic(" Permissions: " << permissions); + LogPedantic(" Unlink on destroy: " << unlinkOnDestroy); + + sem_t *semaphore; + + do + { + if (allowCreate) + { + if (exclusiveCreate) + { + semaphore = sem_open(fileName.c_str(), + O_CREAT | O_EXCL, + permissions, + static_cast(maxLockCount)); + } + else + { + semaphore = sem_open(fileName.c_str(), + O_CREAT, + permissions, + static_cast(maxLockCount)); + } + } + else + { + semaphore = sem_open(fileName.c_str(), 0); + } + } + while (semaphore == SEM_FAILED && errno == EINTR); + + if (semaphore == SEM_FAILED) + { + int error = errno; + + LogPedantic("Failed to create semaphore '" << fileName + << "'. Errno: " << error); + + ThrowMsg(Exception::CreateFailed, + "Failed to create semaphore '" << fileName + << "'. Errno: " << error); + } + + m_semaphore.named.handle = semaphore; + + m_semaphore.named.name = strdup(fileName.c_str()); // May be NULL + + if (m_semaphore.named.name == NULL) + LogPedantic("Out of memory while duplicating semaphore name"); + + m_semaphore.named.unlinkOnDestroy = unlinkOnDestroy; + + m_type = Type_Named; +} + +Semaphore::~Semaphore() +{ + InternalDestroy(); +} + +sem_t *Semaphore::InternalGet() const +{ + switch (m_type) + { + case Type_Unnamed: + return &m_semaphore.unnamed.handle; + + case Type_Named: + return m_semaphore.named.handle; + + default: + Assert(false && "Invalid type"); + } + + return NULL; +} + +void Semaphore::InternalDestroy() +{ + switch (m_type) + { + case Type_Unnamed: + if (sem_destroy(&m_semaphore.unnamed.handle) == -1) + { + int error = errno; + + LogPedantic("Failed to destroy semaphore. Errno: " << error); + } + break; + + case Type_Named: + if (sem_close(m_semaphore.named.handle) == -1) + { + int error = errno; + + LogPedantic("Failed to close semaphore. Errno: " << error); + } + + if (m_semaphore.named.name != NULL) + { + // Unlink named semaphore + if (m_semaphore.named.unlinkOnDestroy && + sem_unlink(m_semaphore.named.name) == -1) + { + int error = errno; + + LogPedantic("Failed to unlink semaphore. Errno: " + << error); + } + + // Free name + free(m_semaphore.named.name); + } + break; + + default: + Assert(false && "Invalid type"); + } +} + +void Semaphore::Lock() const +{ + if (TEMP_FAILURE_RETRY(sem_wait(InternalGet())) != 0) + { + int error = errno; + + LogPedantic("Failed to lock semaphore. Errno: " << error); + + ThrowMsg(Exception::LockFailed, + "Failed to lock semaphore. Errno: " << error); + } +} + +void Semaphore::Unlock() const +{ + if (sem_post(InternalGet()) != 0) + { + int error = errno; + + LogPedantic("Failed to unlock semaphore. Errno: " << error); + + ThrowMsg(Exception::UnlockFailed, + "Failed to unlock semaphore. Errno: " << error); + } +} + +Semaphore::ScopedLock::ScopedLock(Semaphore *semaphore) + : m_semaphore(semaphore) +{ + Assert(semaphore != NULL); + m_semaphore->Lock(); +} + +Semaphore::ScopedLock::~ScopedLock() +{ + Try + { + m_semaphore->Unlock(); + } + Catch (Semaphore::Exception::UnlockFailed) + { + LogPedantic("Failed to leave semaphore scoped lock"); + } +} +} // namespace DPL diff --git a/modules/core/src/serialization.cpp b/modules/core/src/serialization.cpp new file mode 100644 index 0000000..b6e7da8 --- /dev/null +++ b/modules/core/src/serialization.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file serialization.cpp + * @author Tomasz Swierczek (t.swierczek@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of data serialization. + */ +#include + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/modules/core/src/single_instance.cpp b/modules/core/src/single_instance.cpp new file mode 100644 index 0000000..cca8365 --- /dev/null +++ b/modules/core/src/single_instance.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file single_instance.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of single instance + */ +#include +#include +#include +#include +#include +#include + +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 diff --git a/modules/core/src/singleton.cpp b/modules/core/src/singleton.cpp new file mode 100644 index 0000000..a6680f1 --- /dev/null +++ b/modules/core/src/singleton.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file generic_event.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of singleton + */ +#include + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/modules/core/src/string.cpp b/modules/core/src/string.cpp new file mode 100644 index 0000000..d945ebd --- /dev/null +++ b/modules/core/src/string.cpp @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file string.cpp + * @author Piotr Marcinkiewicz (p.marcinkiew@samsung.com) + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// TODO: Completely move to ICU +namespace DPL +{ +namespace //anonymous +{ +class ASCIIValidator +{ + const std::string& m_TestedString; + +public: + ASCIIValidator(const std::string& aTestedString); + + void operator()(char aCharacter) const; +}; + +ASCIIValidator::ASCIIValidator(const std::string& aTestedString) + : m_TestedString(aTestedString) +{ +} + +void ASCIIValidator::operator()(char aCharacter) const +{ + // Check for ASCII data range + if (aCharacter <= 0) + { + ThrowMsg(StringException::InvalidASCIICharacter, + "invalid character code " << static_cast(aCharacter) + << " from string [" << m_TestedString + << "] passed as ASCII"); + } +} + +const iconv_t gc_IconvOperError = reinterpret_cast(-1); +const size_t gc_IconvConvertError = static_cast(-1); +} // namespace anonymous + +String FromUTF8String(const std::string& aIn) +{ + if (aIn.empty()) + + return String(); + + size_t inbytes = aIn.size(); + + // Default iconv UTF-32 module adds BOM (4 bytes) in from of string + // The worst case is when 8bit UTF-8 char converts to 32bit UTF-32 + // newsize = oldsize * 4 + end + bom + // newsize - bytes for UTF-32 string + // oldsize - letters in UTF-8 string + // end - end character for UTF-32 (\0) + // bom - Unicode header in front of string (0xfeff) + size_t outbytes = sizeof(wchar_t)*(inbytes + 2); + std::vector output(inbytes + 2, 0); + + size_t outbytesleft = outbytes; + char* inbuf = const_cast(aIn.c_str()); + + // vector is used to provide buffer for iconv which expects char* buffer + // but during conversion from UTF32 uses internaly wchar_t + char* outbuf = reinterpret_cast(&output[0]); + + iconv_t iconvHandle = iconv_open("UTF-32","UTF-8"); + + if (gc_IconvOperError == iconvHandle) + { + int error = errno; + + ThrowMsg(StringException::IconvInitErrorUTF8ToUTF32, + "iconv_open failed for " << "UTF-32 <- UTF-8" << + "error: " << GetErrnoString(error)); + } + + size_t iconvRet = iconv(iconvHandle, &inbuf, &inbytes, &outbuf, &outbytesleft); + + iconv_close(iconvHandle); + + if (gc_IconvConvertError == iconvRet) + { + ThrowMsg(StringException::IconvConvertErrorUTF8ToUTF32, + "iconv failed for " << "UTF-32 <- UTF-8" << "error: " + << GetErrnoString()); + 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(const_cast(aIn.c_str())); + std::vector output(inbytes, 0); + char* outbuf = &output[0]; + + size_t outbytesleft = outbytes; + + iconv_t iconvHandle = iconv_open("UTF-8","UTF-32"); + + if (gc_IconvOperError == iconvHandle) + { + ThrowMsg(StringException::IconvInitErrorUTF32ToUTF8, + "iconv_open failed for " << "UTF-8 <- UTF-32" + << "error: " << GetErrnoString()); + 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(output)); + + return output; +} + +String FromUTF32String(const std::wstring& aString) +{ + return String(&aString[0]); +} + +static UChar *ConvertToICU(const String &inputString) +{ + ScopedArray outputString; + int32_t size = 0; + int32_t convertedSize = 0; + UErrorCode error = U_ZERO_ERROR; + + // Calculate size of output string + ::u_strFromWCS(NULL, + 0, + &size, + inputString.c_str(), + -1, + &error); + + if (error == U_ZERO_ERROR || + error == U_BUFFER_OVERFLOW_ERROR) + { + // What buffer size is ok ? + LogPedantic("ICU: Output buffer size: " << size); + } + else + { + ThrowMsg(StringException::ICUInvalidCharacterFound, + "ICU: Failed to retrieve output string size. Error: " + << error); + } + + // Allocate proper buffer + outputString.Reset(new UChar[size + 1]); + ::memset(outputString.Get(), 0, sizeof(UChar) * (size + 1)); + + error = U_ZERO_ERROR; + + // Do conversion + ::u_strFromWCS(outputString.Get(), + size + 1, + &convertedSize, + inputString.c_str(), + -1, + &error); + + if (!U_SUCCESS(error)) + { + ThrowMsg(StringException::ICUInvalidCharacterFound, + "ICU: Failed to convert string. Error: " << error); + } + + // Done + return outputString.Release(); +} + +int StringCompare(const String &left, + const String &right, + bool caseInsensitive) +{ + // Convert input strings + ScopedArray leftICU(ConvertToICU(left)); + ScopedArray rightICU(ConvertToICU(right)); + + if (caseInsensitive) + { + return static_cast(u_strcasecmp(leftICU.Get(), rightICU.Get(), 0)); + } + else + { + return static_cast(u_strcmp(leftICU.Get(), rightICU.Get())); + } +} +} //namespace DPL + +std::ostream& operator<<(std::ostream& aStream, const DPL::String& aString) +{ + return aStream << DPL::ToUTF8String(aString); +} diff --git a/modules/core/src/task.cpp b/modules/core/src/task.cpp new file mode 100644 index 0000000..a8f18a4 --- /dev/null +++ b/modules/core/src/task.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/modules/core/src/task_list.cpp b/modules/core/src/task_list.cpp new file mode 100644 index 0000000..89e0ff8 --- /dev/null +++ b/modules/core/src/task_list.cpp @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 +#include + +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(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 diff --git a/modules/core/src/thread.cpp b/modules/core/src/thread.cpp new file mode 100644 index 0000000..ec7166a --- /dev/null +++ b/modules/core/src/thread.cpp @@ -0,0 +1,559 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file thread.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of thread + */ +#include +#include +#include +#include +#include +#include +#include + +namespace // anonymous +{ +static const size_t NANOSECONDS_PER_SECOND = + static_cast(1000 * 1000 * 1000); + +static const size_t NANOSECONDS_PER_MILISECOND = + static_cast(1000 * 1000); + +static const size_t NANOSECONDS_PER_MICROSECOND = + static_cast(1000); + +static const pthread_t g_mainThread = pthread_self(); + +class ThreadSpecific +{ +public: + pthread_key_t threadSpecific; + + ThreadSpecific() + : threadSpecific(0) + { + threadSpecific=0; + pthread_key_create(&threadSpecific, NULL); + } + + virtual ~ThreadSpecific() + { + pthread_key_delete(threadSpecific); + } +}; + +static ThreadSpecific g_threadSpecific; +} // namespace anonymous + +namespace DPL +{ +bool g_TLSforMainCreated = false; + +Thread::Thread() + : m_thread(0), + m_abandon(false), + m_running(false), + m_directInvoke(false) +{ +} + +Thread::~Thread() +{ + // Ensure that we quit thread + // Always wait thread by yourself; if thread is still running + // this may be sometimes very bad. When derived, some resources + // may leak or be doubly freed + Quit(); + + // Remove any remainig events + // Thread proc is surely not running now + for (InternalEventList::iterator iterator = m_eventList.begin(); iterator != m_eventList.end(); ++iterator) + iterator->eventDeleteProc(iterator->event, iterator->userParam); + + m_eventList.clear(); +} + +Thread *Thread::GetCurrentThread() +{ + if (pthread_equal(pthread_self(), g_mainThread)) + return NULL; + + void *threadSpecific = pthread_getspecific(g_threadSpecific.threadSpecific); + + // Is this a managed thread ? + if (threadSpecific == NULL) + Throw(Exception::UnmanagedThread); + + return static_cast(threadSpecific); +} + +void *Thread::StaticThreadEntry(void *param) +{ + LogPedantic("Entered static thread entry"); + + // Retrieve context + Thread *This = static_cast(param); + Assert(This != NULL); + + // Set thread specific + 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(tv.tv_sec) * 1000 + static_cast(tv.tv_usec) / 1000; +} + +int Thread::Exec() +{ + LogPedantic("Executing thread event processing"); + + const std::size_t MIN_HANDLE_LIST_SIZE = 4; + + // Start processing of events + WaitableHandleListEx handleList; + + // index 0: Quit waitable event handle + handleList.push_back(std::make_pair(m_quitEvent.GetHandle(), WaitMode::Read)); + + // index 1: Event occurred event handle + handleList.push_back(std::make_pair(m_eventInvoker.GetHandle(), WaitMode::Read)); + + // index 2: Timed event occurred event handle + handleList.push_back(std::make_pair(m_timedEventInvoker.GetHandle(), WaitMode::Read)); + + // index 3: Waitable handle watch support invoker + handleList.push_back(std::make_pair(WaitableHandleWatchSupport::WaitableInvokerHandle(), WaitMode::Read)); + + // + // Watch list might have been initialized before threaded started + // Need to fill waitable event watch list in this case + // + { + WaitableHandleListEx waitableHandleWatchHandles = WaitableHandleWatchSupport::WaitableWatcherHandles(); + std::copy(waitableHandleWatchHandles.begin(), waitableHandleWatchHandles.end(), std::back_inserter(handleList)); + } + + // Quit flag + bool quit = false; + + while (!quit) + { + // Retrieve minimum wait time, according to timed events list + unsigned long minimumWaitTime; + + // Critical section on timed events mutex + { + Mutex::ScopedLock lock(&m_timedEventMutex); + + if (!m_timedEventVector.empty()) + { + unsigned long currentTimeMiliseconds = GetCurrentTimeMiliseconds(); + unsigned long destinationTimeMiliseconds = m_timedEventVector.begin()->registerTimeMiliseconds + m_timedEventVector.begin()->dueTimeMiliseconds; + + // Are we already late with timed event ? + if (currentTimeMiliseconds > destinationTimeMiliseconds) + minimumWaitTime = 0; + else + minimumWaitTime = destinationTimeMiliseconds - currentTimeMiliseconds; + } + else + minimumWaitTime = 0xFFFFFFFF; // Infinity + } + + // Info + LogPedantic("Thread loop minimum wait time: " << minimumWaitTime << " ms"); + + // Do thread waiting + WaitableHandleIndexList waitableHandleIndexList = WaitForMultipleHandles(handleList, minimumWaitTime); + + if (waitableHandleIndexList.empty()) + { + // Timeout occurred. Process timed events. + LogPedantic("Timed event list elapsed invoker"); + ProcessTimedEvents(); + continue; + } + + // Go through each index + for (WaitableHandleIndexList::const_iterator waitableHandleIndexIterator = waitableHandleIndexList.begin(); + waitableHandleIndexIterator != waitableHandleIndexList.end(); + ++waitableHandleIndexIterator) + { + size_t index = *waitableHandleIndexIterator; + + LogPedantic("Event loop triggered with index: " << index); + + switch (index) + { + case 0: + // Quit waitable event handle + quit = true; + break; + + case 1: + // Event occurred event handle + ProcessEvents(); + + // Handle direct invoker + if (m_directInvoke) + { + m_directInvoke = false; + + LogPedantic("Handling direct invoker"); + + // Update list + while (handleList.size() > MIN_HANDLE_LIST_SIZE) + handleList.pop_back(); + + // Insert current waitable event handles instead + { + WaitableHandleListEx waitableHandleWatchHandles = WaitableHandleWatchSupport::WaitableWatcherHandles(); + std::copy(waitableHandleWatchHandles.begin(), waitableHandleWatchHandles.end(), std::back_inserter(handleList)); + } + } + + // Done + break; + + case 2: + // Timed event list changed + LogPedantic("Timed event list changed invoker"); + ProcessTimedEvents(); + + // Reset timed event invoker + m_timedEventInvoker.Reset(); + + // Done + break; + + case 3: + // Waitable handle watch support invoker + LogPedantic("Waitable handle watch invoker event occurred"); + + // First, remove all previous handles + while (handleList.size() > MIN_HANDLE_LIST_SIZE) + handleList.pop_back(); + + // Insert current waitable event handles instead + { + WaitableHandleListEx waitableHandleWatchHandles = WaitableHandleWatchSupport::WaitableWatcherHandles(); + std::copy(waitableHandleWatchHandles.begin(), waitableHandleWatchHandles.end(), std::back_inserter(handleList)); + } + + // Handle invoker in waitable watch support + WaitableHandleWatchSupport::InvokerFinished(); + + LogPedantic("Waitable handle watch invoker event handled"); + + // Done + break; + + default: + // Waitable event watch list + LogPedantic("Waitable handle watch event occurred"); + + // Handle event in waitable handle watch + { + std::pair handle = handleList[index]; + WaitableHandleWatchSupport::HandleWatcher(handle.first, handle.second); + } + + if (m_directInvoke) + { + m_directInvoke = false; + + LogPedantic("Handling direct invoker"); + + // Update list + while (handleList.size() > MIN_HANDLE_LIST_SIZE) + handleList.pop_back(); + + // Insert current waitable event handles instead + { + WaitableHandleListEx waitableHandleWatchHandles = + WaitableHandleWatchSupport:: + WaitableWatcherHandles(); + std::copy(waitableHandleWatchHandles.begin(), + waitableHandleWatchHandles.end(), + std::back_inserter(handleList)); + } + } + + LogPedantic("Waitable handle watch event handled"); + + // Done + break; + } + } + } + + LogPedantic("Leaving thread event processing"); + return 0; +} + +void Thread::Run() +{ + LogPedantic("Running thread"); + + // Critical section + { + Mutex::ScopedLock lock(&m_stateMutex); + + if (m_running) + return; + + // Try to create new thread + if (pthread_create(&m_thread, NULL, &StaticThreadEntry, this) != 0) + Throw(Exception::RunFailed); + + // At default, we abandon thread + m_abandon = true; + + // Enter running state + m_running = true; + } + + LogPedantic("Thread run"); +} + +void Thread::Quit() +{ + pthread_t joinableThread; + + // Critical section + { + Mutex::ScopedLock lock(&m_stateMutex); + + // Is thread running ? + if (!m_running) + return; + + LogPedantic("Quitting thread..."); + + // Do not abandon thread, we will join + m_abandon = false; + + // Singal quit waitable event + m_quitEvent.Signal(); + + // Copy joinable thread identifier, because + // we are leaving critical section + joinableThread = m_thread; + } + + // Wait for joinable thread + void *result; + + if (pthread_join(joinableThread, &result) != 0) + Throw(Exception::QuitFailed); + + LogPedantic("Thread quit"); +} + +void Thread::PushEvent(void *event, EventDispatchProc eventDispatchProc, EventDeleteProc eventDeleteProc, void *userParam) +{ + // Enter event list critical section + Mutex::ScopedLock lock(&m_eventMutex); + + // Push new event + m_eventList.push_back(InternalEvent(event, userParam, eventDispatchProc, eventDeleteProc)); + + // Trigger invoker + m_eventInvoker.Signal(); + + LogPedantic("Event pushed and invoker signaled"); +} + +void Thread::PushTimedEvent(void *event, double dueTimeSeconds, EventDispatchProc eventDispatchProc, EventDeleteProc eventDeleteProc, void *userParam) +{ + // Check for developer errors + Assert(dueTimeSeconds >= 0.0); + + // Enter timed event list critical section + Mutex::ScopedLock lock(&m_timedEventMutex); + + // Get current time + unsigned long currentTimeMiliseconds = GetCurrentTimeMiliseconds(); + + // Convert to miliseconds + unsigned long dueTimeMiliseconds = static_cast(1000.0 * dueTimeSeconds); + + // Push new timed event + m_timedEventVector.push_back(InternalTimedEvent(event, userParam, dueTimeMiliseconds, currentTimeMiliseconds, eventDispatchProc, eventDeleteProc)); + + // Heapify timed events + std::make_heap(m_timedEventVector.begin(), m_timedEventVector.end()); + + // Trigger invoker + m_timedEventInvoker.Signal(); + + LogPedantic("Timed event pushed and invoker signaled: due time: " << dueTimeMiliseconds << " ms, absolute due time: " << currentTimeMiliseconds + dueTimeMiliseconds << " ms"); +} + +Thread *Thread::GetInvokerThread() +{ + return this; +} + +void Thread::HandleDirectInvoker() +{ + // We must be in ProcessEvents call stack + // Mark that situation to handle direct invoker + m_directInvoke = true; +} + +void Thread::Sleep(uint64_t seconds) +{ + NanoSleep(seconds * NANOSECONDS_PER_SECOND); +} + +void Thread::MiliSleep(uint64_t miliseconds) +{ + NanoSleep(miliseconds * NANOSECONDS_PER_MILISECOND); +} + +void Thread::MicroSleep(uint64_t microseconds) +{ + NanoSleep(microseconds * NANOSECONDS_PER_MICROSECOND); +} + +void Thread::NanoSleep(uint64_t nanoseconds) +{ + timespec requestedTime = + { + static_cast( + nanoseconds / NANOSECONDS_PER_SECOND), + + static_cast( + nanoseconds % NANOSECONDS_PER_SECOND) + }; + + timespec remainingTime; + + for (;;) + { + if (nanosleep(&requestedTime, &remainingTime) == 0) + break; + + int error = errno; + Assert(error == EINTR); + + requestedTime = remainingTime; + } +} +} // namespace DPL diff --git a/modules/core/src/type_list.cpp b/modules/core/src/type_list.cpp new file mode 100644 index 0000000..8eeb106 --- /dev/null +++ b/modules/core/src/type_list.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file type_list.cpp + * @author Bartosz Janiak (b.janiak@samsung.com) + * @version 1.0 + * @brief Generic type list template + */ +#include + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/modules/core/src/union_cast.cpp b/modules/core/src/union_cast.cpp new file mode 100644 index 0000000..b79b622 --- /dev/null +++ b/modules/core/src/union_cast.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file union_cast.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief Implementation file for union cast + */ +#include + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/modules/core/src/waitable_event.cpp b/modules/core/src/waitable_event.cpp new file mode 100644 index 0000000..6bb021c --- /dev/null +++ b/modules/core/src/waitable_event.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file waitable_event.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of waitable event + */ +#include +#include +#include +#include +#include +#include + +namespace DPL +{ +WaitableEvent::WaitableEvent() +{ + if (pipe(m_pipe) == -1) + Throw(Exception::CreateFailed); + + if (fcntl(m_pipe[0], F_SETFL, O_NONBLOCK | fcntl(m_pipe[0], F_GETFL)) == -1) + Throw(Exception::CreateFailed); +} + +WaitableEvent::~WaitableEvent() +{ + if (TEMP_FAILURE_RETRY(close(m_pipe[0])) == -1) + Throw(Exception::DestroyFailed); + + if (TEMP_FAILURE_RETRY(close(m_pipe[1])) == -1) + Throw(Exception::DestroyFailed); +} + +WaitableHandle WaitableEvent::GetHandle() const +{ + return m_pipe[0]; +} + +void WaitableEvent::Signal() const +{ + char data = 0; + + if (TEMP_FAILURE_RETRY(write(m_pipe[1], &data, 1)) != 1) + Throw(Exception::SignalFailed); +} + +void WaitableEvent::Reset() const +{ + char data; + + if (TEMP_FAILURE_RETRY(read(m_pipe[0], &data, 1)) != 1) + Throw(Exception::ResetFailed); +} +} // namespace DPL diff --git a/modules/core/src/waitable_handle.cpp b/modules/core/src/waitable_handle.cpp new file mode 100644 index 0000000..faaea42 --- /dev/null +++ b/modules/core/src/waitable_handle.cpp @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file waitable_handle.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of waitable handle + */ +#include +#include +#include +#include +#include +#include +#include +#include + +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 diff --git a/modules/core/src/waitable_handle_watch_support.cpp b/modules/core/src/waitable_handle_watch_support.cpp new file mode 100644 index 0000000..19c10e7 --- /dev/null +++ b/modules/core/src/waitable_handle_watch_support.cpp @@ -0,0 +1,346 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file waitable_handle_watch_support.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of waitable handle watch support + */ +#include +#include +#include +#include +#include +#include + +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 diff --git a/modules/core/src/zip_input.cpp b/modules/core/src/zip_input.cpp new file mode 100644 index 0000000..d862c01 --- /dev/null +++ b/modules/core/src/zip_input.cpp @@ -0,0 +1,622 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file zip_input.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of zip input + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 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(opaque); + + // Open file for master device + return new File(device); + } + + static uLong ZCALLBACK read_file(voidpf opaque, + voidpf pstream, + void* buf, + uLong size) + { + Device *device = static_cast(opaque); + File *deviceFile = static_cast(pstream); + + // Check if offset is out of bounds + if (deviceFile->offset >= device->m_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(size) > bytesLeft) + bytesToRead = bytesLeft; + else + bytesToRead = static_cast(size); + + // Do copy + memcpy(buf, + device->m_fileMapping->GetAddress() + deviceFile->offset, + static_cast(bytesToRead)); + + // Increment file offset + deviceFile->offset += bytesToRead; + + // Return bytes that were actually read + return static_cast(bytesToRead); + } + + static uLong ZCALLBACK write_file(voidpf opaque, + voidpf stream, + const void* buf, + uLong size) + { + (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(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(stream); + + return static_cast(deviceFile->offset); + } + + static long ZCALLBACK seek64_file(voidpf opaque, + voidpf stream, + ZPOS64_T offset, + int origin) + { + Device *device = static_cast(opaque); + File *deviceFile = static_cast(stream); + + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_SET: + deviceFile->offset = static_cast(offset); + + break; + + case ZLIB_FILEFUNC_SEEK_CUR: + deviceFile->offset += static_cast(offset); + + break; + + case ZLIB_FILEFUNC_SEEK_END: + deviceFile->offset = + device->m_fileMapping->GetSize() - + static_cast(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(new Device(fileName)); + + // Open master file + zlib_filefunc64_def interface; + interface.zopen64_file = &Device::open64_file; + interface.zread_file = &Device::read_file; + interface.zwrite_file = &Device::write_file; + interface.ztell64_file = &Device::tell64_file; + interface.zseek64_file = &Device::seek64_file; + interface.zclose_file = &Device::close_file; + interface.zerror_file = &Device::testerror_file; + interface.opaque = device.Get(); + + LogPedantic("Opening zip file"); + unzFile file = unzOpen2_64(NULL, &interface); + + if (file == NULL) + { + LogPedantic("Failed to open zip file"); + + // Some errror occured + ThrowMsg(Exception::OpenFailed, + "Failed to open zip file: " << fileName); + } + + // Begin scope + ScopedUnzClose scopedUnzClose(file); + + // Read contents + ReadGlobalInfo(file); + ReadGlobalComment(file); + ReadInfos(file); + + // Release scoped unz close + m_masterFile = scopedUnzClose.Release(); + m_device = device.Release(); + + LogPedantic("Zip file opened"); +} + +ZipInput::~ZipInput() +{ + // Close zip + if (unzClose(static_cast(m_masterFile)) != UNZ_OK) + LogPedantic("Failed to close zip input file"); + + // Close device + delete m_device; +} + +void ZipInput::ReadGlobalInfo(void *masterFile) +{ + // Read number of entries and global comment + unz_global_info globalInfo; + + if (unzGetGlobalInfo(static_cast(masterFile), + &globalInfo) != UNZ_OK) + { + LogPedantic("Failed to read zip global info"); + + ThrowMsg(Exception::ReadGlobalInfoFailed, + "Failed to read global info"); + } + + m_numberOfFiles = static_cast(globalInfo.number_entry); + m_globalCommentSize = static_cast(globalInfo.size_comment); + + LogPedantic("Number of files: " << m_numberOfFiles); + LogPedantic("Global comment size: " << m_globalCommentSize); +} + +void ZipInput::ReadGlobalComment(void *masterFile) +{ + ScopedArray comment(new char[m_globalCommentSize + 1]); + + if (unzGetGlobalComment(static_cast(masterFile), + comment.Get(), + m_globalCommentSize + 1) != UNZ_OK) + { + LogPedantic("Failed to read zip global comment"); + + ThrowMsg(Exception::ReadGlobalCommentFailed, + "Failed to read global comment"); + } + + m_globalComment = comment.Get(); + LogPedantic("Global comment: " << m_globalComment); +} + +void ZipInput::ReadInfos(void *masterFile) +{ + // Read infos + m_fileInfos.reserve(m_numberOfFiles); + + if (unzGoToFirstFile(static_cast(masterFile)) != UNZ_OK) + { + LogPedantic("Failed to go to first file"); + ThrowMsg(Exception::SeekFileFailed, "Failed to seek first file"); + } + + for (size_t i = 0; i < m_numberOfFiles; ++i) + { + unz_file_pos_s filePos; + + if (unzGetFilePos(static_cast(masterFile), + &filePos) != UNZ_OK) + { + LogPedantic("Failed to get file pos"); + ThrowMsg(Exception::FileInfoFailed, "Failed to get zip file info"); + } + + unz_file_info64 fileInfo; + + if (unzGetCurrentFileInfo64(static_cast(masterFile), + &fileInfo, + NULL, + 0, + NULL, + 0, + NULL, + 0) != UNZ_OK) + { + LogPedantic("Failed to get file pos"); + ThrowMsg(Exception::FileInfoFailed, "Failed to get zip file info"); + } + + ScopedArray fileName(new char[fileInfo.size_filename + 1]); + ScopedArray fileComment(new char[fileInfo.size_file_comment + 1]); + + if (unzGetCurrentFileInfo64(static_cast(masterFile), + &fileInfo, + fileName.Get(), + fileInfo.size_filename + 1, + NULL, + 0, + fileComment.Get(), + fileInfo.size_file_comment + 1) != UNZ_OK) + { + LogPedantic("Failed to get file pos"); + ThrowMsg(Exception::FileInfoFailed, "Failed to get zip file info"); + } + + m_fileInfos.push_back( + FileInfo( + FileHandle( + static_cast(filePos.pos_in_zip_directory), + static_cast(filePos.num_of_file) + ), + std::string(fileName.Get()), + std::string(fileComment.Get()), + static_cast(fileInfo.version), + static_cast(fileInfo.version_needed), + static_cast(fileInfo.flag), + static_cast(fileInfo.compression_method), + static_cast(fileInfo.dosDate), + static_cast(fileInfo.crc), + static_cast(fileInfo.compressed_size), + static_cast(fileInfo.uncompressed_size), + static_cast(fileInfo.disk_num_start), + static_cast(fileInfo.internal_fa), + static_cast(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(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(handle.first), + static_cast(handle.second) + }; + + if (unzGoToFilePos64(file, &filePos) != UNZ_OK) + { + LogPedantic("Failed to seek to zip file"); + + // Some errror occured + ThrowMsg(ZipInput::Exception::OpenFileFailed, + "Failed to 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(m_file)) != UNZ_OK) + LogPedantic("Failed to close current zip input file"); + + // Close zip file + if (unzClose(static_cast(m_file)) != UNZ_OK) + LogPedantic("Failed to close zip input file"); +} + +DPL::BinaryQueueAutoPtr ZipInput::File::Read(size_t size) +{ + // Do not even try to unzip if requested zero bytes + if (size == 0) + return DPL::BinaryQueueAutoPtr(new DPL::BinaryQueue()); + + // Calc data to read + size_t sizeToRead = size > EXTRACT_BUFFER_SIZE ? + EXTRACT_BUFFER_SIZE : + size; + + // Extract zip file data (one-copy) + ScopedFree rawBuffer(malloc(sizeToRead)); + + if (!rawBuffer) + throw std::bad_alloc(); + + // Do unpack + int bytes = unzReadCurrentFile(static_cast(m_file), + rawBuffer.Get(), + sizeToRead); + + // Internal unzipper error + if (bytes < 0) + { + LogPedantic("Extract failed. Error: " << bytes); + + ThrowMsg(ZipInput::Exception::ReadFileFailed, + "Failed to extract file with error: " << bytes); + } + + // Data was read (may be zero bytes) + DPL::BinaryQueueAutoPtr buffer(new DPL::BinaryQueue()); + + buffer->AppendUnmanaged(rawBuffer.Get(), + static_cast(bytes), + &DPL::BinaryQueue::BufferDeleterFree, + NULL); + + rawBuffer.Release(); + + return buffer; +} + +const std::string &ZipInput::GetGlobalComment() const +{ + return m_globalComment; +} + +bool ZipInput::empty() const +{ + return m_fileInfos.empty(); +} +} // namespace DPL diff --git a/modules/db/config.cmake b/modules/db/config.cmake new file mode 100644 index 0000000..96ccbb9 --- /dev/null +++ b/modules/db/config.cmake @@ -0,0 +1,45 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# @file config.cmake +# @author Lukasz Marek (l.marek@samsung.com) +# @version 1.0 +# @brief +# + +SET(DPL_DB_SOURCES + ${PROJECT_SOURCE_DIR}/modules/db/src/naive_synchronization_object.cpp + ${PROJECT_SOURCE_DIR}/modules/db/src/orm.cpp + ${PROJECT_SOURCE_DIR}/modules/db/src/sql_connection.cpp + ${PROJECT_SOURCE_DIR}/modules/db/src/thread_database_support.cpp + PARENT_SCOPE +) + + +SET(DPL_DB_HEADERS + ${PROJECT_SOURCE_DIR}/modules/db/include/dpl/db/naive_synchronization_object.h + ${PROJECT_SOURCE_DIR}/modules/db/include/dpl/db/orm_generator.h + ${PROJECT_SOURCE_DIR}/modules/db/include/dpl/db/orm.h + ${PROJECT_SOURCE_DIR}/modules/db/include/dpl/db/orm_interface.h + ${PROJECT_SOURCE_DIR}/modules/db/include/dpl/db/orm_macros.h + ${PROJECT_SOURCE_DIR}/modules/db/include/dpl/db/sql_connection.h + ${PROJECT_SOURCE_DIR}/modules/db/include/dpl/db/thread_database_support.h + PARENT_SCOPE +) + +SET(DPL_DB_INCLUDE_DIR + ${PROJECT_SOURCE_DIR}/modules/db/include + PARENT_SCOPE +) diff --git a/modules/db/include/dpl/db/naive_synchronization_object.h b/modules/db/include/dpl/db/naive_synchronization_object.h new file mode 100644 index 0000000..37d268c --- /dev/null +++ b/modules/db/include/dpl/db/naive_synchronization_object.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file naive_synchronization_object.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of SQL naive synchronization object + */ +#ifndef DPL_NAIVE_SYNCHRONIZATION_OBJECT_H +#define DPL_NAIVE_SYNCHRONIZATION_OBJECT_H + +#include + +namespace DPL +{ +namespace DB +{ + +/** + * Naive synchronization object used to synchronize SQL connection + * to the same database across different threads and processes + */ +class NaiveSynchronizationObject + : public SqlConnection::SynchronizationObject +{ +public: + // [SqlConnection::SynchronizationObject] + virtual void Synchronize(); + virtual void NotifyAll(); +}; + +} // namespace DB +} // namespace DPL + +#endif // DPL_NAIVE_SYNCHRONIZATION_OBJECT_H diff --git a/modules/db/include/dpl/db/orm.h b/modules/db/include/dpl/db/orm.h new file mode 100644 index 0000000..f4df084 --- /dev/null +++ b/modules/db/include/dpl/db/orm.h @@ -0,0 +1,704 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file orm.h + * @author Bartosz Janiak (b.janiak@samsung.com) + * @version 1.0 + * @brief DPL-ORM: Object-relational mapping for sqlite database, written on top of DPL. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#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 OptionalString; +typedef DPL::Optional OptionalInteger; +typedef DPL::DB::SqlConnection::DataCommand DataCommand; + +namespace RelationTypes { + extern const char Equal[]; + extern const char LessThan[]; + extern const char And[]; + extern const char Or[]; + extern const char Is[]; + //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 ExpressionPtr; + +template +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 + struct ValidForTable { + typedef std::pair::Yes , + typename RightExpression::template ValidForTable::Yes > + Yes; + }; +}; + +template +BinaryExpression + And(const LeftExpression& leftExpression, const RightExpression& rightExpression) +{ + return BinaryExpression + (leftExpression, rightExpression); +} + +template +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 +class Compare : public ExpressionWithArgument { +public: + explicit Compare(typename ColumnData::ColumnType column) : + ExpressionWithArgument(column) + {} + + virtual std::string GetString() const + { + std::string statement; + statement += ColumnData::GetColumnName(); + statement += " "; + statement += Relation; + statement += " ?"; + return statement; + } + + template + struct ValidForTable { + typedef typename TableDefinition::ColumnList::template Contains Yes; + }; +}; +#define ORM_DEFINE_COMPARE_EXPRESSION(name, relationType) \ + template \ + class name : public Compare { \ + public: \ + name(typename ColumnData::ColumnType column) : \ + Compare(column) \ + {} \ + }; + +ORM_DEFINE_COMPARE_EXPRESSION(Equals, Equal) +ORM_DEFINE_COMPARE_EXPRESSION(Is, Is) + +template +ColumnType GetColumnFromCommand(ColumnIndex columnIndex, DataCommand *command); + +template +class FillRowUtil { +public: + static void FillRow(Row& row, ColumnIndex columnIndex, DataCommand *command) + { + typename ColumnList::Head::ColumnType rowField; + rowField = GetColumnFromCommand(columnIndex, command); + ColumnList::Head::SetRowField(row, rowField); + FillRowUtil::FillRow(row, columnIndex + 1, command); + } +}; + +template +class FillRowUtil { +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 +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 +class QueryWithWhereClause : public Query +{ +protected: + ExpressionPtr m_whereExpression; + + void Prepare() + { + if ( !!m_whereExpression ) + { + this->m_commandString += " WHERE "; + this->m_commandString += m_whereExpression->GetString(); + } + } + + void Bind() + { + if ( !!m_whereExpression ) + { + this->m_bindArgumentIndex = m_whereExpression->BindTo( + this->m_command, this->m_bindArgumentIndex); + } + } + +public: + explicit QueryWithWhereClause(IOrmInterface* interface) : + Query(interface) + { + } + + template + void Where(const Expression& expression) + { + DPL_CHECK_TYPE_INSTANTIABILITY(typename Expression::template ValidForTable::Yes); + if ( !!m_whereExpression && ( typeid(Expression) != typeid(*m_whereExpression) ) ) + { + std::ostringstream str; + str << "Current ORM implementation doesn't allow to reuse Select" + " instance with different query signature (particularly " + "WHERE on different column).\n"; + str << "Query: "; + str << this->m_commandString; + ThrowMsg(Exception::SelectReuseWithDifferentQuerySignature, + str.str()); + } + //TODO maybe don't make a copy here but just generate the string part of the query. + m_whereExpression.Reset(new Expression(expression)); + } + +}; + +template +class Delete : public QueryWithWhereClause +{ +protected: + void Prepare() + { + if ( !this->m_command) + { + this->m_commandString = "DELETE FROM "; + this->m_commandString += TableDefinition::GetName(); + + QueryWithWhereClause::Prepare(); + + this->m_command = TableDefinition::AllocTableDataCommand( + this->m_commandString.c_str(), + Query::m_interface); + LogPedantic("Prepared SQL command " << this->m_commandString); + } + } + + void Bind() + { + this->m_bindArgumentIndex = 1; + QueryWithWhereClause::Bind(); + } + +public: + explicit Delete(IOrmInterface *interface = NULL) : + QueryWithWhereClause(interface) + { + } + + void Execute() + { + Prepare(); + Bind(); + this->m_command->Step(); + this->m_command->Reset(); + } +}; + +template +class Insert : public Query +{ +public: + typedef typename TableDefinition::Row Row; + typedef DPL::DB::SqlConnection::RowID RowID; + +protected: + DPL::Optional m_orClause; + Row m_row; + + class PrepareVisitor { + public: + std::string m_columnNames; + std::string m_values; + + template + void Visit(const char* name, const ColumnType&, bool isSet) + { + if ( isSet ) + { + if ( !m_columnNames.empty() ) + { + m_columnNames += ", "; + m_values += ", "; + } + m_columnNames += name; + m_values += "?"; + } + } + }; + + void Prepare() + { + if ( !this->m_command ) + { + this->m_commandString = "INSERT "; + if ( !!m_orClause ) + { + this->m_commandString += " OR " + *m_orClause + " "; + } + this->m_commandString += "INTO "; + this->m_commandString += TableDefinition::GetName(); + + PrepareVisitor visitor; + m_row.VisitColumns(visitor); + + this->m_commandString += " ( " + visitor.m_columnNames + " ) "; + this->m_commandString += "VALUES ( " + visitor.m_values + " )"; + + LogPedantic("Prepared SQL command " << this->m_commandString); + this->m_command = TableDefinition::AllocTableDataCommand( + this->m_commandString.c_str(), + Query::m_interface); + } + } + + class BindVisitor { + private: + DataCommand *m_command; + ArgumentIndex m_bindArgumentIndex; + public: + BindVisitor(DataCommand *command) : + m_command(command), + m_bindArgumentIndex(1) + {} + + template + void Visit(const char*, const ColumnType& value, bool isSet) + { + if ( isSet ) + { + DataCommandUtils::BindArgument(m_command, m_bindArgumentIndex, value); + m_bindArgumentIndex++; + } + } + }; + + void Bind() + { + BindVisitor visitor(this->m_command); + m_row.VisitColumns(visitor); + } + +public: + explicit Insert( + IOrmInterface* interface = NULL, + const DPL::Optional& orClause = DPL::Optional::Null) : + Query(interface), + m_orClause(orClause) + { + } + + void Values(const Row& row) + { + if ( this->m_command ) + { + if ( !row.IsSignatureMatching(m_row) ) + { + ThrowMsg(Exception::SelectReuseWithDifferentQuerySignature, + "Current ORM implementation doesn't allow to reuse Insert instance " + "with different query signature."); + } + } + m_row = row; + } + + RowID Execute() + { + Prepare(); + Bind(); + this->m_command->Step(); + + RowID result = TableDefinition::GetLastInsertRowID( + Query::m_interface); + + this->m_command->Reset(); + return result; + } +}; + +template +class Select : public QueryWithWhereClause +{ +public: + typedef typename TableDefinition::ColumnList ColumnList; + typedef typename TableDefinition::Row Row; + + typedef std::list RowList; +protected: + DPL::Optional 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::Prepare(); + + if ( !m_orderBy.IsNull() ) + { + this->m_commandString += " ORDER BY " + *m_orderBy; + } + + this->m_command = TableDefinition::AllocTableDataCommand( + this->m_commandString.c_str(), + Query::m_interface); + + LogPedantic("Prepared SQL command " << this->m_commandString); + } + } + + void Bind() + { + this->m_bindArgumentIndex = 1; + QueryWithWhereClause::Bind(); + } + + template + ColumnType GetColumn(ColumnIndex columnIndex) + { + return GetColumnFromCommand(columnIndex, this->m_command); + } + + Row GetRow() + { + Row row; + FillRowUtil::FillRow(row, 0, this->m_command); + return row; + } + +public: + + explicit Select(IOrmInterface *interface = NULL) : + QueryWithWhereClause(interface), + m_distinctResults(false) + { + } + + void Distinct() + { + m_distinctResults = true; + } + + void OrderBy(const std::string& orderBy) + { + m_orderBy = orderBy; + } + + template + typename ColumnData::ColumnType GetSingleValue() + { + Prepare(ColumnData::GetColumnName()); + Bind(); + this->m_command->Step(); + + typename ColumnData::ColumnType result = + GetColumn(0); + + this->m_command->Reset(); + return result; + } + + //TODO return range - pair of custom iterators + template + std::list GetValueList() + { + Prepare(ColumnData::GetColumnName()); + Bind(); + + std::list resultList; + + while (this->m_command->Step()) + resultList.push_back(GetColumn(0)); + + this->m_command->Reset(); + return resultList; + } + + Row GetSingleRow() + { + Prepare("*"); + Bind(); + this->m_command->Step(); + + Row result = GetRow(); + + this->m_command->Reset(); + return result; + } + + //TODO return range - pair of custom iterators + RowList GetRowList() + { + Prepare("*"); + Bind(); + + RowList resultList; + + while (this->m_command->Step()) + resultList.push_back(GetRow()); + + this->m_command->Reset(); + return resultList; + } +}; + +template +class Update : public QueryWithWhereClause { +public: + typedef typename TableDefinition::Row Row; + +protected: + DPL::Optional m_orClause; + Row m_row; + + class PrepareVisitor { + public: + std::string m_setExpressions; + + template + void Visit(const char* name, const ColumnType&, bool isSet) + { + if ( isSet ) + { + if ( !m_setExpressions.empty() ) + { + m_setExpressions += ", "; + } + m_setExpressions += name; + m_setExpressions += " = "; + m_setExpressions += "?"; + } + } + }; + + void Prepare() + { + if ( !this->m_command ) + { + this->m_commandString = "UPDATE "; + if ( !!m_orClause ) + { + this->m_commandString += " OR " + *m_orClause + " "; + } + this->m_commandString += TableDefinition::GetName(); + this->m_commandString += " SET "; + + // got through row columns and values + PrepareVisitor visitor; + m_row.VisitColumns(visitor); + + if(visitor.m_setExpressions.empty()) + { + ThrowMsg(Exception::EmptyUpdateStatement, "No SET expressions in update statement"); + } + + this->m_commandString += visitor.m_setExpressions; + + // where + QueryWithWhereClause::Prepare(); + + this->m_command = TableDefinition::AllocTableDataCommand( + this->m_commandString.c_str(), + Query::m_interface); + LogPedantic("Prepared SQL command " << this->m_commandString); + } + } + + class BindVisitor { + private: + DataCommand *m_command; + + public: + ArgumentIndex m_bindArgumentIndex; + + BindVisitor(DataCommand *command) : + m_command(command), + m_bindArgumentIndex(1) + {} + + template + void Visit(const char*, const ColumnType& value, bool isSet) + { + if ( isSet ) + { + DataCommandUtils::BindArgument(m_command, m_bindArgumentIndex, value); + m_bindArgumentIndex++; + } + } + }; + + void Bind() + { + BindVisitor visitor(this->m_command); + m_row.VisitColumns(visitor); + + this->m_bindArgumentIndex = visitor.m_bindArgumentIndex; + QueryWithWhereClause::Bind(); + } + + +public: + explicit Update(IOrmInterface *interface = NULL, + const DPL::Optional& orClause = DPL::Optional::Null) : + QueryWithWhereClause(interface), + m_orClause(orClause) + { + } + + void Values(const Row& row) + { + if ( this->m_command ) + { + if ( !row.IsSignatureMatching(m_row) ) + { + ThrowMsg(Exception::SelectReuseWithDifferentQuerySignature, + "Current ORM implementation doesn't allow to reuse Update instance " + "with different query signature."); + } + } + m_row = row; + } + + void Execute() + { + Prepare(); + Bind(); + this->m_command->Step(); + this->m_command->Reset(); + } +}; + +} //namespace ORM +} //namespace DB +} //namespace DPL + +#endif // DPL_ORM_H diff --git a/modules/db/include/dpl/db/orm_generator.h b/modules/db/include/dpl/db/orm_generator.h new file mode 100644 index 0000000..61ff9ca --- /dev/null +++ b/modules/db/include/dpl/db/orm_generator.h @@ -0,0 +1,380 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file orm_generator.h + * @author Bartosz Janiak (b.janiak@samsung.com) + * @version 1.0 + * @brief Macro definitions for generating the DPL-ORM table definitions from database definitions. + */ + +#ifndef ORM_GENERATOR_DATABASE_NAME +#error You need to define database name in ORM_GENERATOR_DATABASE_NAME define before you include orm_generator.h file +#endif + +#include + +#define ORM_GENERATOR_DATABASE_NAME_LOCAL + +#ifdef DPL_ORM_GENERATOR_H +#warning orm_generator.h is included multiply times. Make sure it has different ORM_GENERATOR_DATABASE_NAME set. +#endif + +#define DPL_ORM_GENERATOR_H + + +#include +#include +#include +#include +#include +#include +#include + +/* + +This is true only when exactly one db is available. + +#if (defined DECLARE_COLUMN) || (defined INT) || (defined TINYINT) || \ + (defined INTEGER) || (defined BIGINT) || defined(VARCHAR) || defined(TEXT) || \ + (defined SQL) || (defined TABLE_CONSTRAINTS) || (defined OPTIONAL) || \ + (defined DATABASE_START) || (defined DATABASE_END) || (defined CREATE_TABLE) || \ + (defined COLUMN) || (defined COLUMN_NOT_NULL) || (defined CREATE_TABLE_END) + +#error This file temporarily defines many macros with generic names. To avoid name clash please include \ + this file as early as possible. If this is not possible please report this problem to DPL developers. + +#endif +*/ + +namespace DPL { +namespace DB { +namespace ORM { + +// Global macros + +#define STRINGIFY(s) _str(s) +#define _str(s) #s +#define DECLARE_COLUMN(FIELD, TYPE) \ + struct FIELD { \ + typedef TYPE ColumnType; \ + static const char* 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 \ + 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 Select; \ + typedef Insert Insert; \ + typedef Delete Delete; \ + typedef Update 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 diff --git a/modules/db/include/dpl/db/orm_interface.h b/modules/db/include/dpl/db/orm_interface.h new file mode 100644 index 0000000..74908fd --- /dev/null +++ b/modules/db/include/dpl/db/orm_interface.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file orm_interface.h + * @author Lukasz Marek (l.marek@samsung.com) + * @version 1.0 + */ + +#include +#include + +#ifndef DPL_ORM_INTERFACE_H +#define DPL_ORM_INTERFACE_H + +namespace DPL +{ +namespace DB +{ +namespace ORM +{ + +class IOrmInterface +{ + public: + virtual ~IOrmInterface() {} + virtual DPL::DB::SqlConnection::DataCommand *AllocDataCommand(const std::string &statement) = 0; + virtual void FreeDataCommand(DPL::DB::SqlConnection::DataCommand *command) = 0; + virtual void TransactionBegin() = 0; + virtual void TransactionCommit() = 0; + virtual void TransactionRollback() = 0; + virtual DPL::DB::SqlConnection::RowID GetLastInsertRowID() = 0; +}; + +} +} +} + +#endif diff --git a/modules/db/include/dpl/db/orm_macros.h b/modules/db/include/dpl/db/orm_macros.h new file mode 100644 index 0000000..804f59a --- /dev/null +++ b/modules/db/include/dpl/db/orm_macros.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @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() + diff --git a/modules/db/include/dpl/db/sql_connection.h b/modules/db/include/dpl/db/sql_connection.h new file mode 100644 index 0000000..1d032ee --- /dev/null +++ b/modules/db/include/dpl/db/sql_connection.h @@ -0,0 +1,482 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file sql_connection.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of SQL connection + */ +#ifndef DPL_SQL_CONNECTION_H +#define DPL_SQL_CONNECTION_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DPL +{ +namespace DB +{ + +/** + * SQL connection class + */ +class SqlConnection +{ +public: + /** + * SQL Exception classes + */ + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, SyntaxError) + DECLARE_EXCEPTION_TYPE(Base, ConnectionBroken) + DECLARE_EXCEPTION_TYPE(Base, InternalError) + DECLARE_EXCEPTION_TYPE(Base, InvalidColumn) + }; + + typedef int ColumnIndex; + typedef int ArgumentIndex; + + /* + * SQL processed data command + */ + class DataCommand + : private Noncopyable + { + private: + SqlConnection *m_masterConnection; + sqlite3_stmt *m_stmt; + + void CheckBindResult(int result); + void CheckColumnIndex(SqlConnection::ColumnIndex column); + + DataCommand(SqlConnection *connection, const char *buffer); + + friend class SqlConnection; + + public: + virtual ~DataCommand(); + + /** + * Bind null to the prepared statement argument + * + * @param position Index of argument to bind value to + */ + void BindNull(ArgumentIndex position); + + /** + * Bind int to the prepared statement argument + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindInteger(ArgumentIndex position, int value); + + /** + * Bind int8_t to the prepared statement argument + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindInt8(ArgumentIndex position, int8_t value); + + /** + * Bind int16 to the prepared statement argument + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindInt16(ArgumentIndex position, int16_t value); + + /** + * Bind int32 to the prepared statement argument + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindInt32(ArgumentIndex position, int32_t value); + + /** + * Bind int64 to the prepared statement argument + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindInt64(ArgumentIndex position, int64_t value); + + /** + * Bind float to the prepared statement argument + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindFloat(ArgumentIndex position, float value); + + /** + * Bind double to the prepared statement argument + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindDouble(ArgumentIndex position, double value); + + /** + * Bind string to the prepared statement argument + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindString(ArgumentIndex position, const char *value); + + /** + * Bind string to the prepared statement argument + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindString(ArgumentIndex position, const String& value); + + /** + * Bind optional int to the prepared statement argument. + * If optional is not set null will be bound + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindInteger(ArgumentIndex position, const Optional &value); + + /** + * Bind optional int8 to the prepared statement argument. + * If optional is not set null will be bound + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindInt8(ArgumentIndex position, const Optional &value); + + /** + * Bind optional int16 to the prepared statement argument. + * If optional is not set null will be bound + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindInt16(ArgumentIndex position, const Optional &value); + + /** + * Bind optional int32 to the prepared statement argument. + * If optional is not set null will be bound + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindInt32(ArgumentIndex position, const Optional &value); + + /** + * Bind optional int64 to the prepared statement argument. + * If optional is not set null will be bound + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindInt64(ArgumentIndex position, const Optional &value); + + /** + * Bind optional float to the prepared statement argument. + * If optional is not set null will be bound + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindFloat(ArgumentIndex position, const Optional &value); + + /** + * Bind optional double to the prepared statement argument. + * If optional is not set null will be bound + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindDouble(ArgumentIndex position, const Optional &value); + + /** + * Bind optional string to the prepared statement argument. + * If optional is not set null will be bound + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindString(ArgumentIndex position, const Optional &value); + + /** + * Execute the prepared statement and/or move + * to the next row of the result + * + * @return True when there was a row returned + */ + bool Step(); + + /** + * Reset prepared statement's arguments + * All parameters will become null + */ + void Reset(); + + /** + * Checks whether column value is null + * + * @throw Exception::InvalidColumn + */ + bool IsColumnNull(ColumnIndex column); + + /** + * Get integer value from column in current row. + * + * @throw Exception::InvalidColumn + */ + int GetColumnInteger(ColumnIndex column); + + /** + * Get int8 value from column in current row. + * + * @throw Exception::InvalidColumn + */ + int8_t GetColumnInt8(ColumnIndex column); + + /** + * Get int16 value from column in current row. + * + * @throw Exception::InvalidColumn + */ + int16_t GetColumnInt16(ColumnIndex column); + /** + * Get int32 value from column in current row. + * + * @throw Exception::InvalidColumn + */ + int32_t GetColumnInt32(ColumnIndex column); + + /** + * Get int64 value from column in current row. + * + * @throw Exception::InvalidColumn + */ + int64_t GetColumnInt64(ColumnIndex column); + + /** + * Get float value from column in current row. + * + * @throw Exception::InvalidColumn + */ + float GetColumnFloat(ColumnIndex column); + + /** + * Get double value from column in current row. + * + * @throw Exception::InvalidColumn + */ + double GetColumnDouble(ColumnIndex column); + + /** + * Get string value from column in current row. + * + * @throw Exception::InvalidColumn + */ + std::string GetColumnString(ColumnIndex column); + + /** + * Get optional integer value from column in current row. + * + * @throw Exception::InvalidColumn + */ + Optional GetColumnOptionalInteger(ColumnIndex column); + + /** + * Get optional int8 value from column in current row. + * + * @throw Exception::InvalidColumn + */ + Optional GetColumnOptionalInt8(ColumnIndex column); + + /** + * Get optional int16value from column in current row. + * + * @throw Exception::InvalidColumn + */ + Optional GetColumnOptionalInt16(ColumnIndex column); + + /** + * Get optional int32 value from column in current row. + * + * @throw Exception::InvalidColumn + */ + Optional GetColumnOptionalInt32(ColumnIndex column); + + /** + * Get optional int64 value from column in current row. + * + * @throw Exception::InvalidColumn + */ + Optional GetColumnOptionalInt64(ColumnIndex column); + + /** + * Get optional float value from column in current row. + * + * @throw Exception::InvalidColumn + */ + Optional GetColumnOptionalFloat(ColumnIndex column); + + /** + * Get optional double value from column in current row. + * + * @throw Exception::InvalidColumn + */ + Optional GetColumnOptionalDouble(ColumnIndex column); + + /** + * Get optional string value from column in current row. + * + * @throw Exception::InvalidColumn + */ + Optional GetColumnOptionalString(ColumnIndex column); + }; + + // Move on copy semantics + typedef std::auto_ptr DataCommandAutoPtr; + + // Open flags + class Flag + { + public: + enum Type + { + None = 1<<0, + UseLucene = 1<<1 + }; + }; + + // 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 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 diff --git a/modules/db/include/dpl/db/thread_database_support.h b/modules/db/include/dpl/db/thread_database_support.h new file mode 100644 index 0000000..2f45f0f --- /dev/null +++ b/modules/db/include/dpl/db/thread_database_support.h @@ -0,0 +1,303 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file thread_database_support.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk) + * @version 1.0 + * @brief This file contains the declaration of thread database support + */ + +#ifndef DPL_THREAD_DATABASE_SUPPORT_H +#define DPL_THREAD_DATABASE_SUPPORT_H + +#include +#include +#include +#include +#include +#include + +namespace DPL +{ +namespace DB +{ + +/** + * Thread database support + * + * Associate database connection with thread lifecycle + * + */ + +class ThreadDatabaseSupport : + public DPL::DB::ORM::IOrmInterface +{ + private: + typedef DPL::DB::SqlConnection *SqlConnectionPtr; + typedef DPL::ThreadLocalVariable TLVSqlConnectionPtr; + typedef DPL::ThreadLocalVariable TLVSizeT; + typedef DPL::ThreadLocalVariable TLVBool; + + TLVSqlConnectionPtr m_connection; + TLVBool m_linger; + TLVSizeT m_refCounter; + TLVSizeT m_transactionDepth; + TLVSizeT m_attachCount; + TLVBool m_transactionCancel; + std::string m_address; + DPL::DB::SqlConnection::Flag::Type m_flags; + + TLVSqlConnectionPtr &Connection() + { + return m_connection; + } + + TLVBool &Linger() + { + return m_linger; + } + + TLVSizeT &RefCounter() + { + return m_refCounter; + } + + TLVSizeT &TransactionDepth() + { + return m_transactionDepth; + } + + TLVSizeT &AttachCount() + { + return m_attachCount; + } + + TLVBool &TransactionCancel() + { + return m_transactionCancel; + } + + void CheckedConnectionDelete() + { + Assert(!Connection().IsNull()); + Assert(*Linger() == true); + + if (*RefCounter() > 0 || *AttachCount() > 0) { + return; + } + + // Destroy connection + 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 diff --git a/modules/db/src/naive_synchronization_object.cpp b/modules/db/src/naive_synchronization_object.cpp new file mode 100644 index 0000000..198a2b6 --- /dev/null +++ b/modules/db/src/naive_synchronization_object.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file naive_synchronization_object.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of SQL naive synchronization object + */ +#include +#include + +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 diff --git a/modules/db/src/orm.cpp b/modules/db/src/orm.cpp new file mode 100644 index 0000000..5c7c821 --- /dev/null +++ b/modules/db/src/orm.cpp @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file orm.cpp + * @author Bartosz Janiak (b.janiak@samsung.com) + * @version 1.0 + * @brief Static definitions and function template specialziations of DPL-ORM. + */ + +#include + +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(ColumnIndex columnIndex, + DataCommand *command) +{ + return command->GetColumnInteger(columnIndex); +} + +template<> +DPL::String GetColumnFromCommand(ColumnIndex columnIndex, + DataCommand *command) +{ + return DPL::FromUTF8String(command->GetColumnString(columnIndex)); +} + +template<> +OptionalInteger GetColumnFromCommand(ColumnIndex columnIndex, + DataCommand *command) +{ + return command->GetColumnOptionalInteger(columnIndex); +} + +template<> +OptionalString GetColumnFromCommand(ColumnIndex columnIndex, + DataCommand *command) +{ + return command->GetColumnOptionalString(columnIndex); +} + +template<> +double GetColumnFromCommand(ColumnIndex columnIndex, + DataCommand *command) +{ + return command->GetColumnDouble(columnIndex); +} + +void DataCommandUtils::BindArgument(DataCommand *command, + ArgumentIndex index, + int argument) +{ + command->BindInteger(index, argument); +} + +void DataCommandUtils::BindArgument(DataCommand *command, + ArgumentIndex index, + const OptionalInteger& argument) +{ + command->BindInteger(index, argument); +} + +void DataCommandUtils::BindArgument(DataCommand *command, + ArgumentIndex index, + const DPL::String& argument) +{ + command->BindString(index, argument); +} + +void DataCommandUtils::BindArgument(DataCommand *command, + ArgumentIndex index, + const OptionalString& argument) +{ + command->BindString(index, argument); +} + +} +} +} \ No newline at end of file diff --git a/modules/db/src/sql_connection.cpp b/modules/db/src/sql_connection.cpp new file mode 100644 index 0000000..5a7fd4d --- /dev/null +++ b/modules/db/src/sql_connection.cpp @@ -0,0 +1,862 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file sql_connection.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of SQL connection + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DPL +{ +namespace DB +{ + +namespace // anonymous +{ +class ScopedNotifyAll + : public Noncopyable +{ +private: + SqlConnection::SynchronizationObject *m_synchronizationObject; + +public: + explicit ScopedNotifyAll( + SqlConnection::SynchronizationObject *synchronizationObject) + : m_synchronizationObject(synchronizationObject) + { + } + + ~ScopedNotifyAll() + { + if (!m_synchronizationObject) + return; + + LogPedantic("Notifying after successful synchronize"); + m_synchronizationObject->NotifyAll(); + } +}; +} // namespace anonymous + +SqlConnection::DataCommand::DataCommand(SqlConnection *connection, + const char *buffer) + : m_masterConnection(connection), + m_stmt(NULL) +{ + Assert(connection != NULL); + + // Notify all after potentially synchronized database connection access + ScopedNotifyAll notifyAll(connection->m_synchronizationObject.Get()); + + for (;;) + { + int ret = sqlite3_prepare_v2(connection->m_connection, + buffer, strlen(buffer), + &m_stmt, NULL); + + if (ret == SQLITE_OK) + { + LogPedantic("Data command prepared successfuly"); + break; + } + else if (ret == SQLITE_BUSY) + { + LogPedantic("Collision occurred while preparing SQL command"); + + // Synchronize if synchronization object is available + if (connection->m_synchronizationObject) + { + LogPedantic("Performing synchronization"); + connection->m_synchronizationObject->Synchronize(); + continue; + } + + // No synchronization object defined. Fail. + } + + // Fatal error + const char *error = sqlite3_errmsg(m_masterConnection->m_connection); + + LogPedantic("SQL prepare data command failed"); + LogPedantic(" Statement: " << buffer); + LogPedantic(" Error: " << error); + + ThrowMsg(Exception::SyntaxError, error); + } + + LogPedantic("Prepared data command: " << buffer); + + // Increment stored data command count + ++m_masterConnection->m_dataCommandsCount; +} + +SqlConnection::DataCommand::~DataCommand() +{ + LogPedantic("SQL data command finalizing"); + + if (sqlite3_finalize(m_stmt) != SQLITE_OK) + LogPedantic("Failed to finalize data command"); + + // Decrement stored data command count + --m_masterConnection->m_dataCommandsCount; +} + +void SqlConnection::DataCommand::CheckBindResult(int result) +{ + if (result != SQLITE_OK) + { + const char *error = sqlite3_errmsg( + m_masterConnection->m_connection); + + LogPedantic("Failed to bind SQL statement parameter"); + LogPedantic(" Error: " << error); + + ThrowMsg(Exception::SyntaxError, error); + } +} + +void SqlConnection::DataCommand::BindNull( + SqlConnection::ArgumentIndex position) +{ + CheckBindResult(sqlite3_bind_null(m_stmt, position)); + LogPedantic("SQL data command bind null: [" + << position << "]"); +} + +void SqlConnection::DataCommand::BindInteger( + SqlConnection::ArgumentIndex position, + int value) +{ + CheckBindResult(sqlite3_bind_int(m_stmt, position, value)); + LogPedantic("SQL data command bind integer: [" + << position << "] -> " << value); +} + +void SqlConnection::DataCommand::BindInt8( + SqlConnection::ArgumentIndex position, + int8_t value) +{ + CheckBindResult(sqlite3_bind_int(m_stmt, position, + static_cast(value))); + LogPedantic("SQL data command bind int8: [" + << position << "] -> " << value); +} + +void SqlConnection::DataCommand::BindInt16( + SqlConnection::ArgumentIndex position, + int16_t value) +{ + CheckBindResult(sqlite3_bind_int(m_stmt, position, + static_cast(value))); + LogPedantic("SQL data command bind int16: [" + << position << "] -> " << value); +} + +void SqlConnection::DataCommand::BindInt32( + SqlConnection::ArgumentIndex position, + int32_t value) +{ + CheckBindResult(sqlite3_bind_int(m_stmt, position, + static_cast(value))); + LogPedantic("SQL data command bind int32: [" + << position << "] -> " << value); +} + +void SqlConnection::DataCommand::BindInt64( + SqlConnection::ArgumentIndex position, + int64_t value) +{ + CheckBindResult(sqlite3_bind_int64(m_stmt, position, + static_cast(value))); + LogPedantic("SQL data command bind int64: [" + << position << "] -> " << value); +} + +void SqlConnection::DataCommand::BindFloat( + SqlConnection::ArgumentIndex position, + float value) +{ + CheckBindResult(sqlite3_bind_double(m_stmt, position, + static_cast(value))); + LogPedantic("SQL data command bind float: [" + << position << "] -> " << value); +} + +void SqlConnection::DataCommand::BindDouble( + SqlConnection::ArgumentIndex position, + double value) +{ + CheckBindResult(sqlite3_bind_double(m_stmt, position, value)); + LogPedantic("SQL data command bind double: [" + << position << "] -> " << value); +} + +void SqlConnection::DataCommand::BindString( + SqlConnection::ArgumentIndex position, + const char *value) +{ + if (!value) + { + BindNull(position); + return; + } + + // Assume that text may disappear + CheckBindResult(sqlite3_bind_text(m_stmt, position, + value, strlen(value), + SQLITE_TRANSIENT)); + + LogPedantic("SQL data command bind string: [" + << position << "] -> " << value); +} + +void SqlConnection::DataCommand::BindString( + SqlConnection::ArgumentIndex position, + const String &value) +{ + BindString(position, ToUTF8String(value).c_str()); +} + +void SqlConnection::DataCommand::BindInteger( + SqlConnection::ArgumentIndex position, + const Optional &value) +{ + if (value.IsNull()) + BindNull(position); + else + BindInteger(position, *value); +} + +void SqlConnection::DataCommand::BindInt8( + SqlConnection::ArgumentIndex position, + const Optional &value) +{ + if (value.IsNull()) + BindNull(position); + else + BindInt8(position, *value); +} + +void SqlConnection::DataCommand::BindInt16( + SqlConnection::ArgumentIndex position, + const Optional &value) +{ + if (value.IsNull()) + BindNull(position); + else + BindInt16(position, *value); +} + +void SqlConnection::DataCommand::BindInt32( + SqlConnection::ArgumentIndex position, + const Optional &value) +{ + if (value.IsNull()) + BindNull(position); + else + BindInt32(position, *value); +} + +void SqlConnection::DataCommand::BindInt64( + SqlConnection::ArgumentIndex position, + const Optional &value) +{ + if (value.IsNull()) + BindNull(position); + else + BindInt64(position, *value); +} + +void SqlConnection::DataCommand::BindFloat( + SqlConnection::ArgumentIndex position, + const Optional &value) +{ + if (value.IsNull()) + BindNull(position); + else + BindFloat(position, *value); +} + +void SqlConnection::DataCommand::BindDouble( + SqlConnection::ArgumentIndex position, + const Optional &value) +{ + if (value.IsNull()) + BindNull(position); + else + BindDouble(position, *value); +} + +void SqlConnection::DataCommand::BindString( + SqlConnection::ArgumentIndex position, + const Optional &value) +{ + if (!!value) + BindString(position, ToUTF8String(*value).c_str()); + else + BindNull(position); +} + +bool SqlConnection::DataCommand::Step() +{ + // Notify all after potentially synchronized database connection access + ScopedNotifyAll notifyAll( + m_masterConnection->m_synchronizationObject.Get()); + + for (;;) + { + int ret = sqlite3_step(m_stmt); + + if (ret == SQLITE_ROW) + { + LogPedantic("SQL data command step ROW"); + return true; + } + else if (ret == SQLITE_DONE) + { + LogPedantic("SQL data command step DONE"); + return false; + } + else if (ret == SQLITE_BUSY) + { + LogPedantic("Collision occurred while executing SQL command"); + + // Synchronize if synchronization object is available + if (m_masterConnection->m_synchronizationObject) + { + LogPedantic("Performing synchronization"); + + m_masterConnection-> + m_synchronizationObject->Synchronize(); + + continue; + } + + // No synchronization object defined. Fail. + } + + // Fatal error + const char *error = sqlite3_errmsg(m_masterConnection->m_connection); + + LogPedantic("SQL step data command failed"); + LogPedantic(" Error: " << error); + + ThrowMsg(Exception::InternalError, error); + } +} + +void SqlConnection::DataCommand::Reset() +{ + /* + * According to: + * http://www.sqlite.org/c3ref/stmt.html + * + * if last sqlite3_step command on this stmt returned an error, + * then sqlite3_reset will return that error, althought it is not an error. + * So sqlite3_reset allways succedes. + */ + sqlite3_reset(m_stmt); + + LogPedantic("SQL data command reset"); +} + +void SqlConnection::DataCommand::CheckColumnIndex( + SqlConnection::ColumnIndex column) +{ + if (column < 0 || column >= sqlite3_column_count(m_stmt)) + ThrowMsg(Exception::InvalidColumn, "Column index is out of bounds"); +} + +bool SqlConnection::DataCommand::IsColumnNull( + SqlConnection::ColumnIndex column) +{ + LogPedantic("SQL data command get column type: [" << column << "]"); + CheckColumnIndex(column); + return sqlite3_column_type(m_stmt, column) == SQLITE_NULL; +} + +int SqlConnection::DataCommand::GetColumnInteger( + SqlConnection::ColumnIndex column) +{ + LogPedantic("SQL data command get column integer: [" << column << "]"); + CheckColumnIndex(column); + int value = sqlite3_column_int(m_stmt, column); + LogPedantic(" Value: " << value); + return value; +} + +int8_t SqlConnection::DataCommand::GetColumnInt8( + SqlConnection::ColumnIndex column) +{ + LogPedantic("SQL data command get column int8: [" << column << "]"); + CheckColumnIndex(column); + int8_t value = static_cast(sqlite3_column_int(m_stmt, column)); + LogPedantic(" Value: " << value); + return value; +} + +int16_t SqlConnection::DataCommand::GetColumnInt16( + SqlConnection::ColumnIndex column) +{ + LogPedantic("SQL data command get column int16: [" << column << "]"); + CheckColumnIndex(column); + int16_t value = static_cast(sqlite3_column_int(m_stmt, column)); + LogPedantic(" Value: " << value); + return value; +} + +int32_t SqlConnection::DataCommand::GetColumnInt32( + SqlConnection::ColumnIndex column) +{ + LogPedantic("SQL data command get column int32: [" << column << "]"); + CheckColumnIndex(column); + int32_t value = static_cast(sqlite3_column_int(m_stmt, column)); + LogPedantic(" Value: " << value); + return value; +} + +int64_t SqlConnection::DataCommand::GetColumnInt64( + SqlConnection::ColumnIndex column) +{ + LogPedantic("SQL data command get column int64: [" << column << "]"); + CheckColumnIndex(column); + int64_t value = static_cast(sqlite3_column_int64(m_stmt, column)); + LogPedantic(" Value: " << value); + return value; +} + +float SqlConnection::DataCommand::GetColumnFloat( + SqlConnection::ColumnIndex column) +{ + LogPedantic("SQL data command get column float: [" << column << "]"); + CheckColumnIndex(column); + float value = static_cast(sqlite3_column_double(m_stmt, column)); + LogPedantic(" Value: " << value); + return value; +} + +double SqlConnection::DataCommand::GetColumnDouble( + SqlConnection::ColumnIndex column) +{ + LogPedantic("SQL data command get column double: [" << column << "]"); + CheckColumnIndex(column); + double value = sqlite3_column_double(m_stmt, column); + LogPedantic(" Value: " << value); + return value; +} + +std::string SqlConnection::DataCommand::GetColumnString( + SqlConnection::ColumnIndex column) +{ + LogPedantic("SQL data command get column string: [" << column << "]"); + CheckColumnIndex(column); + + const char *value = reinterpret_cast( + sqlite3_column_text(m_stmt, column)); + + LogPedantic("Value: " << (value ? value : "NULL")); + + if (value == NULL) + return std::string(); + + return std::string(value); +} + +Optional SqlConnection::DataCommand::GetColumnOptionalInteger( + SqlConnection::ColumnIndex column) +{ + LogPedantic("SQL data command get column optional integer: [" + << column << "]"); + CheckColumnIndex(column); + if (sqlite3_column_type(m_stmt, column) == SQLITE_NULL) + return Optional::Null; + int value = sqlite3_column_int(m_stmt, column); + LogPedantic(" Value: " << value); + return Optional(value); +} + +Optional SqlConnection::DataCommand::GetColumnOptionalInt8( + SqlConnection::ColumnIndex column) +{ + LogPedantic("SQL data command get column optional int8: [" + << column << "]"); + CheckColumnIndex(column); + if (sqlite3_column_type(m_stmt, column) == SQLITE_NULL) + return Optional::Null; + int8_t value = static_cast(sqlite3_column_int(m_stmt, column)); + LogPedantic(" Value: " << value); + return Optional(value); +} + +Optional SqlConnection::DataCommand::GetColumnOptionalInt16( + SqlConnection::ColumnIndex column) +{ + LogPedantic("SQL data command get column optional int16: [" + << column << "]"); + CheckColumnIndex(column); + if (sqlite3_column_type(m_stmt, column) == SQLITE_NULL) + return Optional::Null; + int16_t value = static_cast(sqlite3_column_int(m_stmt, column)); + LogPedantic(" Value: " << value); + return Optional(value); +} + +Optional SqlConnection::DataCommand::GetColumnOptionalInt32( + SqlConnection::ColumnIndex column) +{ + LogPedantic("SQL data command get column optional int32: [" + << column << "]"); + CheckColumnIndex(column); + if (sqlite3_column_type(m_stmt, column) == SQLITE_NULL) + return Optional::Null; + int32_t value = static_cast(sqlite3_column_int(m_stmt, column)); + LogPedantic(" Value: " << value); + return Optional(value); +} + +Optional SqlConnection::DataCommand::GetColumnOptionalInt64( + SqlConnection::ColumnIndex column) +{ + LogPedantic("SQL data command get column optional int64: [" + << column << "]"); + CheckColumnIndex(column); + if (sqlite3_column_type(m_stmt, column) == SQLITE_NULL) + return Optional::Null; + int64_t value = static_cast(sqlite3_column_int64(m_stmt, column)); + LogPedantic(" Value: " << value); + return Optional(value); +} + +Optional SqlConnection::DataCommand::GetColumnOptionalFloat( + SqlConnection::ColumnIndex column) +{ + LogPedantic("SQL data command get column optional float: [" + << column << "]"); + CheckColumnIndex(column); + if (sqlite3_column_type(m_stmt, column) == SQLITE_NULL) + return Optional::Null; + float value = static_cast(sqlite3_column_double(m_stmt, column)); + LogPedantic(" Value: " << value); + return Optional(value); +} + +Optional SqlConnection::DataCommand::GetColumnOptionalDouble( + SqlConnection::ColumnIndex column) +{ + LogPedantic("SQL data command get column optional double: [" + << column << "]"); + CheckColumnIndex(column); + if (sqlite3_column_type(m_stmt, column) == SQLITE_NULL) + return Optional::Null; + double value = sqlite3_column_double(m_stmt, column); + LogPedantic(" Value: " << value); + return Optional(value); +} + +Optional SqlConnection::DataCommand::GetColumnOptionalString( + SqlConnection::ColumnIndex column) +{ + LogPedantic("SQL data command get column optional string: [" + << column << "]"); + CheckColumnIndex(column); + if (sqlite3_column_type(m_stmt, column) == SQLITE_NULL) + return Optional::Null; + const char *value = reinterpret_cast( + sqlite3_column_text(m_stmt, column)); + LogPedantic("Value: " << value); + String s = FromUTF8String(value); + return Optional(s); +} + +void SqlConnection::Connect(const std::string &address, Flag::Type 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 buffer(rawBuffer); + + if (!buffer) + { + LogPedantic("Failed to allocate statement string"); + return; + } + + LogPedantic("Executing SQL command: " << buffer.Get()); + + // Notify all after potentially synchronized database connection access + ScopedNotifyAll notifyAll(m_synchronizationObject.Get()); + + for (;;) + { + char *errorBuffer; + + int ret = sqlite3_exec(m_connection, + buffer.Get(), + NULL, + NULL, + &errorBuffer); + + std::string errorMsg; + + // Take allocated error buffer + if (errorBuffer != NULL) + { + errorMsg = errorBuffer; + sqlite3_free(errorBuffer); + } + + if (ret == SQLITE_OK) + return; + + if (ret == SQLITE_BUSY) + { + LogPedantic("Collision occurred while executing SQL command"); + + // Synchronize if synchronization object is available + if (m_synchronizationObject) + { + LogPedantic("Performing synchronization"); + m_synchronizationObject->Synchronize(); + continue; + } + + // No synchronization object defined. Fail. + } + + // Fatal error + LogPedantic("Failed to execute SQL command. Error: " << errorMsg); + ThrowMsg(Exception::SyntaxError, errorMsg); + } +} + +SqlConnection::DataCommandAutoPtr SqlConnection::PrepareDataCommand( + const char *format, + ...) +{ + if (m_connection == NULL) + { + LogPedantic("Cannot execute data command. Not connected to DB!"); + return DataCommandAutoPtr(); + } + + char *rawBuffer; + + va_list args; + va_start(args, format); + + if (vasprintf(&rawBuffer, format, args) == -1) + rawBuffer = NULL; + + va_end(args); + + ScopedFree buffer(rawBuffer); + + if (!buffer) + { + LogPedantic("Failed to allocate statement string"); + return DataCommandAutoPtr(); + } + + LogPedantic("Executing SQL data command: " << buffer.Get()); + + return DataCommandAutoPtr(new DataCommand(this, buffer.Get())); +} + +SqlConnection::RowID SqlConnection::GetLastInsertRowID() const +{ + return static_cast(sqlite3_last_insert_rowid(m_connection)); +} + +void SqlConnection::TurnOnForeignKeys() +{ + ExecCommand("PRAGMA foreign_keys = ON;"); +} + +SqlConnection::SynchronizationObject * + SqlConnection::AllocDefaultSynchronizationObject() +{ + return new NaiveSynchronizationObject(); +} + +} // namespace DB +} // namespace DPL diff --git a/modules/db/src/thread_database_support.cpp b/modules/db/src/thread_database_support.cpp new file mode 100644 index 0000000..5b7865c --- /dev/null +++ b/modules/db/src/thread_database_support.cpp @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file thread_database_support.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk) + * @version 1.0 + * @brief This file contains the definition of thread database support + */ + +#include \ No newline at end of file diff --git a/modules/dbus/config.cmake b/modules/dbus/config.cmake new file mode 100644 index 0000000..995c071 --- /dev/null +++ b/modules/dbus/config.cmake @@ -0,0 +1,55 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# @file config.cmake +# @author Lukasz Marek (l.marek@samsung.com) +# @version 1.0 +# @brief +# + +SET(DPL_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 +) diff --git a/modules/dbus/include/dpl/dbus/connection.h b/modules/dbus/include/dpl/dbus/connection.h new file mode 100644 index 0000000..886038c --- /dev/null +++ b/modules/dbus/include/dpl/dbus/connection.h @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file connection.h + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief + */ + +#ifndef DPL_DBUS_CONNECTION_H +#define DPL_DBUS_CONNECTION_H + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DPL { +namespace DBus { + +namespace ConnectionEvents +{ +/** + * Emitted when service name is acquired. + * + * Arg0 Acquired name. + */ +DECLARE_GENERIC_EVENT_1(ServiceNameAcquiredEvent, std::string) + +/** + * Emitted when service name is lost. + * + * Arg0 Lost name. + */ +DECLARE_GENERIC_EVENT_1(ServiceNameLostEvent, std::string) + +/** + * Emitted when remote host closes connection. + * + * Arg0 Low-level error message. + */ +DECLARE_GENERIC_EVENT_1(ConnectionBrokenEvent, std::string) + +/** + * Emitted when invalid or malformed data appear on connection. + * + * Arg0 Low-level error message. + */ +DECLARE_GENERIC_EVENT_1(ConnectionInvalidEvent, std::string) +} + +class Server; + +class Connection; +typedef std::shared_ptr ConnectionPtr; + +typedef std::shared_ptr ObjectProxyPtr; + +class Connection : + public DPL::Event::EventSupport, + public DPL::Event::EventSupport, + public DPL::Event::EventSupport, + public DPL::Event::EventSupport +{ +public: + /** + * Acquires connection to session bus. + * + * @return Session bus connection. + * @throw DBus::Exception If unable to connect to session bus. + */ + static ConnectionPtr sessionBus(); + + /** + * Acquires connection to system bus. + * + * @return System bus connection. + * @throw DBus::Exception If unable to connect to system bus. + */ + static ConnectionPtr systemBus(); + + /** + * Acquires connection to specified bus. + * + * @return Bus connection. + * @throw DBus::Exception If unable to connect to a bus. + */ + static ConnectionPtr connectTo(GBusType busType); + + /** + * Acquires connection to for specified address. + * + * @return Connection. + * @throw DBus::Exception If unable to connect. + * + * @remarks Address should be in DBus format (@see DBus documentation). + */ + static ConnectionPtr connectTo(const std::string& address); + + ~Connection(); + + /** + * Sets up a service on the connection. + * + * @param serviceName Service to register. + * @throw DBus::Exception If registration failed. + * + * @remarks Add objects before services to prevent notifications about new + * interfaces being added. + */ + void registerService(const std::string& serviceName); + + /** + * Unregisters a service from the connection. + * + * @param serviceName Service to unregister. + * @throw DBus::Exception If service not registered. + */ + void unregisterService(const std::string& serviceName); + + /** + * Adds object to the connection. + * + * @param object Object to register. + * @throw DBus::Exception If registration failed. + * + * @remarks Add objects before services to prevent notifications about new + * interfaces being added. + */ + void registerObject(const ObjectPtr& object); + + /** + * Removed object from the connection. + * + * @param objectPath Path of the object to unregister. + * @throw DBus::Exception If object not registered. + */ + void unregisterObject(const std::string& objectPath); + + /** + * Creates proxy to remote objects. + * + * @param serviceName Name of the DBus service. + * @param objectPath DBus path to the object. + * @return Object proxy. + * @throw DBus::ConnectionClosedException If connection is closed. + */ + ObjectProxyPtr createObjectProxy(const std::string& serviceName, + const std::string& objectPath); + +private: + friend class Server; + + typedef std::map RegisteredServices; + + struct ObjectRegistration + { + ObjectRegistration(guint registrationId, const ObjectPtr& object) + : registrationId(registrationId), + object(object) + { + } + + guint registrationId; + ObjectPtr object; + }; + typedef std::map RegisteredObjects; + + static void onServiceNameAcquired(GDBusConnection* connection, + const gchar* serviceName, + gpointer data); + + static void onServiceNameLost(GDBusConnection* connection, + const gchar* serviceName, + gpointer data); + + static void onConnectionClosed(GDBusConnection* connection, + gboolean peerVanished, + GError* error, + gpointer data); + + explicit Connection(GDBusConnection* connection); + + GDBusConnection* m_connection; + + RegisteredServices m_registeredServices; + + RegisteredObjects m_registeredObjects; +}; + +} +} + +#endif // DPL_DBUS_CONNECTION_H diff --git a/modules/dbus/include/dpl/dbus/dbus_client.h b/modules/dbus/include/dpl/dbus/dbus_client.h new file mode 100644 index 0000000..6b86c57 --- /dev/null +++ b/modules/dbus/include/dpl/dbus/dbus_client.h @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file dbus_client.h + * @author Tomasz Swierczek (t.swierczek@samsung.com) + * @version 1.0 + * @brief Header file for DBus generic client support + */ + +#ifndef DPL_DBUS_DBUS_CLIENT_H_ +#define DPL_DBUS_DBUS_CLIENT_H_ + +#include +#include +#include +#include +#include +#include + +namespace DPL { +namespace DBus { + +/* + * DBus::Client class is intended to act as simple DBus client. To call a method + * on remote service "Service", on remote object "Object", interface + * "Interface",use it like this: + * + * + * DBus::Client client("Object", "Service", "Interface"); + * (...) // variables declarations + * client.call("Method name", arg1, arg2, arg2, ... argN, + * &outArg1, &outArg2, &outArg3, ..., &outArgN); + * + * + * As You can see, input parameters of the call are passed with reference, + * output ones are passed as pointers - parameters MUST be passed this way. + * + * To call a void function (no out params), just pass in arguments to Call(). + * + * Currently client supports serialization and deserialization of simple types + * (int, char, float, unsigned), strings (std::string and char*) and + * some STL containers (std::vector, std::list, std::map, std::set, std::pair). + * Structures and classes are not (yet) supported. + */ + +class Client +{ + + public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, DBusClientException) + }; + + Client(std::string serverPath, + std::string serviceName, + std::string interfaceName) : + m_serviceName(serviceName), + m_serverPath(serverPath), + m_interfaceName(interfaceName) + { + DBusError error; + + dbus_error_init(&error); + m_connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error); + if (NULL == m_connection) { + LogPedantic("Couldn't get DBUS connection. Error: " << + error.message); + dbus_error_free(&error); + ThrowMsg(Exception::DBusClientException, + "Couldn't get DBUS connection." ); + } + } + + template + void call(const char* methodName, const Args&... args) + { + DBusMessage* message = dbus_message_new_method_call( + m_serviceName.c_str(), + m_serverPath.c_str(), + m_interfaceName.c_str(), + methodName); + DBusMessageIter argsIterator; + dbus_message_iter_init_append(message, &argsIterator); + call(message, &argsIterator, args...); + dbus_message_unref(message); + } + + template + void call(std::string methodName, const Args&... args) + { + call(methodName.c_str(), args...); + } + + ~Client() + { + dbus_connection_unref(m_connection); + } + + private: + + DBusMessage* makeCall( + DBusMessage* message) + { + DBusError error; + dbus_error_init(&error); + DBusMessage* ret = dbus_connection_send_with_reply_and_block( + m_connection, + message, + -1, + &error); + if (NULL == ret) { + LogPedantic("Error sending DBUS message: " << + error.message); + dbus_error_free(&error); + ThrowMsg(Exception::DBusClientException, + "Error sending DBUS message." ); + } + return ret; + } + + void call(DBusMessage* message, DBusMessageIter* /*argsIterator*/) + { + DBusMessage* ret = makeCall(message); + if (ret != NULL) { + dbus_message_unref(ret); + } else { + LogPedantic("Error getting DBUS response."); + ThrowMsg(Exception::DBusClientException, + "Error getting DBUS response." ); + } + } + + template + void call( + DBusMessage* message, + DBusMessageIter* argsIterator, + const T& invalue, + const Args&... args) + { + if (!Serialization::serialize(argsIterator, invalue)){ + LogPedantic("Error in serialization."); + ThrowMsg(Exception::DBusClientException, + "Error in serialization." ); + } + call(message, argsIterator, args...); + } + + template + void call( + DBusMessage* message, + DBusMessageIter* argsIterator, + const T* invalue, + const Args&... args) + { + if (!Serialization::serialize(argsIterator, invalue)){ + LogPedantic("Error in serialization."); + ThrowMsg(Exception::DBusClientException, + "Error in serialization." ); + } + call(message, argsIterator, args...); + } + + template + void call( + DBusMessage* message, + DBusMessageIter* argsIterator, + const T* invalue) + { + if (!Serialization::serialize(argsIterator, invalue)){ + LogPedantic("Error in serialization."); + ThrowMsg(Exception::DBusClientException, + "Error in serialization." ); + } + call(message, argsIterator); + } + + template + void call( + DBusMessage* message, + DBusMessageIter* /*argsIterator*/, + T* out, + const Args&... args) + { + DBusMessage* ret = makeCall(message); + if (ret != NULL) { + DBusMessageIter responseIterator; + dbus_message_iter_init(ret, &responseIterator); + returnFromCall(&responseIterator, out, args...); + dbus_message_unref(ret); + } + } + + template + void returnFromCall( + DBusMessageIter* responseIterator, + T* out, + const Args&... args) + { + if (!Deserialization::deserialize(responseIterator, out)){ + LogPedantic("Error in deserialization."); + ThrowMsg(Exception::DBusClientException, + "Error in deserialization." ); + } + returnFromCall(responseIterator, args...); + } + + template + void returnFromCall(DBusMessageIter* responseIterator, T* out) + { + if (!Deserialization::deserialize(responseIterator, out)){ + LogPedantic("Error in deserialization."); + ThrowMsg(Exception::DBusClientException, + "Error in deserialization." ); + } + } + + std::string m_serviceName, m_serverPath, m_interfaceName; + DBusConnection* m_connection; +}; + +} // namespace DBus +} // namespace DPL + +#endif // DPL_DBUS_DBUS_CLIENT_H_ diff --git a/modules/dbus/include/dpl/dbus/dbus_deserialization.h b/modules/dbus/include/dpl/dbus/dbus_deserialization.h new file mode 100644 index 0000000..9f50f91 --- /dev/null +++ b/modules/dbus/include/dpl/dbus/dbus_deserialization.h @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file dbus_deserialization.h + * @author Tomasz Swierczek (t.swierczek@samsung.com) + * @version 1.0 + * @brief Header file for DBus data deserialization + */ + +#ifndef DPL_DBUS_DBUS_DESERIALIZATION_H_ +#define DPL_DBUS_DBUS_DESERIALIZATION_H_ + +#include +#include +#include +#include +#include +#include +#include + +namespace DPL { +namespace DBus { + +struct Deserialization +{ + + static bool deserializePrimitive( + DBusMessageIter* responseIterator, + void* arg, + int type) + { + if (dbus_message_iter_get_arg_type(responseIterator) != type) { + return false; + } + dbus_message_iter_get_basic(responseIterator, arg); + return true; + } + + // char* and all integer types + doubles + template + static bool deserialize(DBusMessageIter* responseIterator, T* arg) + { + if (dbus_message_iter_get_arg_type(responseIterator) + != SimpleType::value) { + return false; + } + dbus_message_iter_get_basic(responseIterator, arg); + return true; + } + + // float case - read as double + static bool deserialize(DBusMessageIter* responseIterator, float* arg) + { + double d; + if (!deserialize(responseIterator, &d)){ + return false; + } + *arg = static_cast(d); + return true; + } + + // std::string + static bool deserialize( + DBusMessageIter* responseIterator, + std::string* arg) + { + char* str = NULL; + if (!deserialize(responseIterator, &str)){ + return false; + } + *arg = std::string(str); + return true; + } + + // dbus array deserialization + template + static bool deserializeContainer( + DBusMessageIter* responseIterator, + T* arg) + { + if (dbus_message_iter_get_arg_type(responseIterator) + != DBUS_TYPE_ARRAY) { + return false; + } + DBusMessageIter subIterator; + dbus_message_iter_recurse(responseIterator, &subIterator); + while (dbus_message_iter_get_arg_type(&subIterator) + != DBUS_TYPE_INVALID) { + arg->push_back(typename T::value_type()); + if (!deserialize(&subIterator, &arg->back())){ + return false; + } + dbus_message_iter_next(&subIterator); + } + return true; + } + + // std::vector + template + static bool deserialize( + DBusMessageIter* responseIterator, + std::vector* arg) + { + return deserializeContainer(responseIterator, arg); + } + + // std::list + template + static bool deserialize( + DBusMessageIter* responseIterator, + std::list* arg) + { + return deserializeContainer(responseIterator, arg); + } + + // std::set + template + static bool deserialize( + DBusMessageIter* responseIterator, + std::set* arg) + { + if (dbus_message_iter_get_arg_type(responseIterator) + != DBUS_TYPE_ARRAY) { + return false; + } + DBusMessageIter subIterator; + dbus_message_iter_recurse(responseIterator, &subIterator); + while (dbus_message_iter_get_arg_type(&subIterator) + != DBUS_TYPE_INVALID) { + typename std::set::value_type element; + if (!deserialize(&subIterator, &element)){ + return false; + } + arg->insert(element); + dbus_message_iter_next(&subIterator); + } + return true; + } + + // std::pair + template + static bool deserialize( + DBusMessageIter* argsIterator, + const std::pair* arg) + { + if (dbus_message_iter_get_arg_type(argsIterator) + != DBUS_TYPE_DICT_ENTRY) { + return false; + } + DBusMessageIter dictEntryIterator; + dbus_message_iter_recurse(argsIterator, &dictEntryIterator); + if (!deserialize(dictEntryIterator, &arg->first)){ + return false; + } + dbus_message_iter_next(&dictEntryIterator); + if (!deserialize(dictEntryIterator, &arg->second)){ + return false; + } + return true; + } + + // std::map + template + static bool deserialize( + DBusMessageIter* responseIterator, + const std::map* arg) + { + if (dbus_message_iter_get_arg_type(responseIterator) + != DBUS_TYPE_ARRAY) { + return false; + } + DBusMessageIter subIterator; + dbus_message_iter_recurse(responseIterator, &subIterator); + while (dbus_message_iter_get_arg_type(&subIterator) + != DBUS_TYPE_INVALID) { + typename std::pair element; + if (!deserialize(&subIterator, &element)){ + return false; + } + arg->insert(element); + dbus_message_iter_next(&subIterator); + } + return true; + } + +}; + +template<> +inline bool Deserialization::deserialize( + DBusMessageIter* responseIterator, + bool* arg) +{ + unsigned int value; + if (dbus_message_iter_get_arg_type(responseIterator) + != SimpleType::value) { + return false; + } + dbus_message_iter_get_basic(responseIterator, &value); + *arg = static_cast(value); + return true; +} + +} // namespace DBus +} // namespace DPL + +#endif // DPL_DBUS_DBUS_DESERIALIZATION_H_ diff --git a/modules/dbus/include/dpl/dbus/dbus_interface_dispatcher.h b/modules/dbus/include/dpl/dbus/dbus_interface_dispatcher.h new file mode 100644 index 0000000..d5e3591 --- /dev/null +++ b/modules/dbus/include/dpl/dbus/dbus_interface_dispatcher.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file dbus_interface_dispatcher.h + * @author Tomasz Swierczek (t.swierczek@samsung.com) + * @version 1.0 + * @brief This file contains definitions of DBus::InterfaceDispatcher + * class. + */ + +#ifndef DPL_DBUS_DBUS_INTERFACE_DISPATCHER_H_ +#define DPL_DBUS_DBUS_INTERFACE_DISPATCHER_H_ + +#include +#include +#include + +namespace DPL { +namespace DBus { + +class InterfaceDispatcher : public DBus::Dispatcher +{ +public: + explicit InterfaceDispatcher(const std::string& interfaceName): + m_interfaceName(interfaceName) + { + } + + virtual ~InterfaceDispatcher() + {} + + // Implement it in specific interface with method handling + virtual void onMethodCall(const gchar* /*methodName*/, + GVariant* /*parameters*/, + GDBusMethodInvocation* /*invocation*/) = 0; + + virtual std::string getName() const + { + return m_interfaceName; + } + + virtual std::string getXmlSignature() const + { + return m_xml; + } + virtual void setXmlSignature(const std::string& newSignature) + { + m_xml = newSignature; + } + + virtual void onMethodCall(GDBusConnection* /*connection*/, + const gchar* /*sender*/, + const gchar* /*objectPath*/, + const gchar* interfaceName, + const gchar* methodName, + GVariant* parameters, + GDBusMethodInvocation* invocation) + { + if (g_strcmp0(interfaceName, m_interfaceName.c_str()) == 0){ + onMethodCall(methodName, parameters, invocation); + } else { + LogPedantic("Called invalid interface: " << interfaceName << + " instead of: " << m_interfaceName); + } + } + + virtual GVariant* onPropertyGet(GDBusConnection* /*connection*/, + const gchar* /*sender*/, + const gchar* /*objectPath*/, + const gchar* /*interfaceName*/, + const gchar* propertyName) + { + 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_ diff --git a/modules/dbus/include/dpl/dbus/dbus_serialization.h b/modules/dbus/include/dpl/dbus/dbus_serialization.h new file mode 100644 index 0000000..7bfa65b --- /dev/null +++ b/modules/dbus/include/dpl/dbus/dbus_serialization.h @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file dbus_serialization.h + * @author Tomasz Swierczek (t.swierczek@samsung.com) + * @version 1.0 + * @brief Header file for DBus data derialization + */ + +#ifndef DPL_DBUS_DBUS_SERIALIZATION_H_ +#define DPL_DBUS_DBUS_SERIALIZATION_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DPL { +namespace DBus { + +struct Serialization +{ + + // std::string + static bool serialize( + DBusMessageIter* argsIterator, + const std::string& str) + { + return serialize(argsIterator, str.c_str()); + } + + // float case - send as double + static bool serialize(DBusMessageIter* argsIterator, const float& arg) + { + const double d = static_cast(arg); + return serialize(argsIterator, d); + } + + // char* and all integer types + doubles + template + static bool serialize(DBusMessageIter* argsIterator, const T& arg) + { + return dbus_message_iter_append_basic(argsIterator, + SimpleType::value, + &arg); + } + + // dbus array serialization + template + static bool serializeContainer( + DBusMessageIter* argsIterator, + const T& arg) + { + typename T::const_iterator containerIt; + DBusMessageIter subIterator; + if (!dbus_message_iter_open_container(argsIterator, DBUS_TYPE_ARRAY, + Signature::value(), &subIterator)) { + return false; + } + FOREACH(containerIt,arg) { + if (!serialize(&subIterator, *containerIt)){ + return false; + } + } + return dbus_message_iter_close_container(argsIterator, &subIterator); + } + + // std::vector + template + static bool serialize( + DBusMessageIter* argsIterator, + const std::vector &arg) + { + return serializeContainer(argsIterator, arg); + } + + // std::list + template + static bool serialize( + DBusMessageIter* argsIterator, + const std::list &arg) + { + return serializeContainer(argsIterator, arg); + } + + // std::set + template + static bool serialize( + DBusMessageIter* argsIterator, + const std::set &arg) + { + return serializeContainer(argsIterator, arg); + } + + // std::pair + template + static bool serialize( + DBusMessageIter* argsIterator, + const std::pair &arg) + { + DBusMessageIter dictEntryIterator; + if (!dbus_message_iter_open_container(argsIterator, + DBUS_TYPE_DICT_ENTRY, NULL, &dictEntryIterator)) { + return false; + } + if (!serialize(dictEntryIterator, arg.first)){ + return false; + } + if (!serialize(dictEntryIterator, arg.second)){ + return false; + } + return dbus_message_iter_close_container(argsIterator, + &dictEntryIterator); + } + + // std::map + template + static bool serialize( + DBusMessageIter* argsIterator, + const std::map &arg) + { + return serializeContainer(argsIterator, arg); + } + +}; + +// char* and all integer types + doubles +template<> +inline bool Serialization::serialize(DBusMessageIter* argsIterator, + const bool& arg) +{ + unsigned int value = static_cast(arg); + return dbus_message_iter_append_basic(argsIterator, + SimpleType::value, + &value); +} + +} // namespace DBus +} // namespace DPL + +#endif // DPL_DBUS_DBUS_SERIALIZATION_H_ diff --git a/modules/dbus/include/dpl/dbus/dbus_server_deserialization.h b/modules/dbus/include/dpl/dbus/dbus_server_deserialization.h new file mode 100644 index 0000000..5f3b28b --- /dev/null +++ b/modules/dbus/include/dpl/dbus/dbus_server_deserialization.h @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file dbus_server_deserialization.h + * @author Tomasz Swierczek (t.swierczek@samsung.com) + * @version 1.0 + * @brief Header file for DBus data deserialization from GVariant + */ + +#ifndef DPL_DBUS_DBUS_SERVER_DESERIALIZATION_H_ +#define DPL_DBUS_DBUS_SERVER_DESERIALIZATION_H_ + +#include +#include +#include +#include +#include +#include + +namespace DPL { +namespace DBus { + +struct ServerDeserialization { + + template + static bool deserialize(GVariant* g, T* arg1, Args... args) + { + Assert(NULL != g); + Assert(NULL != arg1); + GVariantIter* iterator = g_variant_iter_new(g); + if (NULL == iterator) { + return false; + } + if (!deserializeIterator(iterator, arg1)) { + g_variant_iter_free(iterator); + return false; + } + if (!deserializeIterator(iterator, args...)) { + g_variant_iter_free(iterator); + return false; + } + g_variant_iter_free(iterator); + return true; + } + + template + static bool deserialize(GVariant* g, T* arg1) + { + Assert(NULL != g); + Assert(NULL != arg1); + GVariantIter* iterator = g_variant_iter_new(g); + if (NULL == iterator) { + return false; + } + if (!deserializeIterator(iterator, arg1)) { + g_variant_iter_free(iterator); + return false; + } + g_variant_iter_free(iterator); + return true; + } + + // deserialization from GVariant tuple iterator + template + static bool deserializeIterator(GVariantIter* g, T* arg1, Args... args) + { + Assert(NULL != g); + Assert(NULL != arg1); + GVariant* elem = g_variant_iter_next_value(g); + if (NULL == elem) { + return false; + } + if (!deserializeElem(elem, arg1)) { + return false; + } + if (!deserializeIterator(g, args...)) { + return false; + } + return true; + } + + template + static bool deserializeIterator(GVariantIter* g, T* arg1) + { + Assert(NULL != g); + Assert(NULL != arg1); + GVariant* elem = g_variant_iter_next_value(g); + if (NULL == elem) { + return false; + } + if (!deserializeElem(elem, arg1)) { + return false; + } + g_variant_unref(elem); + return true; + } + + // type specialization + static bool deserializeElem(GVariant* parameters, std::string* outStr) + { + const gchar* arg = g_variant_get_string(parameters, NULL); + *outStr = std::string(arg); + return true; + } + + static bool deserializeElem(GVariant* parameters, int* outInt) + { + gint32 arg = g_variant_get_int32(parameters); + *outInt = arg; + return true; + } + + static bool deserializeElem(GVariant* parameters, unsigned* outInt) + { + guint32 arg = g_variant_get_uint32(parameters); + *outInt = arg; + return true; + } + + static bool deserializeElem(GVariant* parameters, bool* outInt) + { + gboolean arg = g_variant_get_boolean(parameters); + *outInt = arg; + return true; + } + + static bool deserializeElem(GVariant* parameters, float* outInt) + { + gdouble arg = g_variant_get_double(parameters); + *outInt = static_cast(arg); + return true; + } + + static bool deserializeElem(GVariant* parameters, + std::vector* outArray) + { + unsigned int i = 0; + gsize length = 0; + const gchar** args = g_variant_get_strv( + parameters, + &length); + for (i = 0; i < length; ++i) { + outArray->push_back(std::string(args[i])); + } + g_free(args); + return true; + } + + static bool deserializeElem(GVariant* parameters, + std::list* outArray) + { + unsigned int i = 0; + gsize length = 0; + const gchar** args = g_variant_get_strv( + parameters, + &length); + for (i = 0; i < length; ++i) { + outArray->push_back(std::string(args[i])); + } + g_free(args); + return true; + } +}; + +} // namespace DBus +} // namespace DPL + +#endif // DPL_DBUS_DBUS_SERVER_DESERIALIZATION_H_ diff --git a/modules/dbus/include/dpl/dbus/dbus_server_serialization.h b/modules/dbus/include/dpl/dbus/dbus_server_serialization.h new file mode 100644 index 0000000..8c299ef --- /dev/null +++ b/modules/dbus/include/dpl/dbus/dbus_server_serialization.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file dbus_server_serialization.h + * @author Tomasz Swierczek (t.swierczek@samsung.com) + * @version 1.0 + * @brief Header file for DBus data serialization to GVariant + */ + +#ifndef DPL_DBUS_DBUS_SERVER_SERIALIZATION_H_ +#define DPL_DBUS_DBUS_SERVER_SERIALIZATION_H_ + +#include +#include + +namespace DPL { +namespace DBus { + +struct ServerSerialization { + + template + static GVariant* serialize(Args... args) + { + GVariantBuilder* builder = g_variant_builder_new(G_VARIANT_TYPE_TUPLE); + if (NULL == builder) { + return NULL; + } + serializeBuilder(builder, args ...); + return g_variant_builder_end(builder); + } + + // serialization on GVariantBuilder + template + static void serializeBuilder(GVariantBuilder* builder, + const T& arg, + Args... args) + { + serializeElem(builder, arg); + serializeBuilder(builder, args ...); + } + + template + static void serializeBuilder(GVariantBuilder* builder, const T& arg) + { + serializeElem(builder, arg); + } + + // type specialization + static void serializeElem(GVariantBuilder* builder, int arg) + { + g_variant_builder_add_value(builder, g_variant_new_int32(arg)); + } + + static void serializeElem(GVariantBuilder* builder, unsigned arg) + { + g_variant_builder_add_value(builder, g_variant_new_uint32(arg)); + } + + static void serializeElem(GVariantBuilder* builder, bool arg) + { + g_variant_builder_add_value(builder, g_variant_new_boolean(arg)); + } + + static void serializeElem(GVariantBuilder* builder, float arg) + { + gdouble d = static_cast(arg); + g_variant_builder_add_value(builder, g_variant_new_double(d)); + } + + static void serializeElem(GVariantBuilder* builder, const char* arg) + { + g_variant_builder_add_value(builder, g_variant_new_string(arg)); + } + + static void serializeElem(GVariantBuilder* builder, + const std::string& arg) + { + g_variant_builder_add_value(builder, g_variant_new_string(arg.c_str())); + } +}; + +} // namespace DBus +} // namespace DPL + +#endif // DPL_DBUS_DBUS_SERVER_SERIALIZATION_H_ diff --git a/modules/dbus/include/dpl/dbus/dbus_signature.h b/modules/dbus/include/dpl/dbus/dbus_signature.h new file mode 100644 index 0000000..af0c2ef --- /dev/null +++ b/modules/dbus/include/dpl/dbus/dbus_signature.h @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file dbus_deserialization.h + * @author Tomasz Swierczek (t.swierczek@samsung.com) + * @version 1.0 + * @brief Header file for DBus data signatures + */ + +#ifndef DPL_DBUS_SIGNATURE_H +#define DPL_DBUS_SIGNATURE_H + +#include +#include + +namespace DPL { +namespace DBus { + +template +struct SimpleType; + +template +struct Signature +{ + static inline const char* value() + { + static const char signature[] = + { (char) SimpleType::value, 0 }; + return signature; + } +}; + +// signed integer types +template +struct __SignedIntegerType; + +template<> +struct __SignedIntegerType<1> +{ + static const int value = DBUS_TYPE_INT16; +}; + +template<> +struct __SignedIntegerType<2> +{ + static const int value = DBUS_TYPE_INT16; +}; + +template<> +struct __SignedIntegerType<4> +{ + static const int value = DBUS_TYPE_INT32; +}; + +template<> +struct __SignedIntegerType<8> +{ + static const int value = DBUS_TYPE_INT64; +}; + +// unsigned integer types +template +struct __UnsignedIntegerType; + +template<> +struct __UnsignedIntegerType<1> +{ + static const int value = DBUS_TYPE_BYTE; +}; +template<> +struct __UnsignedIntegerType<2> +{ + static const int value = DBUS_TYPE_UINT16; +}; +template<> +struct __UnsignedIntegerType<4> +{ + static const int value = DBUS_TYPE_UINT32; +}; +template<> +struct __UnsignedIntegerType<8> +{ + static const int value = DBUS_TYPE_UINT64; +}; + +// basic types +template<> +struct SimpleType +{ + static const int value = DBUS_TYPE_BOOLEAN; +}; + +template<> +struct SimpleType +{ + static const int value = __UnsignedIntegerType::value; +}; + +template<> +struct SimpleType +{ + static const int value = __SignedIntegerType::value; +}; + +template<> +struct SimpleType +{ + static const int value = + __UnsignedIntegerType::value; +}; + +template<> +struct SimpleType +{ + static const int value = __SignedIntegerType::value; +}; + +template<> +struct SimpleType +{ + static const int value = + __UnsignedIntegerType::value; +}; + +template<> +struct SimpleType +{ + static const int value = __SignedIntegerType::value; +}; + +template<> +struct SimpleType +{ + static const int value = + __UnsignedIntegerType::value; +}; + +template<> +struct SimpleType +{ + static const int value = __SignedIntegerType::value; +}; + +template<> +struct SimpleType +{ + static const int value = + __UnsignedIntegerType::value; +}; + +template<> +struct SimpleType +{ + static const int value = __SignedIntegerType::value; +}; + +template<> +struct SimpleType +{ + static const int value = __UnsignedIntegerType< + sizeof(unsigned long long)>::value; +}; + +template<> +struct SimpleType +{ + static const int value = DBUS_TYPE_DOUBLE; +}; + +template<> +struct SimpleType +{ + static const int value = DBUS_TYPE_DOUBLE; +}; + +template<> +struct SimpleType +{ + static const int value = DBUS_TYPE_STRING; +}; + +template<> +struct SimpleType +{ + static const int value = DBUS_TYPE_STRING; +}; + +template<> +struct SimpleType +{ + static const int value = DBUS_TYPE_STRING; +}; + +// STL containers signatures + +// generic array +template +struct ArraySignature +{ + static inline const char* value() + { + static const std::string signature = std::string( + DBUS_TYPE_ARRAY_AS_STRING) + Signature::value(); + return signature.c_str(); + } +}; + +// std::vector +template +struct Signature > : public ArraySignature +{ +}; + +// std::list +template +struct Signature > : public ArraySignature +{ +}; + +// std::set +template +struct Signature > : public ArraySignature +{ +}; + +// std::pair +template +struct Signature > +{ + static inline const char* value() + { + static const std::string signature = std::string( + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING) + + Signature::value() + Signature::value() + + DBUS_DICT_ENTRY_END_CHAR_AS_STRING; + return signature.c_str(); + } +}; + +// std::map +template +struct Signature > : public ArraySignature > +{ +}; + +} // namespace DBus +} // namespace DPL + +#endif // DPL_DBUS_SIGNATURE_H diff --git a/modules/dbus/include/dpl/dbus/dispatcher.h b/modules/dbus/include/dpl/dbus/dispatcher.h new file mode 100644 index 0000000..68e4397 --- /dev/null +++ b/modules/dbus/include/dpl/dbus/dispatcher.h @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file dispatcher.h + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief + */ + +#ifndef DPL_DBUS_DISPATCHER_H +#define DPL_DBUS_DISPATCHER_H + +#include + +namespace DPL { +namespace DBus { + +class Dispatcher +{ +public: + virtual ~Dispatcher() =0; + + /** + * Called on method invocation. + * + * @param connection + * @param sender + * @param objectPath + * @param interfaceName + * @param methodName + * @param parameters + * @param invocation + * + * @see GLib DBus documentation. + */ + virtual void onMethodCall(GDBusConnection* connection, + const gchar* sender, + const gchar* objectPath, + const gchar* interfaceName, + const gchar* methodName, + GVariant* parameters, + GDBusMethodInvocation* invocation) =0; + + /** + * Called on property get. + * + * @param connection + * @param sender + * @param objectPath + * @param interfaceName + * @param propertyName + * @return Porperty value. + * + * @see GLib DBus documentation. + */ + virtual GVariant* onPropertyGet(GDBusConnection* connection, + const gchar* sender, + const gchar* objectPath, + const gchar* interfaceName, + const gchar* propertyName, + GError** error); + + /** + * Called on property set. + * + * @param connection + * @param sender + * @param objectPath + * @param interfaceName + * @param propertyName + * @param value + * @return TRUE if successfully set, FALSE otherwise. + * + * @see GLib DBus documentation. + */ + virtual gboolean onPropertySet(GDBusConnection* connection, + const gchar* sender, + const gchar* objectPath, + const gchar* interfaceName, + const gchar* propertyName, + GVariant* value, + GError** error); +}; + +} +} + +#endif // DPL_DBUS_DISPATCHER_H diff --git a/modules/dbus/include/dpl/dbus/exception.h b/modules/dbus/include/dpl/dbus/exception.h new file mode 100644 index 0000000..fb21bf0 --- /dev/null +++ b/modules/dbus/include/dpl/dbus/exception.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file exception.h + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief + */ + +#ifndef DPL_DBUS_EXCEPTION_H +#define DPL_DBUS_EXCEPTION_H + +#include + +namespace DPL { +namespace DBus { + +/** + * Thrown when none of the following, more specific exception fit. + */ +DECLARE_EXCEPTION_TYPE(DPL::Exception, Exception) + +/** + * Thrown when trying to perform an operation on a closed connection. + */ +DECLARE_EXCEPTION_TYPE(DBus::Exception, ConnectionClosedException) + +/** + * Thrown when passing invalid argument(s). + */ +DECLARE_EXCEPTION_TYPE(DBus::Exception, InvalidArgumentException) + +} +} + +#endif diff --git a/modules/dbus/include/dpl/dbus/interface.h b/modules/dbus/include/dpl/dbus/interface.h new file mode 100644 index 0000000..1bf1148 --- /dev/null +++ b/modules/dbus/include/dpl/dbus/interface.h @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file interface.h + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief + */ + +#ifndef DPL_DBUS_INTERFACE_H +#define DPL_DBUS_INTERFACE_H + +#include +#include +#include +#include +#include + +namespace DPL { +namespace DBus { + +class Interface; +typedef std::shared_ptr InterfacePtr; + +class Interface : private DPL::Noncopyable +{ +public: + /** + * Parses supplied XML string to produce DBus interface descriptions. + * + * @param xmlString XML string to parse. + * @return Interfaces. + * @throw DPL::DBus::Exception If error while parsing occurs. + */ + static std::vector fromXMLString( + const std::string& xmlString); + +public: + ~Interface(); + + /** + * Gets pointers to functions called on method call or property get/set + * request. + * + * @return Pointers to functions. + */ + const GDBusInterfaceVTable* getVTable() const; + + /** + * Gets interface description. + * + * @return Interface description. + */ + GDBusInterfaceInfo* getInfo() const; + + /** + * Sets method/property dispatcher for the interface. + * + * @param dispatcher Method call and property get/set dispatcher. + */ + void setDispatcher(Dispatcher* dispatcher); + +private: + static void onMethodCallFunc(GDBusConnection *connection, + const gchar *sender, + const gchar *objectPath, + const gchar *interfaceName, + const gchar *methodName, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer data); + + static GVariant* onPropertyGetFunc(GDBusConnection *connection, + const gchar *sender, + const gchar *objectPath, + const gchar *interfaceName, + const gchar *propertyName, + GError **error, + gpointer data); + + static gboolean onPropertySetFunc(GDBusConnection *connection, + const gchar *sender, + const gchar *objectPath, + const gchar *interfaceName, + const gchar *propertyName, + GVariant *value, + GError **error, + gpointer data); + + explicit Interface(GDBusInterfaceInfo* info); + + static const GDBusInterfaceVTable m_vTable; + + GDBusInterfaceInfo* m_info; + + Dispatcher* m_dispatcher; +}; + +} +} + +#endif // DPL_DBUS_INTERFACE_H diff --git a/modules/dbus/include/dpl/dbus/method_proxy.h b/modules/dbus/include/dpl/dbus/method_proxy.h new file mode 100644 index 0000000..3d553cf --- /dev/null +++ b/modules/dbus/include/dpl/dbus/method_proxy.h @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file method_proxy.h + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief + */ + +#ifndef DPL_DBUS_METHOD_PROXY_H +#define DPL_DBUS_METHOD_PROXY_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DPL { +namespace DBus { + +class ObjectProxy; + +/** + * Represents a remote method. + */ +template +class MethodProxy +{ +public: + ~MethodProxy() + { + g_object_unref(m_connection); + } + + /** + * Invokes remote method. + * + * @param args Input arguments for remote method. + * @return Value returned by remote method. + * @throw DBus::InvalidArgumentException If invalid argument(s) supplied. + * @throw DBus::ConnectionClosedException If connection is closed. + * @throw DBus::Exception If some other error occurs. + */ + Result operator()(const Args&... args) + { + return invoke(args...); + } + +private: + friend class ObjectProxy; + + MethodProxy(GDBusConnection* connection, + const std::string& serviceName, + const std::string& objectPath, + const std::string& interfaceName, + const std::string& methodName) + : m_connection(connection), + m_serviceName(serviceName), + m_objectPath(objectPath), + m_interfaceName(interfaceName), + m_methodName(methodName) + { + Assert(m_connection && "Connection is not set."); + + g_object_ref(m_connection); + } + + /** + * @remarks Making it a template with parameter set by default to class + * template parameter to overload on return type by utilizing + * the SFINAE concept. + */ + template + typename std::enable_if::value, R>::type + invoke(const Args&... args) + { + GVariant* parameters = serialize(args...); + + GVariant* invokeResult = invokeSync(parameters); + + R result; + + ServerDeserialization::deserialize(invokeResult, &result); + + g_variant_unref(invokeResult); + + return result; + } + + /** + * @remarks Void return type overload. + */ + template + typename std::enable_if::value>::type + invoke(const Args&... args) + { + GVariant* parameters = serialize(args...); + + GVariant* invokeResult = invokeSync(parameters); + + g_variant_unref(invokeResult); + } + + /** + * @remarks ArgsM... are the same as Args...; it has been made a template + * to make overloading/specialization possible. + */ + template + GVariant* serialize(ArgsM&&... args) + { + return ServerSerialization::serialize(std::forward(args)...); + } + + /** + * @remarks Specialization for zero-argument functions. + */ + GVariant* serialize() + { + return NULL; + } + + /** + * Calls remote method over DBus. + * + * @param parameters Input parameters for the remote method. + * @return Result returned by the remote method. + * @throw DBus::InvalidArgumentException If invalid argument(s) supplied. + * @throw DBus::ConnectionClosedException If connection is closed. + * @throw DBus::Exception If some other error occurs. + */ + GVariant* invokeSync(GVariant* parameters) + { + GError* error = NULL; + + LogPedantic("Invoking method: " << m_interfaceName << "." << m_methodName); + GVariant* result = g_dbus_connection_call_sync(m_connection, + m_serviceName.c_str(), + m_objectPath.c_str(), + m_interfaceName.c_str(), + m_methodName.c_str(), + parameters, + G_VARIANT_TYPE_TUPLE, + G_DBUS_CALL_FLAGS_NONE, + DBUS_SYNC_CALL_TIMEOUT, + NULL, + &error); + if (NULL == result) + { + std::ostringstream oss; + oss << "Error while invoking: " + << m_interfaceName << "." << m_methodName + << " <" << error->message << ">"; + std::string message = oss.str(); + + gint code = error->code; + + g_error_free(error); + + switch (code) + { + case G_IO_ERROR_INVALID_ARGUMENT: + ThrowMsg(DBus::InvalidArgumentException, message); + case G_IO_ERROR_CLOSED: + ThrowMsg(DBus::ConnectionClosedException, message); + default: + ThrowMsg(DBus::Exception, message); + } + } + + return result; + } + + /** + * Default timeout for synchronous method call. + * + * @see GIO::GDBusConnection::g_dbus_connection_call_sync() for details. + */ + static const gint DBUS_SYNC_CALL_TIMEOUT = -1; + + GDBusConnection* m_connection; + std::string m_serviceName; + std::string m_objectPath; + std::string m_interfaceName; + std::string m_methodName; +}; + +/** + * Smart pointer for MethodProxy objects. + */ +template +class MethodProxyPtr +{ +public: + explicit MethodProxyPtr(MethodProxy* method = NULL) + : m_method(method) + { + } + + Result operator()(const Args&... args) const + { + Assert(NULL != m_method.get() && "Method not set."); + + return (*m_method)(args...); + } + +private: + std::shared_ptr > m_method; +}; + +} +} + +#endif diff --git a/modules/dbus/include/dpl/dbus/object.h b/modules/dbus/include/dpl/dbus/object.h new file mode 100644 index 0000000..7731dfa --- /dev/null +++ b/modules/dbus/include/dpl/dbus/object.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file object.h + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief + */ + +#ifndef DPL_DBUS_OBJECT_H +#define DPL_DBUS_OBJECT_H + +#include +#include +#include +#include + +namespace DPL { +namespace DBus { + +class Object; +typedef std::shared_ptr ObjectPtr; + +class Object +{ +public: + /** + * Creates an object. + * + * @param path Object's path. + * @param interface Interface the object supports. + * @return Object shared pointer. + */ + static ObjectPtr create(const std::string& path, + const InterfacePtr& interface); + + /** + * Gets object's path. + * + * @return Object's path. + */ + std::string getPath() const; + + /** + * Gets object's interface. + * + * @return Object's interface. + */ + InterfacePtr getInterface() const; + +private: + Object(const std::string& path, const InterfacePtr& interface); + + std::string m_path; + InterfacePtr m_interface; +}; + +} +} + +#endif // WRT_SRC_DBUS_OBJECT_H diff --git a/modules/dbus/include/dpl/dbus/object_proxy.h b/modules/dbus/include/dpl/dbus/object_proxy.h new file mode 100644 index 0000000..3d727c0 --- /dev/null +++ b/modules/dbus/include/dpl/dbus/object_proxy.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file object_proxy.h + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief + */ + +#ifndef DPL_DBUS_OBJECT_PROXY_H +#define DPL_DBUS_OBJECT_PROXY_H + +#include +#include +#include +#include + +namespace DPL { +namespace DBus { + +class Connection; + +/** + * Represents a remote object attached to a DBus service. + */ +class ObjectProxy +{ +public: + ~ObjectProxy(); + + /** + * Creates method proxy object. + * + * The object is used to call remote methods. + * + * @param interface Name of the DBus interface. + * @param name Name of the method to call. + * @return Proxy to remote method. + * @throw DBus::ConnectionClosedException If connection is closed. + */ + template + MethodProxyPtr createMethodProxy( + const std::string& interface, + const std::string& name) + { + if (g_dbus_connection_is_closed(m_connection)) + { + ThrowMsg(DBus::ConnectionClosedException, "Connection closed."); + } + + return MethodProxyPtr( + new MethodProxy(m_connection, + m_serviceName, + m_objectPath, + interface, + name)); + } + +private: + friend class Connection; + + ObjectProxy(GDBusConnection* connection, + const std::string& serviceName, + const std::string& objectPath); + + GDBusConnection* m_connection; + std::string m_serviceName; + std::string m_objectPath; +}; + +} +} + +#endif diff --git a/modules/dbus/include/dpl/dbus/server.h b/modules/dbus/include/dpl/dbus/server.h new file mode 100644 index 0000000..39220ae --- /dev/null +++ b/modules/dbus/include/dpl/dbus/server.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file server.h + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief + */ + +#ifndef DPL_DBUS_SERVER_H +#define DPL_DBUS_SERVER_H + +#include +#include +#include +#include +#include +#include + +namespace DPL +{ +namespace DBus +{ + +namespace ServerEvents +{ +/** + * Emitted when new connection is accepted. + * + * Arg0 Accepted connection. + * + * @remarks If this event is processed on separate thread than that thread + * should run GLib main loop if one wants to e.g. register DBus + * objects during this event processing. + */ +DECLARE_GENERIC_EVENT_1(NewConnectionEvent, ConnectionPtr) +} + +class Server; +typedef std::shared_ptr ServerPtr; + +/** + * Class acting as a server for peer to peer connections over DBus. + */ +class Server : public DPL::Event::EventSupport +{ +public: + /** + * Creates server. + * + * @param address Address the server should listen on. + * @return Server. + */ + static ServerPtr create(const std::string& address); + + ~Server(); + + /** + * Starts the server. + */ + void start(); + + /** + * Stops the server. + */ + void stop(); + +protected: + explicit Server(GDBusServer* server); + +private: + static gboolean onNewConnection(GDBusServer* server, + GDBusConnection* connection, + gpointer data); + + GDBusServer* m_server; +}; + +} +} + +#endif // DPL_DBUS_SERVER_H diff --git a/modules/dbus/src/connection.cpp b/modules/dbus/src/connection.cpp new file mode 100644 index 0000000..e50faa8 --- /dev/null +++ b/modules/dbus/src/connection.cpp @@ -0,0 +1,293 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file connection.cpp + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief + */ + +#include +#include +#include +#include + +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(data); + + LogPedantic("Emitting service name acquired event: " << serviceName); + + ConnectionEvents::ServiceNameAcquiredEvent event(serviceName); + self->DPL::Event::EventSupport:: + EmitEvent(event, DPL::Event::EmitMode::Queued); +} + +void Connection::onServiceNameLost(GDBusConnection* /*connection*/, + const gchar* serviceName, + gpointer data) +{ + Assert(data && "Connection should not be NULL"); + + Connection* self = static_cast(data); + + LogPedantic("Emitting service name lost event: " << serviceName); + + ConnectionEvents::ServiceNameLostEvent event(serviceName); + self->DPL::Event::EventSupport:: + EmitEvent(event, DPL::Event::EmitMode::Queued); +} + +void Connection::onConnectionClosed(GDBusConnection* /*connection*/, + gboolean peerVanished, + GError* error, + gpointer data) +{ + Assert(NULL != data && "Connection cannot be NULL"); + + Connection* self = static_cast(data); + + if ((NULL == error) && (FALSE == peerVanished)) + { + // Connection closed by this. + } + else if (NULL != error) + { + std::string message = error->message; + + g_error_free(error); + + if (TRUE == peerVanished) + { + // Connection closed by remote host. + ConnectionEvents::ConnectionBrokenEvent event(message); + self->DPL::Event::EventSupport:: + EmitEvent(event, DPL::Event::EmitMode::Queued); + } + else + { + // Invalid or malformed data on connection. + ConnectionEvents::ConnectionInvalidEvent event(message); + self->DPL::Event::EventSupport:: + EmitEvent(event, DPL::Event::EmitMode::Queued); + } + } +} + +} +} diff --git a/modules/dbus/src/dispatcher.cpp b/modules/dbus/src/dispatcher.cpp new file mode 100644 index 0000000..ca1bbab --- /dev/null +++ b/modules/dbus/src/dispatcher.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file dispatcher.cpp + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief + */ + +#include + +namespace DPL +{ +namespace DBus +{ + +Dispatcher::~Dispatcher() { } + +GVariant* Dispatcher::onPropertyGet(GDBusConnection* /*connection*/, + const gchar* /*sender*/, + const gchar* /*objectPath*/, + const gchar* /*interfaceName*/, + const gchar* /*propertyName*/, + GError** /*error*/) +{ + return NULL; +} + +gboolean Dispatcher::onPropertySet(GDBusConnection* /*connection*/, + const gchar* /*sender*/, + const gchar* /*objectPath*/, + const gchar* /*interfaceName*/, + const gchar* /*propertyName*/, + GVariant* /*value*/, + GError** /*error*/) +{ + return false; +} + +} +} diff --git a/modules/dbus/src/interface.cpp b/modules/dbus/src/interface.cpp new file mode 100644 index 0000000..248ac6d --- /dev/null +++ b/modules/dbus/src/interface.cpp @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file interface.cpp + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief + */ +#include +#include +#include +#include +#include + +namespace DPL { +namespace DBus { + +const GDBusInterfaceVTable Interface::m_vTable = +{ + Interface::onMethodCallFunc, + Interface::onPropertyGetFunc, + Interface::onPropertySetFunc, + {0, 0, 0, 0, 0, 0, 0, 0} +}; + +std::vector Interface::fromXMLString(const std::string& xmlString) +{ + GError* error = NULL; + + GDBusNodeInfo* nodeInfo = g_dbus_node_info_new_for_xml(xmlString.c_str(), + &error); + if (NULL == nodeInfo) + { + std::string message; + if (NULL != error) + { + message = error->message; + g_error_free(error); + } + ThrowMsg(DPL::DBus::Exception, + "Error parsing node info <" << message << ">"); + } + + std::vector result; + + GDBusInterfaceInfo** interface = nodeInfo->interfaces; + while (NULL != *interface) + { + result.push_back(InterfacePtr(new Interface(*interface))); + ++interface; + } + + g_dbus_node_info_unref(nodeInfo); + + return result; +} + +Interface::Interface(GDBusInterfaceInfo* info) + : m_info(info) +{ + g_dbus_interface_info_ref(m_info); +} + +Interface::~Interface() +{ + g_dbus_interface_info_unref(m_info); +} + +const GDBusInterfaceVTable* Interface::getVTable() const +{ + return &m_vTable; +} + +GDBusInterfaceInfo* Interface::getInfo() const +{ + return m_info; +} + +void Interface::setDispatcher(Dispatcher* dispatcher) +{ + m_dispatcher = dispatcher; +} + +void Interface::onMethodCallFunc(GDBusConnection *connection, + const gchar *sender, + const gchar *objectPath, + const gchar *interfaceName, + const gchar *methodName, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer data) +{ + Assert(NULL != data && "Interface cannot be NULL."); + Interface* self = static_cast(data); + + // TODO Verify interface name. + + if (NULL != self->m_dispatcher) + { + try + { + self->m_dispatcher->onMethodCall(connection, + sender, + objectPath, + interfaceName, + methodName, + parameters, + invocation); + } + catch (const DPL::Exception& /*ex*/) + { + // TODO Support for errors. + } + } +} + +GVariant* Interface::onPropertyGetFunc(GDBusConnection *connection, + const gchar *sender, + const gchar *objectPath, + const gchar *interfaceName, + const gchar *propertyName, + GError **error, + gpointer data) +{ + Assert(NULL != data && "Interface cannot be NULL."); + Interface* self = static_cast(data); + + // TODO Verify interface name. + + if (NULL != self->m_dispatcher) + { + try + { + // TODO Check if NULL is returned, if so set error variable. + return self->m_dispatcher->onPropertyGet(connection, + sender, + objectPath, + interfaceName, + propertyName, + error); + } + catch (const DPL::Exception& /*ex*/) + { + // TODO Support for errors. + } + } + + // TODO Set error. + + return NULL; +} + +gboolean Interface::onPropertySetFunc(GDBusConnection *connection, + const gchar *sender, + const gchar *objectPath, + const gchar *interfaceName, + const gchar *propertyName, + GVariant *value, + GError **error, + gpointer data) +{ + Assert(NULL != data && "Interface cannot be NULL."); + Interface* self = static_cast(data); + + // TODO Verify interface name. + + if (NULL != self->m_dispatcher) + { + try + { + return self->m_dispatcher->onPropertySet(connection, + sender, + objectPath, + interfaceName, + propertyName, + value, + error); + } + catch (const DPL::Exception& /*ex*/) + { + // TODO Support for errors. + } + } + + // TODO Set error. + + return false; +} + +} +} diff --git a/modules/dbus/src/object.cpp b/modules/dbus/src/object.cpp new file mode 100644 index 0000000..1c46018 --- /dev/null +++ b/modules/dbus/src/object.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file object.cpp + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief + */ + +#include + +namespace DPL { +namespace DBus { + +ObjectPtr Object::create(const std::string& path, const InterfacePtr& interface) +{ + return ObjectPtr(new Object(path, interface)); +} + +std::string Object::getPath() const +{ + return m_path; +} + +InterfacePtr Object::getInterface() const +{ + return m_interface; +} + +Object::Object(const std::string& path, const InterfacePtr& interface) + : m_path(path), + m_interface(interface) +{ +} + +} +} \ No newline at end of file diff --git a/modules/dbus/src/object_proxy.cpp b/modules/dbus/src/object_proxy.cpp new file mode 100644 index 0000000..22275a1 --- /dev/null +++ b/modules/dbus/src/object_proxy.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file object_proxy.cpp + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief + */ + +#include + +namespace DPL { +namespace DBus { + +ObjectProxy::ObjectProxy(GDBusConnection* connection, + const std::string& serviceName, + const std::string& objectPath) + : m_connection(connection), + m_serviceName(serviceName), + m_objectPath(objectPath) +{ + g_object_ref(m_connection); +} + +ObjectProxy::~ObjectProxy() +{ + g_object_unref(m_connection); +} + +} +} \ No newline at end of file diff --git a/modules/dbus/src/server.cpp b/modules/dbus/src/server.cpp new file mode 100644 index 0000000..08292f5 --- /dev/null +++ b/modules/dbus/src/server.cpp @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file server.cpp + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief + */ + +#include +#include +#include + +namespace DPL { +namespace DBus { + +ServerPtr Server::create(const std::string& address) +{ + GError* error = NULL; + + int flags = G_DBUS_SERVER_FLAGS_NONE | + G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS; + + gchar* serverId = g_dbus_generate_guid(); + + GDBusServer* server = g_dbus_server_new_sync( + address.c_str(), + static_cast(flags), + serverId, + NULL, + NULL, + &error); + g_free(serverId); + + if (NULL == server) + { + std::string message; + if (NULL != error) + { + message = error->message; + g_error_free(error); + } + + ThrowMsg(DPL::Exception, "Error on server creation: " << message); + } + + return ServerPtr(new Server(server)); +} + +Server::Server(GDBusServer* server) + : m_server(server) +{ +} + +Server::~Server() +{ + if (g_dbus_server_is_active(m_server)) + { + stop(); + } + g_object_unref(m_server); +} + +void Server::start() +{ + 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(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:: + EmitEvent(event, DPL::Event::EmitMode::Blocking); + + return TRUE; +} + +} +} \ No newline at end of file diff --git a/modules/event/config.cmake b/modules/event/config.cmake new file mode 100644 index 0000000..07831f0 --- /dev/null +++ b/modules/event/config.cmake @@ -0,0 +1,63 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# @file 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 +) diff --git a/modules/event/include/dpl/event/abstract_event_call.h b/modules/event/include/dpl/event/abstract_event_call.h new file mode 100644 index 0000000..e199897 --- /dev/null +++ b/modules/event/include/dpl/event/abstract_event_call.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_event_call.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of abstract event call + */ +#ifndef DPL_ABSTRACT_EVENT_CALL_H +#define DPL_ABSTRACT_EVENT_CALL_H + +#include + +namespace DPL +{ +namespace Event +{ + + +class AbstractEventCall + : private Noncopyable +{ +public: + /** + * Constructor + */ + explicit AbstractEventCall(); + + /** + * Destructor + */ + virtual ~AbstractEventCall(); + + /** + * Call abstract event call + */ + virtual void Call() = 0; +}; + +} +} // namespace DPL + +#endif // DPL_ABSTRACT_EVENT_CALL_H diff --git a/modules/event/include/dpl/event/abstract_event_dispatcher.h b/modules/event/include/dpl/event/abstract_event_dispatcher.h new file mode 100644 index 0000000..ddd76ad --- /dev/null +++ b/modules/event/include/dpl/event/abstract_event_dispatcher.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_event_dispatcher.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of abstract event dispatcher + */ +#ifndef DPL_ABSTRACT_EVENT_DISPATCHER_H +#define DPL_ABSTRACT_EVENT_DISPATCHER_H + +#include +#include + +namespace DPL +{ +namespace Event +{ + +class AbstractEventDispatcher + : private Noncopyable +{ +public: + /** + * Constructor + */ + explicit AbstractEventDispatcher(); + + /** + * Destructor + */ + virtual ~AbstractEventDispatcher(); + + /** + * Add abstract event call to abstract event dispatcher + * + * @param[in] abstractEventCall Pointer to abstract event call to add + * @return none + */ + virtual void AddEventCall(AbstractEventCall *abstractEventCall) = 0; + + /** + * Add abstract timed event call to abstract event dispatcher + * + * @param[in] abstractEventCall Pointer to abstract event call to add + * @param[in] dueTime Due time for timed event in seconds + * @return none + */ + virtual void AddTimedEventCall(AbstractEventCall *abstractEventCall, double dueTime) = 0; +}; + +} +} // namespace DPL + +#endif // DPL_ABSTRACT_EVENT_DISPATCHER_H diff --git a/modules/event/include/dpl/event/controller.h b/modules/event/include/dpl/event/controller.h new file mode 100644 index 0000000..1c5c75c --- /dev/null +++ b/modules/event/include/dpl/event/controller.h @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file controller.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of MVC controller + */ +#ifndef DPL_CONTROLLER_H +#define DPL_CONTROLLER_H + +#include +#include +#include +#include +#include + +namespace DPL +{ +namespace Event +{ + +template +class ControllerEventHandler + : public EventListener, + private EventSupport +{ +private: + bool m_touched; + +public: + ControllerEventHandler() + : m_touched(false) + { + EventSupport::AddListener(this); + } + + virtual ~ControllerEventHandler() + { + EventSupport::RemoveListener(this); + } + + void PostEvent(const EventType &event) + { + Assert(m_touched && "Default context not inherited. Call Touch() to inherit one."); + EventSupport::EmitEvent(event, EmitMode::Queued); + } + + void PostTimedEvent(const EventType &event, double dueTime) + { + Assert(m_touched && "Default context not inherited. Call Touch() to inherit one."); + EventSupport::EmitEvent(event, EmitMode::Deffered, dueTime); + } + + void PostSyncEvent(const EventType &event) + { + Assert(m_touched && "Default context not inherited. Call Touch() to inherit one."); + + // Check calling context + EventSupport::EmitEvent(event, EmitMode::Blocking); + } + + void SwitchToThread(Thread *thread) + { + Assert(m_touched && "Default context not inherited. Call Touch() to inherit one."); + EventSupport::SwitchListenerToThread(this, thread); + } + + void Touch() + { + m_touched = true; + EventSupport::SwitchListenerToThread(this, Thread::GetCurrentThread()); + } +}; + +template +class Controller + : public Controller, + public ControllerEventHandler +{ +public: + typedef typename EventTypeList::Head EventType; + +public: + Controller() + { + } + + virtual ~Controller() + { + } + + virtual void SwitchToThread(Thread *thread) + { + ControllerEventHandler::SwitchToThread(thread); + Controller::SwitchToThread(thread); + } + + virtual void Touch() + { + ControllerEventHandler::Touch(); + Controller::Touch(); + } +}; + +template<> +class Controller::Type> +{ +public: + Controller() + { + } + + virtual ~Controller() + { + } + + virtual void SwitchToThread(Thread *thread) + { + (void)thread; + } + + virtual void Touch() + { + } +}; + +} +} // namespace DPL + +// Utilities +#define CONTROLLER_POST_EVENT(Name, EventArg) Name##Singleton::Instance().DPL::Event::ControllerEventHandler<__typeof__ EventArg>::PostEvent(EventArg) +#define CONTROLLER_POST_TIMED_EVENT(Name, EventArg, DueTime) Name##Singleton::Instance().DPL::Event::ControllerEventHandler<__typeof__ EventArg>::PostTimedEvent(EventArg, DueTime) +#define CONTROLLER_POST_SYNC_EVENT(Name, EventArg) Name##Singleton::Instance().DPL::Event::ControllerEventHandler<__typeof__ EventArg>::PostSyncEvent(EventArg) + +#endif // DPL_CONTROLLER_H diff --git a/modules/event/include/dpl/event/event_delivery.h b/modules/event/include/dpl/event/event_delivery.h new file mode 100644 index 0000000..f4c893c --- /dev/null +++ b/modules/event/include/dpl/event/event_delivery.h @@ -0,0 +1,338 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Event delivery system + * + * Sample usages: + * + * I. Listening for standard predefined notifications + * + * class MyClass + * : public EventListener + * { + * void OnEventReceived(const EventMessages::RoamingChanged& event) + * { + * std::cout << "Roaming is now " << event.GetRoamingEnabled() ? "ENABLED" : "DISABLED" << std::endl; + * } + * + * public: + * MyClass() + * { + * EventDeliverySystem::AddListener(this); + * } + * + * virtual ~MyClass() + * { + * EventDeliverySystem::RemoveListener(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 + * { + * void OnEventReceived(const MyEvent &event) + * { + * std::cout << "Event contents: " << event.GetArg0() << ", " << event.GetArg1() << std::endl; + * } + * + * public: + * MyClass() + * { + * EventDeliverySystem::AddListener(this); + * } + * + * virtual ~MyClass() + * { + * EventDeliverySystem::RemoveListener(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 +class EventDeliverySystemPublisher + : private EventSupport + , public AbstractEventDeliverySystemPublisher +{ +public: + typedef typename EventSupport::EventListenerType EventListenerType; + +private: + friend class EventDeliverySystem; + + EventDeliverySystemPublisher(EventListenerType *eventListener) + : m_eventListener(eventListener) + { + EventSupport::AddListener(m_eventListener); + } + + EventListenerType *m_eventListener; + +public: + ~EventDeliverySystemPublisher() + { + EventSupport::RemoveListener(m_eventListener); + } + + void PublishEvent(const EventType &event) + { + EmitEvent(event, EmitMode::Queued); + } + + EventListenerType *GetListener() const + { + return m_eventListener; + } +}; + +template +class EventDeliverySystemTraits +{ +public: + typedef Type EventType; + typedef EventDeliverySystemPublisher PublisherType; + typedef typename PublisherType::EventListenerType EventListenerType; + typedef SharedPtr PublisherPtrType; + typedef std::list PublisherPtrContainerType; +}; + +class EventDeliverySystem + : private Noncopyable +{ +private: + typedef SharedPtr AbstractPublisherPtrType; + typedef std::list AbstractPublisherPtrContainerType; + typedef AbstractPublisherPtrContainerType::const_iterator AbstractPublisherPtrContainerTypeConstIterator; + typedef AbstractPublisherPtrContainerType::iterator AbstractPublisherPtrContainerTypeIterator; + typedef std::map AbstractPublisherPtrContainerMapType; + + template + 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 + static AbstractPublisherPtrContainerType &GetPublisherContainerRef() + { + std::string typeId = typeid(EventType).name(); + + //FIXME: problem with linking per compilation unit won't hurt this check? + static CrtDeleteCheck crtDeleteCheck(m_publishers[typeId]); + (void)crtDeleteCheck; + + return m_publishers[typeId]; + } + + template + static typename EventDeliverySystemTraits::PublisherPtrContainerType GetPublisherContainer() + { + std::string typeId = typeid(EventType).name(); + typedef typename EventDeliverySystemTraits::PublisherPtrContainerType PublisherContainerType; + typedef typename EventDeliverySystemTraits::PublisherType PublisherType; + typedef typename EventDeliverySystemTraits::PublisherPtrType PublisherPtrType; + + AbstractPublisherPtrContainerType eventPublishers = m_publishers[typeId]; + PublisherContainerType publisherContainer; + + FOREACH(iterator, eventPublishers) + { + PublisherPtrType publisher = + StaticPointerCast(*iterator); + publisherContainer.push_back(publisher); + } + + return publisherContainer; + } + + // Detail access + template + static void Inject(const EventType &event) + { + typedef typename EventDeliverySystemTraits::PublisherPtrContainerType PublisherContainerType; + typedef typename EventDeliverySystemTraits::PublisherPtrType PublisherPtrType; + + PublisherContainerType publisherContainer = GetPublisherContainer(); + typename PublisherContainerType::iterator iterator; + + for (iterator = publisherContainer.begin(); iterator != publisherContainer.end(); ++iterator) + { + PublisherPtrType &publisher = *iterator; + publisher->PublishEvent(event); + } + } + + template + class PublisherPtrContainerListenerPredicate + { + public: + typedef EventListener EventListenerType; + + private: + EventListenerType *m_listener; + + public: + PublisherPtrContainerListenerPredicate(EventListenerType *listener) + : m_listener(listener) + { + } + + bool operator()(const AbstractPublisherPtrType &publisher) const + { + return StaticPointerCast::PublisherType>(publisher)->GetListener() == m_listener; + } + }; + + friend class EventDeliverySystemInjector; + +public: + virtual ~EventDeliverySystem() + { + } + + template + static void AddListener(EventListener *listener) + { + typedef typename EventDeliverySystemTraits::PublisherType PublisherType; + typedef typename EventDeliverySystemTraits::PublisherPtrType PublisherPtrType; + typedef typename EventDeliverySystemTraits::PublisherPtrContainerType PublisherPtrContainerType; + + typedef PublisherPtrContainerListenerPredicate PublisherPtrContainerListenerPredicateType; + + AbstractPublisherPtrContainerType &publisherContainer = GetPublisherContainerRef(); + 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 + static void RemoveListener(EventListener *listener) + { + typedef typename EventDeliverySystemTraits::PublisherType PublisherType; + typedef typename EventDeliverySystemTraits::PublisherPtrType PublisherPtrType; + typedef typename EventDeliverySystemTraits::PublisherPtrContainerType PublisherPtrContainerType; + + typedef PublisherPtrContainerListenerPredicate PublisherPtrContainerListenerPredicateType; + + AbstractPublisherPtrContainerType &publisherContainer = GetPublisherContainerRef(); + + 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 + static void Publish(const EventType &event) + { + m_detailSystem.Publish(event); + } +}; + +} +} // namespace DPL + +#endif // DPL_EVENT_DELIVERY_H diff --git a/modules/event/include/dpl/event/event_delivery_detail.h b/modules/event/include/dpl/event/event_delivery_detail.h new file mode 100644 index 0000000..b5907d0 --- /dev/null +++ b/modules/event/include/dpl/event/event_delivery_detail.h @@ -0,0 +1,306 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 +#include +#include +#include +#include +#include + +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 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 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 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 + void Publish(const EventMessages::Generic1 &event) + { + std::string eventName = std::string(NOTI_EVENT_ID_GENERIC_1) + event.GetGcid(); + SignalGenericNoti(eventName, event.SerializeType()); + } + + template + void Publish(const EventMessages::Generic2 &event) + { + std::string eventName = std::string(NOTI_EVENT_ID_GENERIC_2) + event.GetGcid(); + SignalGenericNoti(eventName, event.SerializeType()); + } + + template + void Publish(const EventMessages::Generic3 &event) + { + std::string eventName = std::string(NOTI_EVENT_ID_GENERIC_3) + event.GetGcid(); + SignalGenericNoti(eventName, event.SerializeType()); + } + + template + void Publish(const EventMessages::Generic4 &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 + void Listen(const EventMessages::Generic1 &event) + { + std::string eventName = std::string(NOTI_EVENT_ID_GENERIC_1) + event.GetGcid(); + RegisterFileNotiCallback(event.GetGcid(), eventName); + } + + template + void Listen(const EventMessages::Generic2 &event) + { + std::string eventName = std::string(NOTI_EVENT_ID_GENERIC_2) + event.GetGcid(); + RegisterFileNotiCallback(event.GetGcid(), eventName); + } + + template + void Listen(const EventMessages::Generic3 &event) + { + std::string eventName = std::string(NOTI_EVENT_ID_GENERIC_3) + event.GetGcid(); + RegisterFileNotiCallback(event.GetGcid(), eventName); + } + + template + void Listen(const EventMessages::Generic4 &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 + void Unlisten(const EventMessages::Generic1 &event) + { + std::string eventName = std::string(NOTI_EVENT_ID_GENERIC_1) + event.GetGcid(); + UnregisterFileNotiCallback(eventName); + } + + template + void Unlisten(const EventMessages::Generic2 &event) + { + std::string eventName = std::string(NOTI_EVENT_ID_GENERIC_2) + event.GetGcid(); + UnregisterFileNotiCallback(eventName); + } + + template + void Unlisten(const EventMessages::Generic3 &event) + { + std::string eventName = std::string(NOTI_EVENT_ID_GENERIC_3) + event.GetGcid(); + UnregisterFileNotiCallback(eventName); + } + + template + void Unlisten(const EventMessages::Generic4 &event) + { + std::string eventName = std::string(NOTI_EVENT_ID_GENERIC_4) + event.GetGcid(); + UnregisterFileNotiCallback(eventName); + } +}; + +} +} // namespace DPL + +#endif // DPL_EVENT_DELIVERY_DETAIL_EFL_H diff --git a/modules/event/include/dpl/event/event_delivery_injector.h b/modules/event/include/dpl/event/event_delivery_injector.h new file mode 100644 index 0000000..546b4c3 --- /dev/null +++ b/modules/event/include/dpl/event/event_delivery_injector.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 +#include +#include +#include +#include +#include + +namespace DPL +{ +namespace Event +{ + +class EventDeliverySystemInjector + : private Noncopyable +{ +private: + EventDeliverySystemInjector() + { + } + + typedef void (*MetaCall)(const std::string &metaData); + typedef std::map 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 + 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 diff --git a/modules/event/include/dpl/event/event_delivery_messages.h b/modules/event/include/dpl/event/event_delivery_messages.h new file mode 100644 index 0000000..046738d --- /dev/null +++ b/modules/event/include/dpl/event/event_delivery_messages.h @@ -0,0 +1,923 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 +#include +#include +#include + +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 + void SerializeField(std::ostream &stream, const Type &type) const + { + stream << type; + } + + void SerializeSeparator(std::ostream &stream) const + { + stream << SEPARATOR; + } + + std::vector SplitStream(const std::string &stream) const + { + char separator[2] = {}; + separator[0] = SEPARATOR; + std::vector 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 + 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 +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 splitVector = SplitStream(stream); + if (splitVector.size() != 1) + return; + std::istringstream s0(splitVector[0]); + m_arg0 = DeserializeField(s0, Arg0()); + } +}; + +template +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 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 +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 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 +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 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 \ + { \ + public: \ + EventType() : DPL::Event::EventMessages::Generic1(EventType##_StaticDeclarator::Name) {} \ + EventType(const Arg0 &arg0) : DPL::Event::EventMessages::Generic1(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 \ + { \ + public: \ + EventType() : DPL::Event::EventMessages::Generic2(EventType##_StaticDeclarator::Name) {} \ + EventType(const Arg0 &arg0, const Arg1 &arg1) : DPL::Event::EventMessages::Generic2(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 \ + { \ + public: \ + EventType() : DPL::Event::EventMessages::Generic3(EventType##_StaticDeclarator::Name) {} \ + EventType(const Arg0 &arg0, const Arg1 &arg1, const Arg2 &arg2) : DPL::Event::EventMessages::Generic3(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 \ + { \ + public: \ + EventType() : DPL::Event::EventMessages::Generic4(EventType##_StaticDeclarator::Name) {} \ + EventType(const Arg0 &arg0, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3) : DPL::Event::EventMessages::Generic4(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 diff --git a/modules/event/include/dpl/event/event_listener.h b/modules/event/include/dpl/event/event_listener.h new file mode 100644 index 0000000..bc7ecbf --- /dev/null +++ b/modules/event/include/dpl/event/event_listener.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file event_listener.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of MVC event listener + */ +#ifndef DPL_EVENT_LISTENER_H +#define DPL_EVENT_LISTENER_H + +#include + +namespace DPL +{ +namespace Event +{ + +template +class EventListener + : private Noncopyable +{ +public: + EventListener() + { + } + + virtual ~EventListener() + { + } + + virtual void OnEventReceived(const EventType &event) = 0; +}; + +} +} // namespace DPL + +#endif // DPL_EVENT_LISTENER_H diff --git a/modules/event/include/dpl/event/event_support.h b/modules/event/include/dpl/event/event_support.h new file mode 100644 index 0000000..3aaab81 --- /dev/null +++ b/modules/event/include/dpl/event/event_support.h @@ -0,0 +1,788 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file event_support.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of MVC event support + */ +#ifndef DPL_EVENT_SUPPORT_H +#define DPL_EVENT_SUPPORT_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DPL +{ +namespace Event +{ +namespace EmitMode +{ +enum Type +{ + Auto, ///< If calling thread is the same as receiver's use + ///< direct call, otherwise call is queued + + Queued, ///< Call is always queued + + Blocking, ///< If calling thread is the same as receiver's use + ///< direct call, otherwise call is queued and blocking + + Deffered ///< Call is always queued for a period of time +}; +} // namespace EmitMode + +template +class EventSupport + : private Noncopyable +{ +public: + typedef EventSupport EventSupportType; + + typedef EventListener EventListenerType; + typedef FastDelegate1 DelegateType; + + class EventSupportData; // Forward declaration + typedef EventSupportData *EventSupportDataPtr; + +private: + typedef typename GenericEventCall:: + template Rebind:: + Other GenericEventCallType; + + // Event listener list + typedef std::map EventListenerList; + EventListenerList m_eventListenerList; + + // Delegate list + typedef std::map DelegateList; + DelegateList m_delegateList; + + // Event support operation mutex + Mutex m_listenerDelegateMutex; + + // Dedicated instance of thread event dispatcher + ThreadEventDispatcher m_threadEventDispatcher; + + // Guard destruction of event support in event handler + Atomic m_guardedCallInProgress; + + // Events created by this support + typedef std::list EventCallList; + EventCallList m_eventsList; + + // Events list mutex + Mutex m_eventListMutex; + +public: + class EventSupportData + { + private: + typedef void (EventSupportType::*ReceiveAbstractEventCallMethod)( + const EventType &event, + EventListenerType *eventListener, + DelegateType delegate, + WaitableEvent *synchronization); + + EventSupportType *m_eventSupport; + ReceiveAbstractEventCallMethod m_method; + typename EventCallList::iterator m_iterator; + + //TODO: Add dispatcher iterator to remove events from + // framework/thread's event queue + WaitableEvent *m_synchronization; + + Mutex m_dataMutex; + + public: + EventSupportData(EventSupportType *support, + ReceiveAbstractEventCallMethod method, + WaitableEvent *synchronization) + : m_eventSupport(support), + m_method(method), + m_synchronization(synchronization) + { + } + + ~EventSupportData() + { + Mutex::ScopedLock lock(&m_dataMutex); + + if (!m_eventSupport) + { + LogPedantic("EventSupport for this call does not exist"); + return; + } + + m_eventSupport->RemoveEventCall(m_iterator); + } + + // TODO: Make private and make EventSupport friend + void SetIterator(typename EventCallList::iterator iter) + { + m_iterator = iter; + } + + // This method at the end destroys this as it will not be used anymore + void CallAndDestroy(const EventType &event, + EventListenerType *listener, + DelegateType delegate) + { + { + Mutex::ScopedLock lock(&m_dataMutex); + + if (m_eventSupport != NULL) + { + (*m_eventSupport.*m_method)(event, + listener, + delegate, + m_synchronization); + } + else + { + LogPedantic("EventSupport for this call does not " + "exist anymore. Ignored."); + } + + // releasing mutex lock + } + + // EventSupportData object is no more used. + // It can be safely destroyed now. + delete this; + } + + void Reset() + { + LogPedantic("Reseting my EventSupport"); + + Mutex::ScopedLock lock(&m_dataMutex); + m_eventSupport = NULL; + } + }; + +private: + GenericEventCallType *RegisterEventCall(const EventType &event, + EventListenerType *eventListener, + DelegateType delegate, + WaitableEvent *waitableEvent) + { + LogPedantic("Create and Register EventCall in EventSupport"); + + Mutex::ScopedLock lock(&m_eventListMutex); + + EventSupportDataPtr supportData = + new EventSupportData( + this, + &EventSupportType::ReceiveAbstractEventCall, + waitableEvent); + + GenericEventCallType *eventCall = + new GenericEventCallType(supportData, eventListener, + delegate, event); + + typename EventCallList::iterator eventCallIter = + m_eventsList.insert(m_eventsList.end(), eventCall); + + supportData->SetIterator(eventCallIter); + + return eventCall; + } + + void RemoveEventCall(typename EventCallList::iterator eventIterator) + { + Mutex::ScopedLock lock(&m_eventListMutex); + + LogPedantic("Removing event call from EventSupport"); + + m_eventsList.erase(eventIterator); + } + + // Note: Reentrant metod + void GuardedEventCall(const EventType &event, + EventListenerType *eventListener) + { + LogPedantic("Guarded event listener call..."); + + ++m_guardedCallInProgress; + + UNHANDLED_EXCEPTION_HANDLER_BEGIN + { + eventListener->OnEventReceived(event); + } + UNHANDLED_EXCEPTION_HANDLER_END + + --m_guardedCallInProgress; + + LogPedantic("Guarded event listener finished"); + } + + // Note: Reentrant metod + void GuardedEventCall(const EventType &event, + DelegateType delegate) + { + LogPedantic("Guarded delegate call..."); + + ++m_guardedCallInProgress; + + UNHANDLED_EXCEPTION_HANDLER_BEGIN + { + delegate(event); + } + UNHANDLED_EXCEPTION_HANDLER_END + + --m_guardedCallInProgress; + + LogPedantic("Guarded delegate call finished"); + } + + void ReceiveAbstractEventCall(const EventType &event, + EventListenerType *eventListener, + DelegateType delegate, + WaitableEvent *synchronization) + { + LogPedantic("Received abstract event call method"); + + Thread *targetThread; + + // Listener might have been removed, ensure that it still exits + if (eventListener != NULL) + { + Mutex::ScopedLock lock(&m_listenerDelegateMutex); + + typename EventListenerList::iterator iterator = + m_eventListenerList.find(eventListener); + + if (iterator == m_eventListenerList.end()) + { + LogPedantic("Abstract event call listener disappeared." + "Event ignored."); + + // Even though, synchronize caller if needed + if (synchronization != NULL) + synchronization->Signal(); + + return; + } + + // Get target thread id + targetThread = iterator->second; + } + else + { + // Delegate might have been removed, ensure that it still exits + Mutex::ScopedLock lock(&m_listenerDelegateMutex); + + typename DelegateList::iterator iterator = + m_delegateList.find(delegate); + + if (iterator == m_delegateList.end()) + { + LogPedantic("Abstract event call delegate disappeared." + "Event ignored."); + + // Even though, synchronize caller if needed + if (synchronization != NULL) + synchronization->Signal(); + + return; + } + + // Get target thread id + targetThread = iterator->second; + } + + // Ensure that we are now in proper thread now + if (targetThread != Thread::GetCurrentThread()) + { + LogPedantic("Detected event dispatching ping-pong scenario"); + + // Retry if it was not synchronized + if (synchronization == NULL) + { + // Cheat with event delivery + EmitEvent(event, EmitMode::Queued); + + LogPedantic("Ping-Pong: Resent as queued event"); + } + else + { + // There is a problem + // Developer did something nasty, and we will not clean up his mess + synchronization->Signal(); + + LogPedantic("### Ping-Pong: Failed to deliver synchronized" + "event in ping-pong scenario!"); + } + + return; + } + + // Guard listener code for exceptions + if (eventListener != NULL) + GuardedEventCall(event, eventListener); + else + GuardedEventCall(event, delegate); + + // Release caller if synchronizing + if (synchronization != NULL) + synchronization->Signal(); + } + +protected: + void EmitEvent(const EventType &event, + EmitMode::Type mode = EmitMode::Queued, + double dueTime = 0.0) + { + // Emit event, and retrieve later in current context to dispatch + ScopedPtr lock( + new Mutex::ScopedLock(&m_listenerDelegateMutex)); + + // Show some info + switch (mode) + { + case EmitMode::Auto: + LogPedantic("Emitting AUTO event..."); + break; + + case EmitMode::Queued: + LogPedantic("Emitting QUEUED event..."); + break; + + case EmitMode::Blocking: + LogPedantic("Emitting BLOCKING event..."); + break; + + case EmitMode::Deffered: + LogPedantic("Emitting DEFFERED event..."); + break; + + default: + break; + } + + // In some configurations there is a barrier + std::vector synchronizationBarrier; + + // Emit to all listeners + FOREACH(iterator, m_eventListenerList) + { + // Switch to proper dispatcher and emit event + AbstractEventDispatcher *dispatcher = NULL; + + if (iterator->second == NULL) + { + // Send to main thread + LogPedantic("Sending event to main dispatcher"); + dispatcher = &GetMainEventDispatcherInstance(); + } + else + { + // Setup thread dispatcher, and send to proper thread + LogPedantic("Sending event to thread dispatcher"); + m_threadEventDispatcher.SetThread(iterator->second); + dispatcher = &m_threadEventDispatcher; + } + + // Dispatch event to abstract dispatcher + WaitableEvent *synchronization; + + // TODO: Pool synchronization objects + switch (mode) + { + case EmitMode::Auto: + // Check thread + if (iterator->second == Thread::GetCurrentThread()) + { + // Guard listener code for exceptions + GuardedEventCall(event, iterator->first); + } + else + { + // Handle non-synchronized event + dispatcher->AddEventCall( + RegisterEventCall(event, iterator->first, + DelegateType(), NULL)); + } + break; + + case EmitMode::Queued: + // Handle non-synchronized event + dispatcher->AddEventCall( + RegisterEventCall(event, iterator->first, + DelegateType(), NULL)); + + break; + + case EmitMode::Blocking: + // Check thread + if (iterator->second == Thread::GetCurrentThread()) + { + // Guard listener code for exceptions + GuardedEventCall(event, iterator->first); + } + else + { + // New synchronization object is needed + synchronization = new WaitableEvent(); + + // Handle synchronized event + dispatcher->AddEventCall( + RegisterEventCall(event, iterator->first, + DelegateType(), synchronization)); + + // Add to barrier + synchronizationBarrier.push_back(synchronization); + } + break; + + case EmitMode::Deffered: + // Handle deffered events + Assert(dueTime >= 0.0 && "Due time must be non-negative"); + + dispatcher->AddTimedEventCall( + RegisterEventCall(event, iterator->first, + DelegateType(), NULL), dueTime); + + break; + + default: + Assert("Invalid emit mode"); + } + } + + LogPedantic("Added event to dispatchers"); + + // Emit to all delegates + FOREACH(iterator, m_delegateList) + { + // Switch to proper dispatcher and emit event + AbstractEventDispatcher *dispatcher = NULL; + + if (iterator->second == NULL) + { + // Send to main thread + LogPedantic("Sending event to main dispatcher"); + dispatcher = &GetMainEventDispatcherInstance(); + } + else + { + // Setup thread dispatcher, and send to proper thread + LogPedantic("Sending event to thread dispatcher"); + m_threadEventDispatcher.SetThread(iterator->second); + dispatcher = &m_threadEventDispatcher; + } + + // Dispatch event to abstract dispatcher + WaitableEvent *synchronization; + + // TODO: Pool synchronization objects + switch (mode) + { + case EmitMode::Auto: + // Check thread + if (iterator->second == Thread::GetCurrentThread()) + { + // Guard listener code for exceptions + GuardedEventCall(event, iterator->first); + } + else + { + // Handle non-synchronized event + dispatcher->AddEventCall( + RegisterEventCall(event, + NULL, + iterator->first, + NULL)); + } + break; + + case EmitMode::Queued: + // Handle non-synchronized event + dispatcher->AddEventCall( + RegisterEventCall(event, + NULL, + iterator->first, + NULL)); + + break; + + case EmitMode::Blocking: + // Check thread + if (iterator->second == Thread::GetCurrentThread()) + { + // Guard listener code for exceptions + GuardedEventCall(event, iterator->first); + } + else + { + // New synchronization object is needed + synchronization = new WaitableEvent(); + + // Handle synchronized event + dispatcher->AddEventCall( + RegisterEventCall(event, + NULL, + iterator->first, + synchronization)); + + // Add to barrier + synchronizationBarrier.push_back(synchronization); + } + break; + + case EmitMode::Deffered: + // Handle deffered events + Assert(dueTime >= 0.0 && "Due time must be non-negative"); + + dispatcher->AddTimedEventCall( + RegisterEventCall(event, + NULL, + iterator->first, + NULL), dueTime); + + break; + + default: + Assert("Invalid emit mode"); + } + } + + LogPedantic("Added event to dispatchers"); + + // Leave listeners lock in case of blocking call + if (!synchronizationBarrier.empty()) + { + LogPedantic("Leaving lock due to existing barrier"); + lock.Reset(); + } + + LogPedantic("Size of barrier: " << synchronizationBarrier.size()); + + // Synchronize with barrier + // TODO: Implement generic WaitForAllMultipleHandles call + while (!synchronizationBarrier.empty()) + { + // Get barrier waitable handles + WaitableHandleList barrierHandles; + + FOREACH(iterator, synchronizationBarrier) + barrierHandles.push_back((*iterator)->GetHandle()); + + // Await more events + WaitableHandleIndexList indexList = + WaitForMultipleHandles(barrierHandles); + + // Remove all awaited handles + // TODO: Return handles to pool + FOREACH(iterator, indexList) + { + // Delete object + delete synchronizationBarrier[*iterator]; + + // Zero out place + synchronizationBarrier[*iterator] = NULL; + } + + // Now clean up + std::vector clearedSynchronizationBarrier; + + FOREACH(iterator, synchronizationBarrier) + { + if (*iterator == NULL) + continue; + + clearedSynchronizationBarrier.push_back(*iterator); + } + + synchronizationBarrier.swap(clearedSynchronizationBarrier); + + LogPedantic("Reduced size of barrier: " + << synchronizationBarrier.size()); + } + + LogPedantic("Event emitted"); + } + +public: + EventSupport() + : m_guardedCallInProgress(false) + { + } + + virtual ~EventSupport() + { + 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 diff --git a/modules/event/include/dpl/event/generic_event_call.h b/modules/event/include/dpl/event/generic_event_call.h new file mode 100644 index 0000000..7c0567c --- /dev/null +++ b/modules/event/include/dpl/event/generic_event_call.h @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file generic_event_call.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of generic event call + */ +#ifndef DPL_GENERIC_EVENT_CALL_H +#define DPL_GENERIC_EVENT_CALL_H + +#include +#include +#include +#include +#include +#include + +namespace DPL +{ +namespace Event +{ + +template +class GenericEventCall + : public AbstractEventCall +{ +public: + typedef EventListener EventListenerType; + typedef FastDelegate1 DelegateType; + +protected: + SupportDataType m_supportData; + EventListenerType *m_eventListener; + DelegateType m_delegate; + EventType m_event; + +public: + template + struct Rebind + { + typedef GenericEventCall Other; + }; + + GenericEventCall(SupportDataType supportData, + EventListenerType *eventListener, + DelegateType delegate, + const EventType &event) + : m_supportData(supportData), + m_eventListener(eventListener), + m_delegate(delegate), + m_event(event) + { + } + + virtual ~GenericEventCall() + { + Assert(m_supportData == NULL && + "Call method hasn't been called" + " (support data wasn't destroyed)"); + } + + virtual void Call() + { + LogPedantic("Calling generic event call"); + + m_supportData->CallAndDestroy(m_event, m_eventListener, m_delegate); + + // Now m_supportData points to invalid object. Marking it as NULL. + m_supportData = NULL; + + LogPedantic("Generic event called"); + } + + virtual void DisableEvent() + { + LogPedantic("Disabling this EventCall"); + m_supportData->Reset(); + + // TODO: In the future, event should be completely removed + // from the event queue (not just marked "disabled") + } +}; + +} +} // namespace DPL + +#endif // DPL_GENERIC_EVENT_CALL_H diff --git a/modules/event/include/dpl/event/inter_context_delegate.h b/modules/event/include/dpl/event/inter_context_delegate.h new file mode 100644 index 0000000..55af651 --- /dev/null +++ b/modules/event/include/dpl/event/inter_context_delegate.h @@ -0,0 +1,397 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file inter_context_delegate.h + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + * @brief This file is the header file of inter context delegate + */ + +#ifndef DPL_INTER_CONTEXT_DELEGATE_H_ +#define DPL_INTER_CONTEXT_DELEGATE_H_ + +#ifndef __GXX_EXPERIMENTAL_CXX0X__ // C++11 compatibility check +# include +#else + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * - Created ICDelegate can be passed freely to other threads. + * - ICDelegate can be called just once. All following calls will be + * silently ignored. + * - When ICDelegateSupport is destroyed, all its ICDelegates + * are invalidated and safetly removed. + * - ICDelegate can be invalidated by call to disable method on it. + * - To use ICDelegate you have to do two steps: + * + * 1. Class that will be used to create delegate have to derive from templated + * class ICDelegateSupport + * + * 2. Create instance of ICDelegate by calling + * makeICDelegate and passing to it pointer to method + * + * class A : ICDelegateSupport + * { + * void methodA(int) {} + * void createDelegate() { + * ICDelegate dlg; + * dlg = makeICDelegate(&A::MethodA); + * }; + */ + +namespace DPL { +namespace Event { + +//forward declaration +template +class ICDelegate; + +namespace ICD{ +// This Type defines whether ICDelegate should be destroyed after the call, or +// could be reused later. +enum class Reuse{ Yes, No }; +} + +namespace ICDPrivate { +// Base for all ICDSharedDatas. Needed for auto disabling and deleting of +// ICDSharedDatas. +// If ICDSharedData is disabled, delegate won't be called anymore. +class ICDSharedDataBase +{ + public: + typedef DPL::SharedPtr ICDSharedDataBasePtr; + typedef std::list ICDSharedDataBaseList; + + class ScopedLock : DPL::Noncopyable + { + public: + explicit ScopedLock(ICDSharedDataBasePtr helperBase) : + m_scopedLock(&helperBase->m_mutex) + { + } + + private: + DPL::RecursiveMutex::ScopedLock m_scopedLock; + }; + + ICDSharedDataBase() : m_disabled(false) + { + } + virtual ~ICDSharedDataBase() + { + } + + bool isDisabled() const + { + return m_disabled; + } + virtual void disable() + { + m_disabled = true; + } + + void setIterator(ICDSharedDataBaseList::iterator pos) + { + m_position = pos; + } + + ICDSharedDataBaseList::iterator getIterator() const + { + return m_position; + } + + private: + bool m_disabled; + DPL::RecursiveMutex m_mutex; + ICDSharedDataBaseList::iterator m_position; +}; + +// Pure Event to remove ICDSharedData. +class DeleteICDSharedDataBaseEventCall : public DPL::Event::AbstractEventCall +{ + public: + DeleteICDSharedDataBaseEventCall( + ICDSharedDataBase::ICDSharedDataBasePtr helperBase) : + m_helperBase(helperBase) + { + } + virtual void Call() + { + m_helperBase.Reset(); + } + + private: + ICDSharedDataBase::ICDSharedDataBasePtr m_helperBase; +}; + + +class ICDelegateSupportInterface +{ + protected: + virtual ~ICDelegateSupportInterface() + { + } + virtual void unregisterICDSharedData( + ICDPrivate::ICDSharedDataBase::ICDSharedDataBasePtr helper) = 0; + virtual void registerICDSharedData( + ICDPrivate::ICDSharedDataBase::ICDSharedDataBasePtr helper) = 0; + private: + template + friend class DPL::Event::ICDelegate; +}; +} //ICDPrivate + +// Better makeDelegate then DPL::MakeDelegate +template +FastDelegate +makeDelegate(ThisType* This, + void (ThisType::*Func)(ArgTypesList ...)) +{ + return FastDelegate(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 +class ICDelegate +{ + public: + ICDelegate() + { + } + ICDelegate(ICDPrivate::ICDelegateSupportInterface* base, + DPL::FastDelegate 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(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(m_helper)); + m_helper->disable(); + } + + protected: + ICDPrivate::ICDSharedDataBase::ICDSharedDataBasePtr + getRelatedICDSharedData() const + { + return DPL::StaticPointerCast(m_helper); + } + + private: + template + friend class ICDelegateSupport; + class ICDSharedData; + typedef DPL::SharedPtr ICDSharedDataPtr; + + struct PrivateEvent + { + PrivateEvent(ICDSharedDataPtr a_helper, + ArgTypesList ... arguments) : + helper(a_helper), + args(std::make_tuple(arguments ...)) + { + } + + ICDSharedDataPtr helper; + std::tuple args; + }; + + typedef DPL::FastDelegate + ICDSharedDataDelegateType; + class ICDSharedData : private DPL::Event::EventSupport, + private DPL::EnableSharedFromThis, + public ICDPrivate::ICDSharedDataBase + { + public: + ICDSharedData( + ICDPrivate::ICDelegateSupportInterface *base, + DPL::FastDelegate outerDelegate, + ICD::Reuse reuse) : + m_base(base), + m_outerDelegate(outerDelegate), + m_reuse(reuse) + { + Assert(m_base); + // lock is not needed: this object is not shared at that moment + m_subDelegate = + DPL::Event::makeDelegate(this, + &ICDSharedData::delegateForwarder); + EventSupport::AddListener(m_subDelegate); + } + + void CallDelegate(ArgTypesList ... args) + { + ICDPrivate::ICDSharedDataBase::ScopedLock lock( + DPL::StaticPointerCast( + this->SharedFromThis())); + if (!isDisabled()) { + EmitEvent(PrivateEvent(this->SharedFromThis(), + args ...)); + } + } + + virtual void disable() + { + ICDPrivate::ICDSharedDataBase::ICDSharedDataBasePtr ptr( + DPL::StaticPointerCast( + this->SharedFromThis())); + ICDPrivate::ICDSharedDataBase::ScopedLock lock(ptr); + if (!isDisabled()) { + ICDPrivate::ICDSharedDataBase::disable(); + EventSupport::RemoveListener(m_subDelegate); + m_base->unregisterICDSharedData(ptr); + } + } + + private: + friend class DPL::SharedPtr; + ICDSharedDataDelegateType m_subDelegate; + ICDPrivate::ICDelegateSupportInterface* m_base; + DPL::FastDelegate m_outerDelegate; + ICD::Reuse m_reuse; + + void delegateForwarder(const PrivateEvent& event) + { + ICDPrivate::ICDSharedDataBase::ICDSharedDataBasePtr ptr( + DPL::StaticPointerCast(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 +class ICDelegateSupport : public ICDPrivate::ICDelegateSupportInterface +{ + protected: + template + ICDelegate makeICDelegate( + void (ThisType::*Func)(ArgTypesList ...), + ICD::Reuse reuse = ICD::Reuse::No) + { + ThisType* This = static_cast(this); + ICDelegate icdelegate( + This, + makeDelegate(This, Func), + reuse); + this->registerICDSharedData(icdelegate.getRelatedICDSharedData()); + return icdelegate; + } + + ICDelegateSupport() + { + } + + ~ICDelegateSupport() + { + ICDPrivate::ICDSharedDataBase::ICDSharedDataBaseList list = + m_ICDSharedDatas; + FOREACH(helper, list) { + ICDPrivate::ICDSharedDataBase::ScopedLock lock( + DPL::StaticPointerCast(*helper)); + (*helper)->disable(); + } + m_ICDSharedDatas.clear(); + } + + private: + virtual void unregisterICDSharedData( + ICDPrivate::ICDSharedDataBase::ICDSharedDataBasePtr helper) + { + m_ICDSharedDatas.erase(helper->getIterator()); + } + + virtual void registerICDSharedData( + ICDPrivate::ICDSharedDataBase::ICDSharedDataBasePtr helper) + { + helper->setIterator( + m_ICDSharedDatas.insert(m_ICDSharedDatas.begin(), + helper)); + } + + private: + ICDPrivate::ICDSharedDataBase::ICDSharedDataBaseList m_ICDSharedDatas; +}; + +} +} //namespace + +#endif // __GXX_EXPERIMENTAL_CXX0X__ + +#endif //DPL_INTER_CONTEXT_DELEGATE_H_ diff --git a/modules/event/include/dpl/event/main_event_dispatcher.h b/modules/event/include/dpl/event/main_event_dispatcher.h new file mode 100644 index 0000000..97145f6 --- /dev/null +++ b/modules/event/include/dpl/event/main_event_dispatcher.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file main_event_dispatcher.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of main event dispatcher for EFL + */ +#ifndef DPL_MAIN_EVENT_DISPATCHER_H +#define DPL_MAIN_EVENT_DISPATCHER_H + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DPL +{ +namespace Event +{ + +class MainEventDispatcher + : public AbstractEventDispatcher +{ +public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, CreateFailed) + DECLARE_EXCEPTION_TYPE(Base, AddEventFailed) + DECLARE_EXCEPTION_TYPE(Base, AddTimedEventFailed) + }; + +protected: + struct WrappedEventCall + { + AbstractEventCall *abstractEventCall; + bool timed; + double dueTime; + + WrappedEventCall(AbstractEventCall *abstractEventCallArg, + bool timedArg, + double dueTimeArg) + : abstractEventCall(abstractEventCallArg), + timed(timedArg), + dueTime(dueTimeArg) + { + } + }; + + typedef std::list WrappedEventCallList; + + // Cross thread send support + WrappedEventCallList m_wrappedCrossEventCallList; + Mutex m_crossEventCallMutex; + WaitableEvent m_crossEventCallInvoker; + + Ecore_Event_Handler *m_eventCallHandler; + Ecore_Fd_Handler *m_crossEventCallHandler; + + int m_eventId; + + // Timed event support + struct TimedEventStruct + { + AbstractEventCall *abstractEventCall; + MainEventDispatcher *This; + + TimedEventStruct(AbstractEventCall *abstractEventCallArg, + MainEventDispatcher *ThisArg) + : abstractEventCall(abstractEventCallArg), + This(ThisArg) + { + } + }; + + void InternalAddEvent(AbstractEventCall *abstractEventCall, bool timed, double dueTime); + + static void StaticDeleteEvent(void *data, void *event); + static Eina_Bool StaticDispatchEvent(void *data, int type, void *event); + static Eina_Bool StaticDispatchTimedEvent(void *event); + static Eina_Bool StaticDispatchCrossInvoker(void *data, Ecore_Fd_Handler *fd_handler); + + void DeleteEvent(AbstractEventCall *abstractEventCall); + void DispatchEvent(AbstractEventCall *abstractEventCall); + void DispatchTimedEvent(AbstractEventCall *abstractEventCall); + void DispatchCrossInvoker(); + +public: + explicit MainEventDispatcher(); + virtual ~MainEventDispatcher(); + + virtual void AddEventCall(AbstractEventCall *abstractEventCall); + virtual void AddTimedEventCall(AbstractEventCall *abstractEventCall, double dueTime); +}; + +MainEventDispatcher& GetMainEventDispatcherInstance(); + +} +} // namespace DPL + +#endif // DPL_MAIN_EVENT_DISPATCHER_H diff --git a/modules/event/include/dpl/event/model.h b/modules/event/include/dpl/event/model.h new file mode 100644 index 0000000..07c0340 --- /dev/null +++ b/modules/event/include/dpl/event/model.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file model.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief Header file for model + */ +#ifndef DPL_MODEL_H +#define DPL_MODEL_H + +#include +#include + +namespace DPL +{ +namespace Event +{ + +class Model + : public Noncopyable +{ +protected: + mutable DPL::ReadWriteMutex m_mutex; + + template + friend class PropertyBase; + + template + friend class Property; + +public: + virtual ~Model() = 0; +}; + +} +} // namespace DPL + +#endif // DPL_MODEL_H diff --git a/modules/event/include/dpl/event/model_bind_to_dao.h b/modules/event/include/dpl/event/model_bind_to_dao.h new file mode 100644 index 0000000..51473e8 --- /dev/null +++ b/modules/event/include/dpl/event/model_bind_to_dao.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file model_bind_to_dao.h + * @author Grzegorz Krawczyk (g.krawczyk@samsung.com) + * @version 1.0 + * @brief + */ + +#ifndef DPL_MODEL_BIND_TO_DAO_H_ +#define DPL_MODEL_BIND_TO_DAO_H_ + +namespace DPL +{ +namespace Event +{ + +/** + * @param ObjectType type of object used as delegate argument + * @param RetType Type returned from the external function + * @param ExtArg Type of argument required by external fun + * @param getterFun Object Type method which returns value of type ExtArg + * used as argument for external function + * */ +//STATIC FUNCTION +template < + typename ObjectType, + typename ValueType, + typename ExtArg, + ExtArg(ObjectType::*argGetter) () const, + ValueType(*externalGetter) (ExtArg) + > +struct BindToDAO_Static +{ + static ValueType Get(DPL::Event::Model* obj) + { + ObjectType* instance = static_cast(obj); + + return externalGetter((instance->*argGetter)()); + } +}; + +template < + typename ObjectType, + typename ValueType, + typename ExtArg, + typename ExtObject, + ExtArg(ObjectType::*argGetter) () const, + ValueType(ExtObject::*externalGetter) () const + > +struct BindToDAO +{ + static ValueType Get(DPL::Event::Model* obj) + { + ObjectType* instance = static_cast(obj); + ExtObject extObject((instance->*argGetter)()); + return (extObject.*externalGetter)(); + } +}; + +} +} + +#endif diff --git a/modules/event/include/dpl/event/nested_loop.h b/modules/event/include/dpl/event/nested_loop.h new file mode 100644 index 0000000..7138c8a --- /dev/null +++ b/modules/event/include/dpl/event/nested_loop.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * 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 +#include +#include +#include +#include + +namespace DPL +{ +namespace Event +{ + +class LoopExitEvent +{ +}; + +typedef unsigned LoopHandle; +typedef std::list LoopHandleList; + +const LoopHandle UNDEFINED_LOOP_HANDLE = 0; + +class NestedLoopManager : + protected Controller::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 RunningLoopsList; + typedef RunningLoopsList::iterator RunningLoopsListIterator; + + bool m_eventGuard; // only one event is allowed + LoopHandle m_handle; + RunningLoopsList m_runningLoops; + + friend class Singleton; +}; + +typedef Singleton NestedLoopManagerSingleton; + +} +} // namespace DPL + +#endif // WRT_ENGINE_SRC_COMMON_NESTED_LOOP_H_ diff --git a/modules/event/include/dpl/event/property.h b/modules/event/include/dpl/event/property.h new file mode 100644 index 0000000..33da4df --- /dev/null +++ b/modules/event/include/dpl/event/property.h @@ -0,0 +1,522 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file property.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief Header file for property + */ +#ifndef DPL_PROPERTY_H +#define DPL_PROPERTY_H + +#include +#include +#include +#include +#include +#include +#include + +namespace DPL +{ +namespace Event +{ + +/** + * Property is a class that encapsulates model's property fields. + * Its main purpose is to automate things related to model's properties + * such as: data storage, synchronization and event emitting. + * + * Property is a template of the following schema: + * + * template class Property + * + * Type is an internal type that property is encapsulating. It is required + * that the type is default-constructible and copyable. + * + * Property access rights control which operations are allowed to be + * executed on property. + * + * Property storage mode is a mode describing where and how internal data should + * be stored. + * + * Property modifiers: + * + * PropertyStorageCached: The data is stored internally as one copy. It can + * never be changed from external. + * + * PropertyStorageDynamic: The data is stored remotely and is accessed via + * provided delegates. It can change at any time + * if external mechanism changes its value. + * + * PropertyStorageDynamicCached: The data is stored internally, but only after + * it has been retrieved by delegates. The + * changed data is stored internally and also set + * remotely with delegate. After the value has + * been received from external source, it will + * never be updated externally. + * + * Property access modes: + * + * PropertyReadOnly: Property is a read-only property. + * It doesn't have Set() method. + * + * PropertyReadWrite: Property is a read-write property. It have both Get() + * and Set() methods. + * + * Examples: + * + * Note: All properties, if not specified otherwise in template arguments, + * have read-write access rights and cached data storage. + * + * Simple property with int: + * @code DPL::Property Number; + * + * A property with string: + * @code DPL::Property Name; + * + * A read-only float property: + * @code DPL::Property Gravity; + * + * A read-write string property: + * @code DPL::Property Caption; + * + * A read-write string property which is stored internally: + * @code DPL::Property Name; + * + * A read-write string property which is stored externally: + * @code DPL::Property RemoteName; + * + * A read-write string property which is stored externally, but also cached: + * @code DPL::Property CachedName; + * + * A model is an agregation of many properties. Whenever some of them change, + * an event with this change is emmited along with model handle which + * contains this property. These changes can be listened to. To achieve this, + * one have to add a delegate which contains changed property value and + * a pointer to the model. + * + * Example of a model with a property: + * + * @code + * class MyModel: public DPL::Model + * { + * public: + * DPL::Property Number1; + * DPL::Property Number2; + * DPL::Property Number3; + * + * // Read write property delegate method can be static + * static int ReadCustomValue(Model *model); + * + * // Read write property delegate method can also be method + * void WriteCustomValue(const int &value, Model *model); + * + * MyModel() + * : // Initialize property with default value and this model + * Number1(this), + * + * // Initialize property with 123 and this model + * Number2(this, 123), + * + * // Initialize property with 0 and custom read delegate and this model + * Number3(this, 0, &ReadCustomValue), + * + * // Initialize property with 7 and custom read-write delegates + * // and this model + * Number4(this, 7, &ReadCustomValue, + * 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 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 +struct PropertyEvent +{ + PropertyEvent(const Type &v, Model *s) + : value(v), + sender(s) + { + } + + Type value; + Model *sender; +}; + +template +class PropertyStorageMethodDynamicBase +{ +protected: + ReadDelegateType m_readValue; + WriteDelegateType m_writeValue; + + PropertyStorageMethodDynamicBase(ReadDelegateType readValue, + WriteDelegateType writeValue) + : m_readValue(readValue), + m_writeValue(writeValue) + { + } +}; + +template +class PropertyStorageMethodCachedBase +{ +protected: + mutable Type m_value; + + PropertyStorageMethodCachedBase() + { + } +}; + +class PropertyStorageMethodBase +{ +protected: + explicit PropertyStorageMethodBase(Model *model) + : m_model(model) + { + } + + Model *m_model; +}; + +template +class PropertyStorageMethod; + +template +class PropertyStorageMethod + : protected PropertyStorageMethodBase, + protected PropertyStorageMethodCachedBase +{ +public: + PropertyStorageMethod(Model *model, + ReadDelegateType /*readValue*/, + WriteDelegateType /*writeValue*/) + : PropertyStorageMethodBase(model) + { + } + + Type Get() const + { + return this->m_value; + } + + void Set(const Type &value) + { + this->m_value = value; + } +}; + +template +class PropertyStorageMethod + : protected PropertyStorageMethodBase, + protected PropertyStorageMethodDynamicBase +{ +public: + PropertyStorageMethod(Model *model, + ReadDelegateType readValue, + WriteDelegateType writeValue) + : PropertyStorageMethodBase(model), + PropertyStorageMethodDynamicBase( + readValue, + writeValue) + { + } + + Type Get() const + { + Assert(!this->m_readValue.empty()); + return this->m_readValue(m_model); + } + + void Set(const Type &value) + { + Assert(!this->m_writeValue.empty()); + this->m_writeValue(value, m_model); + } +}; + +template +class PropertyStorageMethod + : protected PropertyStorageMethodBase, + protected PropertyStorageMethodDynamicBase, + protected PropertyStorageMethodCachedBase +{ +private: + typedef PropertyStorageMethod ThisType; + + // These two are mutable + void OnceEnsure() const + { + this->m_value = this->m_readValue(m_model); + } + + void OnceDisable() const + { + } + +protected: + mutable Once m_once; + +public: + PropertyStorageMethod(Model *model, + ReadDelegateType readValue, + WriteDelegateType writeValue) + : PropertyStorageMethodBase(model), + PropertyStorageMethodDynamicBase( + readValue, writeValue) + { + } + + Type Get() const + { + Assert(!this->m_readValue.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 +class PropertyBase + : protected EventSupport > +{ +public: + typedef typename EventSupport >::EventListenerType + EventListenerType; + + typedef typename EventSupport >::DelegateType + DelegateType; + + typedef FastDelegate + ReadDelegateType; + + typedef FastDelegate + WriteDelegateType; + +protected: + PropertyStorageMethod m_storage; + Model *m_model; + + PropertyBase(Model *model, + ReadDelegateType readValue, + WriteDelegateType writeValue) + : m_storage(model, readValue, writeValue), + m_model(model) + { + } + +public: + virtual Type Get() const + { + ReadWriteMutex::ScopedReadLock lock(&m_model->m_mutex); + return m_storage.Get(); + } + + void AddListener(DelegateType delegate) + { + EventSupport >::AddListener(delegate); + } + + void RemoveListener(DelegateType delegate) + { + EventSupport >::RemoveListener(delegate); + } +}; + +template +class Property; + +template +class Property + : public PropertyBase +{ +public: + typedef typename PropertyBase::EventListenerType + EventListenerType; + + typedef typename PropertyBase::DelegateType + DelegateType; + + typedef typename PropertyBase::ReadDelegateType + ReadDelegateType; + + typedef typename PropertyBase::WriteDelegateType + WriteDelegateType; + +public: + explicit Property(Model *model, + ReadDelegateType readValue = NULL) + : PropertyBase(model, readValue, NULL) + { + } + + Property(Model *model, + const Type &value, + ReadDelegateType readValue = NULL) + : PropertyBase(model, readValue, NULL) + { + this->m_storage.Set(value); + } +}; + +template +class Property + : public PropertyBase +{ +public: + typedef typename PropertyBase::EventListenerType + EventListenerType; + + typedef typename PropertyBase::DelegateType + DelegateType; + + typedef typename PropertyBase::ReadDelegateType + ReadDelegateType; + + typedef typename PropertyBase::WriteDelegateType + WriteDelegateType; + +public: + explicit Property(Model *model, + ReadDelegateType readValue = NULL, + WriteDelegateType writeValue = NULL) + : PropertyBase(model, readValue, writeValue) + { + } + + Property(Model *model, + const Type &value, + ReadDelegateType readValue = NULL, + WriteDelegateType writeValue = NULL) + : PropertyBase(model, readValue, writeValue) + { + this->m_storage.Set(value); + } + + virtual void Set(const Type &value) + { + ReadWriteMutex::ScopedWriteLock lock(&this->m_model->m_mutex); + + if (this->m_storage.Get() == value) + return; + + this->m_storage.Set(value); + + EmitEvent(PropertyEvent(value, this->m_model), + EmitMode::Auto); + } +}; + +} +} // namespace DPL + +#endif // DPL_PROPERTY_H diff --git a/modules/event/include/dpl/event/thread_event_dispatcher.h b/modules/event/include/dpl/event/thread_event_dispatcher.h new file mode 100644 index 0000000..e5e81a4 --- /dev/null +++ b/modules/event/include/dpl/event/thread_event_dispatcher.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file thread_event_dispatcher.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of thread event dispatcher + */ +#ifndef DPL_THREAD_EVENT_DISPATCHER_H +#define DPL_THREAD_EVENT_DISPATCHER_H + +#include +#include +#include + +namespace DPL +{ +namespace Event +{ + +class ThreadEventDispatcher + : public AbstractEventDispatcher +{ +protected: + Thread *m_thread; + + static void StaticEventDelete(void *event, void *userParam); + static void StaticEventDispatch(void *event, void *userParam); + + void EventDelete(AbstractEventCall *abstractEventCall); + void EventDispatch(AbstractEventCall *abstractEventCall); + +public: + explicit ThreadEventDispatcher(); + virtual ~ThreadEventDispatcher(); + + void SetThread(Thread *thread); + + virtual void AddEventCall(AbstractEventCall *abstractEventCall); + virtual void AddTimedEventCall(AbstractEventCall *abstractEventCall, double dueTime); +}; + +} +} // namespace DPL + +#endif // DPL_THREAD_EVENT_DISPATCHER_H diff --git a/modules/event/src/abstract_event_call.cpp b/modules/event/src/abstract_event_call.cpp new file mode 100644 index 0000000..093e5b5 --- /dev/null +++ b/modules/event/src/abstract_event_call.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 + +namespace DPL +{ +namespace Event +{ + +AbstractEventCall::AbstractEventCall() +{ +} + +AbstractEventCall::~AbstractEventCall() +{ +} + +} +} // namespace DPL diff --git a/modules/event/src/abstract_event_dispatcher.cpp b/modules/event/src/abstract_event_dispatcher.cpp new file mode 100644 index 0000000..043e452 --- /dev/null +++ b/modules/event/src/abstract_event_dispatcher.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 + +namespace DPL +{ +namespace Event +{ + +AbstractEventDispatcher::AbstractEventDispatcher() +{ +} + +AbstractEventDispatcher::~AbstractEventDispatcher() +{ +} + +} +} // namespace DPL diff --git a/modules/event/src/controller.cpp b/modules/event/src/controller.cpp new file mode 100644 index 0000000..abb126e --- /dev/null +++ b/modules/event/src/controller.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file controller.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of MVC controller + */ +#include + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/modules/event/src/event_delivery.cpp b/modules/event/src/event_delivery.cpp new file mode 100644 index 0000000..4a3dacc --- /dev/null +++ b/modules/event/src/event_delivery.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 +#include + +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 diff --git a/modules/event/src/event_delivery_detail.cpp b/modules/event/src/event_delivery_detail.cpp new file mode 100644 index 0000000..9c7e493 --- /dev/null +++ b/modules/event/src/event_delivery_detail.cpp @@ -0,0 +1,568 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 buffer(new char[length]); + fileStream.read(buffer.Get(), static_cast(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(notiData); + notiSignal->GetReceiver()->OnNotiSignal(notiSignal); +} + +void EventDeliverySystemDetail::OnSettingSignal(keynode_t *keyNode, void *userParam) +{ + SettingSignal *settingSignal = static_cast(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(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 : "") << ", 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(&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 diff --git a/modules/event/src/event_listener.cpp b/modules/event/src/event_listener.cpp new file mode 100644 index 0000000..a90973c --- /dev/null +++ b/modules/event/src/event_listener.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/modules/event/src/event_support.cpp b/modules/event/src/event_support.cpp new file mode 100644 index 0000000..641b311 --- /dev/null +++ b/modules/event/src/event_support.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 + +namespace DPL +{ +namespace Event +{ + +namespace // anonymous +{ +int dummyInitializerProc() +{ + GetMainEventDispatcherInstance(); + return 0; +} + +int g_dummyInitializer = dummyInitializerProc(); + +} // namespace anonymous + +} +} // namespace DPL + diff --git a/modules/event/src/generic_event_call.cpp b/modules/event/src/generic_event_call.cpp new file mode 100644 index 0000000..2ad49b8 --- /dev/null +++ b/modules/event/src/generic_event_call.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/modules/event/src/inter_context_delegate.cpp b/modules/event/src/inter_context_delegate.cpp new file mode 100644 index 0000000..e1dfc52 --- /dev/null +++ b/modules/event/src/inter_context_delegate.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file 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 + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/modules/event/src/main_event_dispatcher.cpp b/modules/event/src/main_event_dispatcher.cpp new file mode 100644 index 0000000..dc2de85 --- /dev/null +++ b/modules/event/src/main_event_dispatcher.cpp @@ -0,0 +1,332 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file main_event_dispatcher.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of main event dispatcher for EFL + */ +#include +#include +#include +#include + +namespace DPL +{ + +IMPLEMENT_SINGLETON(Event::MainEventDispatcher) + +namespace Event +{ + +typedef Singleton MainEventDispatcherSingleton; + +namespace // anonymous +{ +static const pthread_t g_threadMain = pthread_self(); + +// Late EFL event handling +MainEventDispatcher *g_lateMainEventDispatcher = NULL; +} // namespace anonymous + +MainEventDispatcher::MainEventDispatcher() +{ + // Late EFL event handling + Assert(g_lateMainEventDispatcher == NULL); + g_lateMainEventDispatcher = this; + + // Increment ECORE init count to ensure we have all + // subsystems correctly set-up until main dispatcher dtor + // This is especially important when MainEventDispatcher + // is a global object destroyed no earlier than crt destroy routine + ecore_init(); + + // Add new global ECORE event + m_eventId = ecore_event_type_new(); + + LogPedantic("ECORE event class registered: " << m_eventId); + + // Register event class handler + if ((m_eventCallHandler = ecore_event_handler_add(m_eventId, &StaticDispatchEvent, this)) == NULL) + ThrowMsg(Exception::CreateFailed, "Failed to register event handler!"); + + // 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(data); + AbstractEventCall *abstractEventCall = static_cast(event); + + Assert(This != NULL); + Assert(abstractEventCall != NULL); + + // Late EFL event handling + if (g_lateMainEventDispatcher == NULL) + { + LogPedantic("WARNING: Late EFL event delete!"); + delete abstractEventCall; + } + else + { + This->DeleteEvent(abstractEventCall); + } +} + +Eina_Bool MainEventDispatcher::StaticDispatchEvent(void *data, int type, void *event) +{ + LogPedantic("Static ECORE dispatch event"); + + MainEventDispatcher *This = static_cast(data); + AbstractEventCall *abstractEventCall = static_cast(event); + (void)type; + + Assert(This != NULL); + Assert(abstractEventCall != NULL); + + // Late EFL event handling + if (g_lateMainEventDispatcher == NULL) + { + LogPedantic("WARNING: Late EFL event dispatch!"); + } + else + { + This->DispatchEvent(abstractEventCall); + } + + // Continue to handler other ECORE events + return ECORE_CALLBACK_RENEW; +} + +Eina_Bool MainEventDispatcher::StaticDispatchTimedEvent(void *data) +{ + LogPedantic("Static ECORE dispatch timed event"); + + TimedEventStruct *timedEventStruct = static_cast(data); + MainEventDispatcher *This = timedEventStruct->This; + AbstractEventCall *abstractEventCall = timedEventStruct->abstractEventCall; + delete timedEventStruct; + + Assert(This != NULL); + Assert(abstractEventCall != NULL); + + // Late EFL event handling + if (g_lateMainEventDispatcher == NULL) + { + LogPedantic("WARNING: Late EFL timed event dispatch!"); + } + else + { + // Dispatch timed event + This->DispatchEvent(abstractEventCall); + } + + // And delete manually event, because ECORE does not + // use delete handler for timers + StaticDeleteEvent(static_cast(This), static_cast(abstractEventCall)); + + // Do not continue timed event handlers + // This also releases ECORE timer + return ECORE_CALLBACK_CANCEL; +} + +Eina_Bool MainEventDispatcher::StaticDispatchCrossInvoker(void *data, Ecore_Fd_Handler *fd_handler) +{ + LogPedantic("Static ECORE dispatch cross invoker"); + + MainEventDispatcher *This = static_cast(data); + (void)fd_handler; + + Assert(This != NULL); + + // Late EFL event handling + if (g_lateMainEventDispatcher == NULL) + { + LogPedantic("WARNING: Late EFL cross invoker dispatch!"); + } + else + { + This->DispatchCrossInvoker(); + } + + return ECORE_CALLBACK_RENEW; +} + +void MainEventDispatcher::DeleteEvent(AbstractEventCall *abstractEventCall) +{ + LogPedantic("ECORE delete event"); + delete abstractEventCall; +} + +void MainEventDispatcher::DispatchEvent(AbstractEventCall *abstractEventCall) +{ + LogPedantic("ECORE dispatch event"); + + // Call event handler + abstractEventCall->Call(); +} + +void MainEventDispatcher::DispatchTimedEvent(AbstractEventCall *abstractEventCall) +{ + LogPedantic("ECORE dispatch timed event"); + + // Call event handler + abstractEventCall->Call(); +} + +void MainEventDispatcher::DispatchCrossInvoker() +{ + LogPedantic("ECORE dispatch cross invoker"); + + // Steal cross events list + WrappedEventCallList stolenCrossEvents; + + // Critical section + { + m_crossEventCallInvoker.Reset(); + Mutex::ScopedLock lock(&m_crossEventCallMutex); + m_wrappedCrossEventCallList.swap(stolenCrossEvents); + } + + LogPedantic("Cross-thread event list stolen. Number of events: " << stolenCrossEvents.size()); + + // Repush all stolen events + WrappedEventCallList::const_iterator eventIterator; + + for (eventIterator = stolenCrossEvents.begin(); eventIterator != stolenCrossEvents.end(); ++eventIterator) + { + // Unwrap events + LogPedantic("Dispatching event from invoker"); + InternalAddEvent(eventIterator->abstractEventCall, eventIterator->timed, eventIterator->dueTime); + } + + LogPedantic("Cross-thread events dispatched"); +} + +void MainEventDispatcher::AddEventCall(AbstractEventCall *abstractEventCall) +{ + if (pthread_equal(pthread_self(), g_threadMain)) + { + LogPedantic("Main thread ECORE event push"); + InternalAddEvent(abstractEventCall, false, 0.0); + } + else + { + LogPedantic("Cross-thread ECORE event push"); + + // Push event to cross event list + { + Mutex::ScopedLock lock(&m_crossEventCallMutex); + m_wrappedCrossEventCallList.push_back(WrappedEventCall(abstractEventCall, false, 0.0)); + m_crossEventCallInvoker.Signal(); + } + + LogPedantic("Event pushed to cross-thread event list"); + } +} + +void MainEventDispatcher::AddTimedEventCall(AbstractEventCall *abstractEventCall, double dueTime) +{ + if (pthread_equal(pthread_self(), g_threadMain)) + { + LogPedantic("Main thread timed ECORE event push"); + InternalAddEvent(abstractEventCall, true, dueTime); + } + else + { + LogPedantic("Cross-thread timed ECORE event push"); + + // Push event to cross event list + { + Mutex::ScopedLock lock(&m_crossEventCallMutex); + m_wrappedCrossEventCallList.push_back(WrappedEventCall(abstractEventCall, true, dueTime)); + m_crossEventCallInvoker.Signal(); + } + + LogPedantic("Event pushed to cross-thread event list"); + } +} + +void MainEventDispatcher::InternalAddEvent(AbstractEventCall *abstractEventCall, bool timed, double dueTime) +{ + LogPedantic("Adding base event"); + + if (timed == true) + { + // Push timed event onto ecore stack + TimedEventStruct* eventData = new TimedEventStruct(abstractEventCall, this); + Ecore_Timer *timedEvent = ecore_timer_add(dueTime, &StaticDispatchTimedEvent, eventData); + + if (timedEvent == NULL) + { + delete eventData; + delete abstractEventCall; + ThrowMsg(Exception::AddTimedEventFailed, "Failed to add ECORE timed event"); + } + + LogPedantic("Timed wrapped event added"); + } + else + { + // Push immediate event onto ecore stack + Ecore_Event *event = ecore_event_add(m_eventId, abstractEventCall, &StaticDeleteEvent, this); + + if (event == NULL) + { + delete abstractEventCall; + ThrowMsg(Exception::AddEventFailed, "Failed to add ECORE event"); + } + + LogPedantic("Wrapped event added"); + } +} + +MainEventDispatcher& GetMainEventDispatcherInstance() +{ + return MainEventDispatcherSingleton::Instance(); +} + +} +} // namespace DPL diff --git a/modules/event/src/model.cpp b/modules/event/src/model.cpp new file mode 100644 index 0000000..a2e951d --- /dev/null +++ b/modules/event/src/model.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file model.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of model + */ +#include + +namespace DPL +{ +namespace Event +{ +Model::~Model() +{ +} +} +} // namespace DPL diff --git a/modules/event/src/nested_loop.cpp b/modules/event/src/nested_loop.cpp new file mode 100644 index 0000000..c142fd7 --- /dev/null +++ b/modules/event/src/nested_loop.cpp @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * 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 +#include +#include +#include +#include +#include + +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(); + } +} + +} +} diff --git a/modules/event/src/thread_event_dispatcher.cpp b/modules/event/src/thread_event_dispatcher.cpp new file mode 100644 index 0000000..fa155bc --- /dev/null +++ b/modules/event/src/thread_event_dispatcher.cpp @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file thread_event_dispatcher.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of thread event dispatcher + */ +#include +#include +#include + +namespace DPL +{ +namespace Event +{ + +ThreadEventDispatcher::ThreadEventDispatcher() + : m_thread(NULL) +{ +} + +ThreadEventDispatcher::~ThreadEventDispatcher() +{ +} + +void ThreadEventDispatcher::SetThread(Thread *thread) +{ + m_thread = thread; +} + +void ThreadEventDispatcher::StaticEventDelete(void *event, void *userParam) +{ + AbstractEventCall *abstractEventCall = static_cast(event); + ThreadEventDispatcher *This = static_cast(userParam); + + LogPedantic("Received static event delete from thread"); + + Assert(abstractEventCall != NULL); + Assert(This != NULL); + + This->EventDelete(abstractEventCall); +} + +void ThreadEventDispatcher::StaticEventDispatch(void *event, void *userParam) +{ + AbstractEventCall *abstractEventCall = static_cast(event); + ThreadEventDispatcher *This = static_cast(userParam); + + LogPedantic("Received static event dispatch from thread"); + + Assert(abstractEventCall != NULL); + Assert(This != NULL); + + This->EventDispatch(abstractEventCall); +} + +void ThreadEventDispatcher::EventDelete(AbstractEventCall *abstractEventCall) +{ + LogPedantic("Deleting event"); + delete abstractEventCall; +} + +void ThreadEventDispatcher::EventDispatch(AbstractEventCall *abstractEventCall) +{ + LogPedantic("Dispatching event to event support"); + abstractEventCall->Call(); +} + +void ThreadEventDispatcher::AddEventCall(AbstractEventCall *abstractEventCall) +{ + // Thread must be set prior to call + Assert(m_thread != NULL); + + LogPedantic("Adding event to thread event loop"); + + // Call abstract event call in dedicated thread + m_thread->PushEvent(abstractEventCall, &StaticEventDispatch, &StaticEventDelete, this); +} + +void ThreadEventDispatcher::AddTimedEventCall(AbstractEventCall *abstractEventCall, double dueTime) +{ + // Thread must be set prior to call + Assert(m_thread != NULL); + + LogPedantic("Adding timed event to thread event loop"); + + // Call abstract event call in dedicated thread + m_thread->PushTimedEvent(abstractEventCall, dueTime, &StaticEventDispatch, &StaticEventDelete, this); +} + +} +} // namespace DPL diff --git a/modules/localization/config.cmake b/modules/localization/config.cmake new file mode 100644 index 0000000..5f52e6f --- /dev/null +++ b/modules/localization/config.cmake @@ -0,0 +1,38 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# @file 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 +) diff --git a/modules/localization/include/dpl/localization/localization_utils.h b/modules/localization/include/dpl/localization/localization_utils.h new file mode 100644 index 0000000..6779fd5 --- /dev/null +++ b/modules/localization/include/dpl/localization/localization_utils.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file localization_utils.h + * @author Bartosz Janiak (b.janiak@samsung.com) + * @version 1.0 + */ + +#ifndef LOCALIZATION_UTILS_H +#define LOCALIZATION_UTILS_H + +#include + +#include +#include +#include +#include + +/** + * WidgetIcon + * Structure to hold information about widget icon. + */ + +struct WidgetIcon +{ + WidgetIcon() : + width(DPL::Optional::Null), + height(DPL::Optional::Null) + { + } + + /* + * a valid URI to an image file inside the widget package that represents an + * iconic representation of the widget + */ + DPL::String src; + DPL::Optional width; /// the width of the icon in pixels + DPL::Optional height; /// the height of the icon in pixels + + bool operator==(const WidgetIcon &other) const + { + return src == other.src; + } +}; + +struct WidgetStartFileInfo +{ + DPL::String file; + DPL::String localizedPath; + DPL::String encoding; + DPL::String type; + + bool operator==(const WidgetStartFileInfo& other) const + { + return file == other.file && + localizedPath == other.localizedPath && + encoding == other.encoding && + type == other.type; + } +}; + +typedef DPL::Optional OptionalWidgetIcon; +typedef std::list LanguageTagsList; +typedef DPL::Optional 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 diff --git a/modules/localization/include/dpl/localization/w3c_file_localization.h b/modules/localization/include/dpl/localization/w3c_file_localization.h new file mode 100644 index 0000000..d52bd6c --- /dev/null +++ b/modules/localization/include/dpl/localization/w3c_file_localization.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file w3c_file_localization.h + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + */ + +#ifndef W3C_FILE_LOCALIZATION_H +#define W3C_FILE_LOCALIZATION_H + +#include +#include +#include +#include + +#include + +// WrtDB::DbWidgetHandle +#include + +namespace W3CFileLocalization { +typedef std::list WidgetIconList; + +DPL::Optional getFilePathInWidgetPackageFromUrl( + WrtDB::DbWidgetHandle widgetHandle, + const LanguageTagsList &languageTags, + const DPL::String &url); + +DPL::Optional 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 diff --git a/modules/localization/src/localization_utils.cpp b/modules/localization/src/localization_utils.cpp new file mode 100644 index 0000000..9a63800 --- /dev/null +++ b/modules/localization/src/localization_utils.cpp @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file localization_utils.cpp + * @author Bartosz Janiak (b.janiak@samsung.com) + * @version 1.0 + */ + +#include + +#include +#include +#include + +#include +#include +#include + +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 +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 +} + +} diff --git a/modules/localization/src/w3c_file_localization.cpp b/modules/localization/src/w3c_file_localization.cpp new file mode 100644 index 0000000..bb41c5d --- /dev/null +++ b/modules/localization/src/w3c_file_localization.cpp @@ -0,0 +1,315 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file w3c_file_localization.cpp + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + */ + +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include + +using namespace WrtDB; + +namespace { +const DPL::String FILE_URI_BEGIN = L"file://"; +const DPL::String WIDGET_URI_BEGIN = L"widget://"; + +DPL::Optional 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::Null; } + //Removing preceding '/' + if (filePath[0] == '/') { filePath.erase(0, 1); } + //Check if string isn't empty + if (filePath.size() == 0) { return DPL::Optional::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(path); + } + } + } + + return DPL::Optional::Null; +} + +DPL::Optional GetFilePathInWidgetPackageInternal( + const LanguageTagsList &languageTags, + const DPL::String& basePath, + const DPL::String& filePath) +{ + DPL::Optional path = + GetFilePathInWidgetPackageInternal(languageTags, + DPL::ToUTF8String(basePath), + DPL::ToUTF8String(filePath)); + DPL::Optional dplPath; + if (!!path) { + dplPath = DPL::FromUTF8String(*path); + } + return dplPath; +} +} + +namespace W3CFileLocalization { +DPL::Optional 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::Null; + } + + auto widgetPath = dao.getPath(); + + DPL::Optional found = + GetFilePathInWidgetPackageInternal(languageTags, widgetPath, req); + + if (!found) { + LogError("Path not found within current locale in current widget"); + return DPL::Optional::Null; + } + + found = widgetPath + *found; + + return found; +} + +DPL::Optional 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; +} +} diff --git a/modules/log/config.cmake b/modules/log/config.cmake new file mode 100644 index 0000000..26e35f6 --- /dev/null +++ b/modules/log/config.cmake @@ -0,0 +1,41 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# @file 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 +) diff --git a/modules/log/include/dpl/log/abstract_log_provider.h b/modules/log/include/dpl/log/abstract_log_provider.h new file mode 100644 index 0000000..fdce9c0 --- /dev/null +++ b/modules/log/include/dpl/log/abstract_log_provider.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_log_provider.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of abstract log provider + */ +#ifndef DPL_ABSTRACT_LOG_PROVIDER_H +#define DPL_ABSTRACT_LOG_PROVIDER_H + +namespace DPL +{ +namespace Log +{ + +class AbstractLogProvider +{ +public: + virtual ~AbstractLogProvider() {} + + virtual void Debug(const char *message, const char *fileName, int line, const char *function) = 0; + virtual void Info(const char *message, const char *fileName, int line, const char *function) = 0; + virtual void Warning(const char *message, const char *fileName, int line, const char *function) = 0; + virtual void Error(const char *message, const char *fileName, int line, const char *function) = 0; + virtual void Pedantic(const char *message, const char *fileName, int line, const char *function) = 0; + +protected: + static const char *LocateSourceFileName(const char *filename); +}; + +} +} // namespace DPL + +#endif // DPL_ABSTRACT_LOG_PROVIDER_H diff --git a/modules/log/include/dpl/log/dlog_log_provider.h b/modules/log/include/dpl/log/dlog_log_provider.h new file mode 100644 index 0000000..0b3edb5 --- /dev/null +++ b/modules/log/include/dpl/log/dlog_log_provider.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file dlog_log_provider.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of DLOG log provider + */ +#ifndef DPL_DLOG_LOG_PROVIDER_H +#define DPL_DLOG_LOG_PROVIDER_H + +#include +#include +#include + +namespace DPL +{ +namespace Log +{ + +class DLOGLogProvider + : public AbstractLogProvider +{ +private: + DPL::ScopedFree m_tag; + + static std::string FormatMessage(const char *message, const char *filename, int line, const char *function); +public: + DLOGLogProvider(); + virtual ~DLOGLogProvider(); + + virtual void Debug(const char *message, const char *fileName, int line, const char *function); + virtual void Info(const char *message, const char *fileName, int line, const char *function); + virtual void Warning(const char *message, const char *fileName, int line, const char *function); + virtual void Error(const char *message, const char *fileName, int line, const char *function); + virtual void Pedantic(const char *message, const char *fileName, int line, const char *function); + + // Set global Tag according to DLOG + void SetTag(const char *tag); +}; + +} +} // namespace DPL + +#endif // DPL_DLOG_LOG_PROVIDER_H diff --git a/modules/log/include/dpl/log/log.h b/modules/log/include/dpl/log/log.h new file mode 100644 index 0000000..c9564bb --- /dev/null +++ b/modules/log/include/dpl/log/log.h @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file log.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of log system + */ +#ifndef DPL_LOG_H +#define DPL_LOG_H + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DPL +{ +namespace Log +{ +/** + * DPL log system + * + * To switch logs into old style, export + * DPL_USE_OLD_STYLE_LOGS before application start + */ +class LogSystem + : private Noncopyable +{ +private: + ReadWriteMutex m_spinLock; + + typedef std::list AbstractLogProviderPtrList; + AbstractLogProviderPtrList m_providers; + + DLOGLogProvider *m_dlogProvider; + OldStyleLogProvider *m_oldStyleProvider; + + bool m_isLoggingEnabled; + +public: + bool IsLoggingEnabled() const; + LogSystem(); + virtual ~LogSystem(); + + /** + * Log debug message + */ + void Debug(const char *message, const char *filename, int line, const char *function); + + /** + * Log info message + */ + void Info(const char *message, const char *filename, int line, const char *function); + + /** + * Log warning message + */ + void Warning(const char *message, const char *filename, int line, const char *function); + + /** + * Log error message + */ + void Error(const char *message, const char *filename, int line, const char *function); + + /** + * Log pedantic message + */ + void Pedantic(const char *message, const char *filename, int line, const char *function); + + /** + * Set default's DLOG provider Tag + */ + void SetTag(const char *tag); + + /** + * Add abstract provider to providers list + * + * @notice Ownership is transfered to LogSystem and deleted upon exit + */ + void AddProvider(AbstractLogProvider *provider); + + /** + * Remove abstract provider from providers list + */ + void RemoveProvider(AbstractLogProvider *provider); +}; + +/* + * Replacement low overhead null logging class + */ +class NullStream { + public: + NullStream() {} + + template + NullStream& operator<<(const T&) { return *this; } +}; + +/** + * Log system singleton + */ +typedef Singleton LogSystemSingleton; + +} +} // namespace DPL + +// +// Log support +// +// + +#ifdef DPL_LOGS_ENABLED + #define DPL_MACRO_FOR_LOGGING(message, function) \ + do \ + { \ + if (DPL::Log::LogSystemSingleton::Instance().IsLoggingEnabled()) \ + { \ + std::ostringstream platformLog; \ + platformLog << message; \ + DPL::Log::LogSystemSingleton::Instance().function( \ + platformLog.str().c_str(), \ + __FILE__, __LINE__, __FUNCTION__); \ + } \ + } while (0) +#else +/* avoid warnings about unused variables */ + #define DPL_MACRO_FOR_LOGGING(message, function) \ + do { \ + DPL::Log::NullStream ns; \ + ns << message; \ + } while (0) +#endif + + +#define LogDebug(message) DPL_MACRO_FOR_LOGGING(message, Debug) +#define LogInfo(message) DPL_MACRO_FOR_LOGGING(message, Info) +#define LogWarning(message) DPL_MACRO_FOR_LOGGING(message, Warning) +#define LogError(message) DPL_MACRO_FOR_LOGGING(message, Error) +#define LogPedantic(message) DPL_MACRO_FOR_LOGGING(message, Pedantic) + +#endif // DPL_LOG_H diff --git a/modules/log/include/dpl/log/old_style_log_provider.h b/modules/log/include/dpl/log/old_style_log_provider.h new file mode 100644 index 0000000..3ff3d89 --- /dev/null +++ b/modules/log/include/dpl/log/old_style_log_provider.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file old_style_log_provider.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of old style log provider + */ +#ifndef DPL_OLD_STYLE_LOG_PROVIDER_H +#define DPL_OLD_STYLE_LOG_PROVIDER_H + +#include +#include + +namespace DPL +{ +namespace Log +{ +class OldStyleLogProvider + : public AbstractLogProvider +{ +private: + bool m_showDebug; + bool m_showInfo; + bool m_showWarning; + bool m_showError; + bool m_showPedantic; + + 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 diff --git a/modules/log/src/abstract_log_provider.cpp b/modules/log/src/abstract_log_provider.cpp new file mode 100644 index 0000000..d16976c --- /dev/null +++ b/modules/log/src/abstract_log_provider.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_log_provider.cpp + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of abstract log provider + */ +#include +#include + +namespace DPL +{ +namespace Log +{ +const char *AbstractLogProvider::LocateSourceFileName(const char *filename) +{ + const char *ptr = strrchr(filename, '/'); + return ptr != NULL ? ptr + 1 : filename; +} +} +} diff --git a/modules/log/src/dlog_log_provider.cpp b/modules/log/src/dlog_log_provider.cpp new file mode 100644 index 0000000..448ae2c --- /dev/null +++ b/modules/log/src/dlog_log_provider.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file dlog_log_provider.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of DLOG log provider + */ +#include +#include +#include +#include + +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 diff --git a/modules/log/src/log.cpp b/modules/log/src/log.cpp new file mode 100644 index 0000000..b03ab61 --- /dev/null +++ b/modules/log/src/log.cpp @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file log.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of log system + */ +#include +#include + +IMPLEMENT_SINGLETON(DPL::Log::LogSystem) + +namespace DPL +{ +namespace Log +{ +namespace // anonymous +{ +const char *OLD_STYLE_LOGS_ENV_NAME = "DPL_USE_OLD_STYLE_LOGS"; +const char *OLD_STYLE_PEDANTIC_LOGS_ENV_NAME = "DPL_USE_OLD_STYLE_PEDANTIC_LOGS"; +const char *OLD_STYLE_LOGS_MASK_ENV_NAME = "DPL_USE_OLD_STYLE_LOGS_MASK"; +const char *DPL_LOG_OFF = "DPL_LOG_OFF"; +} // namespace anonymous + + +bool LogSystem::IsLoggingEnabled() const +{ + return m_isLoggingEnabled; +} + +LogSystem::LogSystem() + : m_dlogProvider(NULL), + m_oldStyleProvider(NULL), + m_isLoggingEnabled(!getenv(DPL_LOG_OFF)) +{ + bool oldStyleLogs = false; + bool oldStyleDebugLogs = true; + bool oldStyleInfoLogs = true; + bool oldStyleWarningLogs = true; + bool oldStyleErrorLogs = true; + bool oldStylePedanticLogs = false; + + // Check environment settings about pedantic logs + const char *value = getenv(OLD_STYLE_LOGS_ENV_NAME); + + if (value != NULL && !strcmp(value, "1")) + oldStyleLogs = true; + + value = getenv(OLD_STYLE_PEDANTIC_LOGS_ENV_NAME); + + if (value != NULL && !strcmp(value, "1")) + oldStylePedanticLogs = true; + + value = getenv(OLD_STYLE_LOGS_MASK_ENV_NAME); + + if (value != NULL) + { + size_t len = strlen(value); + + if (len >= 1) + { + if (value[0] == '0') + oldStyleDebugLogs = false; + else if (value[0] == '1') + oldStyleDebugLogs = true; + } + + if (len >= 2) + { + if (value[1] == '0') + oldStyleInfoLogs = false; + else if (value[1] == '1') + oldStyleInfoLogs = true; + } + + if (len >= 3) + { + if (value[2] == '0') + oldStyleWarningLogs = false; + else if (value[2] == '1') + oldStyleWarningLogs = true; + } + + if (len >= 4) + { + if (value[3] == '0') + oldStyleErrorLogs = false; + else if (value[3] == '1') + oldStyleErrorLogs = true; + } + } + + // Setup default DLOG and old style logging + if (oldStyleLogs) + { + // Old style + m_oldStyleProvider = new OldStyleLogProvider(oldStyleDebugLogs, oldStyleInfoLogs, oldStyleWarningLogs, oldStyleErrorLogs, oldStylePedanticLogs); + AddProvider(m_oldStyleProvider); + } + else + { + // DLOG + m_dlogProvider = new DLOGLogProvider(); + AddProvider(m_dlogProvider); + } +} + +LogSystem::~LogSystem() +{ + // Delete all providers + for (AbstractLogProviderPtrList::iterator iterator = m_providers.begin(); iterator != m_providers.end(); ++iterator) + delete *iterator; + + m_providers.clear(); + + // And even default providers + m_dlogProvider = NULL; + m_oldStyleProvider = NULL; +} + +void LogSystem::SetTag(const char* tag) +{ + if (m_dlogProvider != NULL) + m_dlogProvider->SetTag(tag); +} + +void LogSystem::AddProvider(AbstractLogProvider *provider) +{ + 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 diff --git a/modules/log/src/old_style_log_provider.cpp b/modules/log/src/old_style_log_provider.cpp new file mode 100644 index 0000000..7c3b1fc --- /dev/null +++ b/modules/log/src/old_style_log_provider.cpp @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file old_style_log_provider.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of old style log provider + */ +#include +#include +#include +#include +#include +#include + +namespace DPL +{ +namespace Log +{ +namespace // anonymous +{ +using namespace DPL::Colors::Text; +const char *DEBUG_BEGIN = GREEN_BEGIN; +const char *DEBUG_END = GREEN_END; +const char *INFO_BEGIN = CYAN_BEGIN; +const char *INFO_END = CYAN_END; +const char *ERROR_BEGIN = RED_BEGIN; +const char *ERROR_END = RED_END; +const char *WARNING_BEGIN = BOLD_GOLD_BEGIN; +const char *WARNING_END = BOLD_GOLD_END; +const char *PEDANTIC_BEGIN = PURPLE_BEGIN; +const char *PEDANTIC_END = PURPLE_END; + + +std::string GetFormattedTime() +{ + timeval tv; + tm localNowTime; + + gettimeofday(&tv, NULL); + localtime_r(&tv.tv_sec, &localNowTime); + + char format[64]; + snprintf(format, sizeof(format), "%02i:%02i:%02i.%03i", localNowTime.tm_hour, localNowTime.tm_min, localNowTime.tm_sec, static_cast(tv.tv_usec / 1000)); + return format; +} + +} // namespace anonymous + +std::string OldStyleLogProvider::FormatMessage(const char *message, const char *filename, int line, const char *function) +{ + std::ostringstream val; + + val << std::string("[") << GetFormattedTime() << std::string("] [") << + static_cast(pthread_self()) << "/" << static_cast(getpid()) << std::string("] [") << + LocateSourceFileName(filename) << std::string(":") << line << + std::string("] ") << function << std::string("(): ") << message; + + return val.str(); +} + +OldStyleLogProvider::OldStyleLogProvider(bool showDebug, bool showInfo, bool showWarning, bool showError, bool showPedantic) + : m_showDebug(showDebug), + m_showInfo(showInfo), + m_showWarning(showWarning), + m_showError(showError), + m_showPedantic(showPedantic) +{ +} + +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 diff --git a/modules/popup/DESCRIPTION b/modules/popup/DESCRIPTION new file mode 100644 index 0000000..665e43e --- /dev/null +++ b/modules/popup/DESCRIPTION @@ -0,0 +1,2 @@ +!!!options!!! stop +UI module for displaying all kinds of pop-up dialogs diff --git a/modules/popup/config.cmake b/modules/popup/config.cmake new file mode 100644 index 0000000..7a304d9 --- /dev/null +++ b/modules/popup/config.cmake @@ -0,0 +1,42 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# @file 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 diff --git a/modules/popup/include/dpl/popup/evas_object.h b/modules/popup/include/dpl/popup/evas_object.h new file mode 100644 index 0000000..ba4ad9b --- /dev/null +++ b/modules/popup/include/dpl/popup/evas_object.h @@ -0,0 +1,661 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DPL { +namespace Popup { + +class EvasObject +{ + class EvasObjectShared; + typedef DPL::SharedPtr 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 IConnectionsSet; + + class SmartConnectionBase : public IConnection + { + public: + SmartConnectionBase(const std::string& name, + EvasObjectShared* object); + + virtual void ConnectPrv(); + virtual void DisconnectPrv(); + std::string m_callbackName; + }; + + template + 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(m_callback, + m_args, + this, + event_info); + } + + private: + CbType m_callback; + std::tuple m_args; + }; + + template + 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 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 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 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 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 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 + IConnection* ConnectSmartCallback(const char* callbackName, + typename SmartConnection::CbType callback, + Args ... args) + { + Assert(m_object); + Assert(callbackName); + Assert(callback); + IConnection* connection = new SmartConnection( + callbackName, + callback, + this, + args ...); + m_connections.insert(connection); + connection->ConnectPrv(); + return connection; + } + + template + IConnection* ConnectMemberSmartCallback( + const char* callbackName, + typename SmartMemberConnection2::CbType callback, + ThisType* callee, + ArgType1* arg1, + ArgType2* arg2) + { + Assert(m_object); + Assert(callee); + Assert(callbackName); + Assert(callback); + IConnection* connection = + new SmartMemberConnection2( + callbackName, + callback, + callee, + arg1, + arg2, + this); + m_connections.insert(connection); + connection->ConnectPrv(); + return connection; + } + + template + IConnection* ConnectMemberSmartCallback( + const char* callbackName, + typename SmartMemberConnection1::CbType callback, + ThisType* callee, + ArgType1* arg1) + { + Assert(m_object); + Assert(callee); + Assert(callbackName); + Assert(callback); + IConnection* connection = + new SmartMemberConnection1(callbackName, + callback, + callee, + arg1, + this); + m_connections.insert(connection); + connection->ConnectPrv(); + return connection; + } + + template + IConnection* ConnectEvasCallback(Evas_Callback_Type callbackType, + typename EvasConnection2::CbType callback, + ArgType1* arg1, + ArgType2* arg2) + { + Assert(m_object); + Assert(callbackType); + Assert(callback); + IConnection* connection = new EvasConnection2( + callbackType, + callback, + arg1, + arg2, + this); + m_connections.insert(connection); + connection->ConnectPrv(); + return connection; + } + + template + IConnection* ConnectEvasCallback(Evas_Callback_Type callbackType, + typename EvasConnection1::CbType callback, + ArgType1* arg1) + { + Assert(m_object); + Assert(callbackType); + Assert(callback); + IConnection* connection = new EvasConnection1( + callbackType, + callback, + arg1, + this); + m_connections.insert(connection); + connection->ConnectPrv(); + return connection; + } + + template + IConnection* ConnectMemberEvasCallback( + Evas_Callback_Type callbackType, + typename EvasMemberConnection2::CbType callback, + ThisType* callee, + ArgType1* arg1, + ArgType2* arg2) + { + Assert(m_object); + Assert(callee); + Assert(callbackType); + Assert(callback); + IConnection* connection = + new EvasMemberConnection2( + callbackType, + callback, + callee, + arg1, + arg2, + this); + m_connections.insert(connection); + connection->ConnectPrv(); + return connection; + } + + template + IConnection* ConnectMemberEvasCallback( + Evas_Callback_Type callbackType, + typename EvasMemberConnection1::CbType callback, + ThisType* callee, + ArgType1* arg1) + { + Assert(m_object); + Assert(callee); + Assert(callbackType); + Assert(callback); + IConnection* connection = + new EvasMemberConnection1(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 + IConnection* ConnectSmartCallback( + const char* callbackName, + typename EvasObjectShared::SmartConnection::CbType + callback, + Args ... args) + { + Assert(m_object); + return m_object->ConnectSmartCallback(callbackName, callback, args ...); + } + + template + IConnection* ConnectMemberSmartCallback( + const char* callbackName, + typename EvasObjectShared::SmartMemberConnection2::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 + IConnection* ConnectMemberSmartCallback( + const char* callbackName, + typename EvasObjectShared::SmartMemberConnection1::CbType + callback, + ThisType* callee, + ArgType1* arg1) + { + Assert(m_object); + Assert(callee); + Assert(callback); + return m_object->ConnectMemberSmartCallback(callbackName, + callback, + callee, + arg1); + } + + template + IConnection* ConnectEvasCallback( + Evas_Callback_Type callbackType, + typename EvasObjectShared::EvasConnection1::CbType + callback, + ArgType1* arg1, + ArgType2* arg2) + { + Assert(m_object); + return m_object->ConnectEvasCallback(callbackType, callback, arg1, arg2); + } + + template + IConnection* ConnectEvasCallback( + Evas_Callback_Type callbackType, + typename EvasObjectShared::EvasConnection1::CbType + callback, + ArgType1* arg1) + { + Assert(m_object); + return m_object->ConnectEvasCallback(callbackType, callback, arg1); + } + + template + IConnection* ConnectMemberEvasCallback( + Evas_Callback_Type callbackType, + typename EvasObjectShared::EvasMemberConnection1::CbType + callback, + ThisType* callee, + ArgType1* arg1) + { + Assert(m_object); + Assert(callee); + Assert(callback); + return m_object->ConnectMemberEvasCallback(callbackType, + callback, + callee, + arg1); + } + + template + IConnection* ConnectMemberEvasCallback( + Evas_Callback_Type callbackType, + typename EvasObjectShared::EvasMemberConnection2::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 + diff --git a/modules/popup/include/dpl/popup/popup.h b/modules/popup/include/dpl/popup/popup.h new file mode 100644 index 0000000..59fd854 --- /dev/null +++ b/modules/popup/include/dpl/popup/popup.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 +#include +#include +#include +#include +#include +#include +#include + +namespace DPL { +namespace Popup { + +struct AnswerCallbackData +{ + int buttonAnswer; + DPL::Optional password; + bool chackState; + DPL::Event::LoopHandle loopHandle; +}; + +class PopupManager; +class IPopup; +typedef DPL::SharedPtr IPopupPtr; + +class IPopup : protected DPL::EnableSharedFromThis +{ + 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; +}; + +} // namespace Popup +} // namespace DPL + +#endif //WRT_SRC_POPUP_POPUP_H_ diff --git a/modules/popup/include/dpl/popup/popup_controller.h b/modules/popup/include/dpl/popup/popup_controller.h new file mode 100644 index 0000000..3550b3a --- /dev/null +++ b/modules/popup/include/dpl/popup/popup_controller.h @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 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, + protected DPL::EnableSharedFromThis +{ + public: + void SetTitle(const std::string &title); + void Append(PopupObject::IPopupObject *object); + + private: + friend class PopupController; + friend class DPL::SharedPtr; + + 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::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 +{ + template + 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(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 + PopupAnswerCallback MakeAnswerCallback(Type* This, + void (Type::*callback) + (const AnswerCallbackData &)) + { + return PopupAnswerCallbackCreator::Create(This, callback); + } +}; + +typedef DPL::Singleton PopupControllerSingleton; + +} //namespace Popup +} //namespace DPL + +#endif //WRT_SRC_POPUP_CONTROLLER_POPUP_CONTROLLER_H_ diff --git a/modules/popup/include/dpl/popup/popup_manager.h b/modules/popup/include/dpl/popup/popup_manager.h new file mode 100644 index 0000000..512ddd6 --- /dev/null +++ b/modules/popup/include/dpl/popup/popup_manager.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 +#include +#include +#include +#include +#include +#include + +namespace DPL { +namespace Popup { + +class PopupManager : DPL::Noncopyable +{ + template + 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 + void RunAsyncWithArgType(IPopupPtr popup, + typename TemplatedPopupCallback::Type callback, + ArgType* argument) + { + Assert(callback); + WrapCbAndArg* wrapped = + new WrapCbAndArg(callback, argument); + popup->Show(&CallbackArgTypeTranslator, 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 + struct WrapCbAndArg + { + WrapCbAndArg(typename TemplatedPopupCallback::Type cb, + ArgType* arg) : + callback(cb), + argument(arg) + { + } + + typename TemplatedPopupCallback::Type callback; + ArgType* argument; + }; + + template + static void CallbackArgTypeTranslator(const AnswerCallbackData & answer, + void* data) + { + WrapCbAndArg* wrapped = + static_cast< WrapCbAndArg* >(data); + wrapped->callback(answer, wrapped->argument); + delete wrapped; + } + + bool m_initialized; + PopupRendererPtr m_popupRenderer; +}; + +typedef DPL::Singleton PopupManagerSingleton; + +} // namespace Popup +} // namespace DPL + +#endif //WRT_SRC_POPUP_POPUP_MANAGER_H_ diff --git a/modules/popup/include/dpl/popup/popup_object.h b/modules/popup/include/dpl/popup/popup_object.h new file mode 100644 index 0000000..5eddc49 --- /dev/null +++ b/modules/popup/include/dpl/popup/popup_object.h @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 + +#include +#include + +namespace DPL { +namespace Popup { + +namespace PopupObject { +class IPopupObject; +class PopupObjectBase; +class Button; +class Label; +class Check; + +typedef std::list 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_ diff --git a/modules/popup/include/dpl/popup/popup_renderer.h b/modules/popup/include/dpl/popup/popup_renderer.h new file mode 100644 index 0000000..593c231 --- /dev/null +++ b/modules/popup/include/dpl/popup/popup_renderer.h @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 +#include + +#include +#include +#include +#include +#include +#include + +#include + +namespace DPL { +namespace Popup { + +class PopupRenderer : public DPL::EnableSharedFromThis +{ + public: + PopupRenderer(); + ~PopupRenderer(); + void Initialize(); + void Deinitialize(); + IPopupPtr CreatePopup(); + virtual void setExternalCanvas(void* externalCanvas); + protected: + class Popup; + typedef DPL::SharedPtr PopupPtr; + + class Popup : public IPopup + { + public: + typedef std::map 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(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; + friend class PopupObjectTheme; + + Popup(DPL::SharedPtr 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 m_renderer; + }; + + private: + void Render (PopupPtr popup); + + class Impl; + Impl* m_impl; +}; + +typedef DPL::SharedPtr PopupRendererPtr; + +} // namespace Popup +} // namespace DPL + +#endif //WRT_SRC_POPUP_POPUP_RENDERER_H_ diff --git a/modules/popup/src/evas_object.cpp b/modules/popup/src/evas_object.cpp new file mode 100644 index 0000000..aa41500 --- /dev/null +++ b/modules/popup/src/evas_object.cpp @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 +#include + +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(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(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(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 diff --git a/modules/popup/src/popup_controller.cpp b/modules/popup/src/popup_controller.cpp new file mode 100644 index 0000000..e8163be --- /dev/null +++ b/modules/popup/src/popup_controller.cpp @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file popup_controller.cpp + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + * @bref Implementation file for popup controller + */ + +#include + +#include +#include +#include +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::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::RemoveListener(this); +} + +void PopupControllerUser::ListenForAnswer(CtrlPopupPtr popup) +{ + popup->DPL::Event::EventSupport::AddListener(this); +} +} //namespace Popup +} //namespace DPL diff --git a/modules/popup/src/popup_manager.cpp b/modules/popup/src/popup_manager.cpp new file mode 100644 index 0000000..6e838f6 --- /dev/null +++ b/modules/popup/src/popup_manager.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file popup_manager.cpp + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + * @brief This is popup_manager implementation file + */ + +#include +#include + +#include +#include +#include +#include + +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 diff --git a/modules/popup/src/popup_renderer.cpp b/modules/popup/src/popup_renderer.cpp new file mode 100644 index 0000000..7a45c77 --- /dev/null +++ b/modules/popup/src/popup_renderer.cpp @@ -0,0 +1,414 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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(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(themeIndex).c_str(), + check); + + check.ConnectMemberSmartCallback(CHANGED_CALLBACK_NAME, + &Impl::CheckCallback, + this, + static_cast(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(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(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(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 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 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(externalCanvas); + } + + Evas_Object* getExternalCanvas() const + { + return m_externalCanvas; + } + + std::queue m_popupsToRender; + std::list m_createdObjects; + PopupPtr m_current; + bool m_initialized; + bool m_checkState; + DPL::Optional 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(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 diff --git a/modules/rpc/config.cmake b/modules/rpc/config.cmake new file mode 100644 index 0000000..9f3d810 --- /dev/null +++ b/modules/rpc/config.cmake @@ -0,0 +1,52 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# @file config.cmake +# @author Lukasz Marek (l.marek@samsung.com) +# @version 1.0 +# @brief +# + +SET(DPL_RPC_SOURCES + ${PROJECT_SOURCE_DIR}/modules/rpc/src/abstract_rpc_connection.cpp + ${PROJECT_SOURCE_DIR}/modules/rpc/src/abstract_rpc_connector.cpp + ${PROJECT_SOURCE_DIR}/modules/rpc/src/generic_rpc_connection.cpp + ${PROJECT_SOURCE_DIR}/modules/rpc/src/generic_socket_rpc_client.cpp + ${PROJECT_SOURCE_DIR}/modules/rpc/src/generic_socket_rpc_connection.cpp + ${PROJECT_SOURCE_DIR}/modules/rpc/src/generic_socket_rpc_server.cpp + ${PROJECT_SOURCE_DIR}/modules/rpc/src/unix_socket_rpc_client.cpp + ${PROJECT_SOURCE_DIR}/modules/rpc/src/unix_socket_rpc_connection.cpp + ${PROJECT_SOURCE_DIR}/modules/rpc/src/unix_socket_rpc_server.cpp + PARENT_SCOPE +) + +SET(DPL_RPC_HEADERS + ${PROJECT_SOURCE_DIR}/modules/rpc/include/dpl/rpc/abstract_rpc_connection.h + ${PROJECT_SOURCE_DIR}/modules/rpc/include/dpl/rpc/abstract_rpc_connector.h + ${PROJECT_SOURCE_DIR}/modules/rpc/include/dpl/rpc/generic_rpc_connection.h + ${PROJECT_SOURCE_DIR}/modules/rpc/include/dpl/rpc/generic_socket_rpc_client.h + ${PROJECT_SOURCE_DIR}/modules/rpc/include/dpl/rpc/generic_socket_rpc_connection.h + ${PROJECT_SOURCE_DIR}/modules/rpc/include/dpl/rpc/generic_socket_rpc_server.h + ${PROJECT_SOURCE_DIR}/modules/rpc/include/dpl/rpc/rpc_function.h + ${PROJECT_SOURCE_DIR}/modules/rpc/include/dpl/rpc/unix_socket_rpc_client.h + ${PROJECT_SOURCE_DIR}/modules/rpc/include/dpl/rpc/unix_socket_rpc_connection.h + ${PROJECT_SOURCE_DIR}/modules/rpc/include/dpl/rpc/unix_socket_rpc_server.h + PARENT_SCOPE +) + +SET(DPL_RPC_INCLUDE_DIR + ${PROJECT_SOURCE_DIR}/modules/rpc/include + PARENT_SCOPE +) diff --git a/modules/rpc/include/dpl/rpc/abstract_rpc_connection.h b/modules/rpc/include/dpl/rpc/abstract_rpc_connection.h new file mode 100644 index 0000000..6f1fd63 --- /dev/null +++ b/modules/rpc/include/dpl/rpc/abstract_rpc_connection.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_rpc_connection.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file for abstract RPC connection + */ +#ifndef DPL_ABSTRACT_RPC_CONNECTION_H +#define DPL_ABSTRACT_RPC_CONNECTION_H + +#include +#include +#include +#include +#include +#include + +namespace DPL +{ +namespace RPC +{ +namespace AbstractRPCConnectionEvents +{ +/** + * Asynchronous call event + */ +DECLARE_GENERIC_EVENT_1(AsyncCallEvent, RPCFunction) + +/** + * Connection closed event + */ +DECLARE_GENERIC_EVENT_0(ConnectionClosedEvent) + +/** + * Connection broken event + */ +DECLARE_GENERIC_EVENT_0(ConnectionBrokenEvent) +} // namespace AbstractRPCConnectionEvents + +class AbstractRPCConnection + : public DPL::Event::EventSupport, + public DPL::Event::EventSupport, + public DPL::Event::EventSupport +{ +public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, AsyncCallFailed) + DECLARE_EXCEPTION_TYPE(Base, PingFailed) + }; + +public: + virtual ~AbstractRPCConnection() {} + + /** + * Call asynchronously RPC function + * + * @param function COnstant reference to RPC function to call + * @return none + */ + virtual void AsyncCall(const RPCFunction &function) = 0; + + /** + * Ping RPC connection + * This will send a ping/pong packet over connection to ensure it is alive + * If any errors are to occur proper events will be emitted + * + * @return none + */ + virtual void Ping() = 0; +}; + +/** + * Abstract connection ID used to represent connection being established + * or RPC server accepting connection + */ +typedef void *AbstractRPCConnectionID; + +} +} // namespace DPL + +#endif // DPL_ABSTRACT_RPC_CONNECTION_H diff --git a/modules/rpc/include/dpl/rpc/abstract_rpc_connector.h b/modules/rpc/include/dpl/rpc/abstract_rpc_connector.h new file mode 100644 index 0000000..38c1e97 --- /dev/null +++ b/modules/rpc/include/dpl/rpc/abstract_rpc_connector.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_rpc_connector.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file for abstract RPC connector + */ +#ifndef DPL_ABSTRACT_RPC_CONNECTOR_H +#define DPL_ABSTRACT_RPC_CONNECTOR_H + +#include +#include +#include + +namespace DPL +{ +namespace RPC +{ +namespace AbstractRPCConnectorEvents +{ +/** + * RPC connection established + */ +DECLARE_GENERIC_EVENT_2(ConnectionEstablishedEvent, AbstractRPCConnectionID, AbstractRPCConnection *) +} // namespace AbstractRPCClientEvents + +class AbstractRPCConnector + : public DPL::Event::EventSupport +{ +public: + /** + * Destructor + */ + virtual ~AbstractRPCConnector() {} +}; + +} +} // namespace DPL + +#endif // DPL_ABSTRACT_RPC_CONNECTOR_H diff --git a/modules/rpc/include/dpl/rpc/generic_rpc_connection.h b/modules/rpc/include/dpl/rpc/generic_rpc_connection.h new file mode 100644 index 0000000..1342859 --- /dev/null +++ b/modules/rpc/include/dpl/rpc/generic_rpc_connection.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file generic_rpc_connection.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file for generic RPC connection + */ +#ifndef DPL_GENERIC_RPC_CONNECTION_H +#define DPL_GENERIC_RPC_CONNECTION_H + +#include +#include +#include +#include + +namespace DPL +{ +namespace RPC +{ + +class GenericRPCConnection + : public AbstractRPCConnection, + private DPL::Socket::WaitableInputOutputExecutionContextSupport +{ +private: + // WaitableInputOutputExecutionContextSupport + virtual void OnInputStreamRead(); + virtual void OnInputStreamClosed(); + virtual void OnInputStreamBroken(); + + ScopedPtr 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 diff --git a/modules/rpc/include/dpl/rpc/generic_socket_rpc_client.h b/modules/rpc/include/dpl/rpc/generic_socket_rpc_client.h new file mode 100644 index 0000000..122dd0b --- /dev/null +++ b/modules/rpc/include/dpl/rpc/generic_socket_rpc_client.h @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file generic_socket_rpc_client.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file for generic socket RPC client + */ +#ifndef DPL_GENERIC_SOCKET_RPC_CLIENT_H +#define DPL_GENERIC_SOCKET_RPC_CLIENT_H + +#include +#include +#include + +namespace DPL +{ +namespace RPC +{ + +template +class GenericSocketRPCClient + : public AbstractRPCConnector, + private DPL::Event::EventListener +{ +public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, OpenFailed) + DECLARE_EXCEPTION_TYPE(Base, CloseFailed) + }; + +protected: + // Derived class implementations for connection managment + virtual AbstractRPCConnection *OpenSpecificConnection(SocketType *socket) = 0; + +private: + typedef std::set InternalConnectionSet; + InternalConnectionSet m_internalConnectionSet; + + virtual void OnEventReceived(const DPL::Socket::AbstractSocketEvents::ConnectedEvent &event) + { + // Retrieve socket sender + SocketType *socket = static_cast(event.GetSender()); + + LogPedantic("Connection with RPC server established"); + + // Is this connection still tracked ? + // It might have disappeared on close + typename InternalConnectionSet::iterator iterator = m_internalConnectionSet.find(socket); + + if (iterator == m_internalConnectionSet.end()) + { + LogPedantic("RPC client connection socket disappeared"); + return; + } + + // Open specific connection implementation + AbstractRPCConnection *connection = OpenSpecificConnection(socket); + + // Remove internal connection + socket->EventSupport::RemoveListener(this); + m_internalConnectionSet.erase(iterator); + + // Retrieve ID once again + AbstractRPCConnectionID connectionID = static_cast(socket); + + // Inform listeners + DPL::Event::EventSupport:: + EmitEvent(AbstractRPCConnectorEvents::ConnectionEstablishedEvent( + connectionID, connection, EventSender(this)), DPL::Event::EmitMode::Queued); + } + +public: + explicit GenericSocketRPCClient() + { + } + + virtual ~GenericSocketRPCClient() + { + // Always close all connections + CloseAll(); + } + + AbstractRPCConnectionID Open(const Address &socketAddress) + { + LogPedantic("Starting client: " << socketAddress.ToString()); + + // Alloc new socket + SocketType *socket = new SocketType(); + + // Add socket listeners + socket->EventSupport::AddListener(this); + + Try + { + // Open socket + socket->Open(); + + // Start connecting to server + socket->Connect(Address(socketAddress)); + } + Catch (DPL::Socket::AbstractSocket::Exception::Base) + { + // Remove back socket listener + socket->EventSupport::RemoveListener(this); + + // Log debug message + LogPedantic("Cannot connect to: " << socketAddress.ToString()); + + // Problem with client startup + ReThrowMsg(typename Exception::OpenFailed, socketAddress.ToString()); + } + + // Register new internal connection + m_internalConnectionSet.insert(socket); + + // Debug info + LogPedantic("Client started on interface: " << socket->GetLocalAddress().ToString()); + + // Return unique identifier + return static_cast(socket); + } + + void Close(AbstractRPCConnectionID connectionID) + { + LogPedantic("Closing client interface..."); + + // Get socket from ID + SocketType *socket = static_cast(connectionID); + + // Find corresponding internal connection + typename InternalConnectionSet::iterator iterator = m_internalConnectionSet.find(socket); + + if (iterator == m_internalConnectionSet.end()) + return; + + // Close socket + socket->Close(); + + // Remove internal socket + socket->EventSupport::RemoveListener(this); + delete socket; + + m_internalConnectionSet.erase(iterator); + + // Done + LogPedantic("Closed"); + } + + void CloseAll() + { + while (!m_internalConnectionSet.empty()) + Close(static_cast(*m_internalConnectionSet.begin())); + } +}; + +} +} // namespace DPL + +#endif // DPL_GENERIC_SOCKET_RPC_CLIENT_H diff --git a/modules/rpc/include/dpl/rpc/generic_socket_rpc_connection.h b/modules/rpc/include/dpl/rpc/generic_socket_rpc_connection.h new file mode 100644 index 0000000..12e53de --- /dev/null +++ b/modules/rpc/include/dpl/rpc/generic_socket_rpc_connection.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file generic_socket_rpc_connection.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file for generic socket RPC connection + */ +#ifndef DPL_GENERIC_SOCKET_RPC_CONNECTION_H +#define DPL_GENERIC_SOCKET_RPC_CONNECTION_H + +#include + +namespace DPL +{ +namespace RPC +{ + +template +class GenericSocketRPCConnection + : public GenericRPCConnection +{ +protected: + // Private construction with socket acquisition + GenericSocketRPCConnection(SocketType *socket) + : GenericRPCConnection(socket) + { + } +}; + +} +} // namespace DPL + +#endif // DPL_GENERIC_SOCKET_RPC_CONNECTION_H diff --git a/modules/rpc/include/dpl/rpc/generic_socket_rpc_server.h b/modules/rpc/include/dpl/rpc/generic_socket_rpc_server.h new file mode 100644 index 0000000..87d6899 --- /dev/null +++ b/modules/rpc/include/dpl/rpc/generic_socket_rpc_server.h @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file generic_socket_rpc_server.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file for generic socket RPC server + */ +#ifndef DPL_GENERIC_SOCKET_RPC_SERVER_H +#define DPL_GENERIC_SOCKET_RPC_SERVER_H + +#include +#include +#include + +namespace DPL +{ +namespace RPC +{ + +template +class GenericSocketRPCServer + : public AbstractRPCConnector, + private DPL::Event::EventListener +{ +public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, OpenFailed) + DECLARE_EXCEPTION_TYPE(Base, CloseFailed) + }; + +protected: + // Derived class implementations for connection managment + virtual AbstractRPCConnection *OpenSpecificConnection(SocketType *socket) = 0; + +private: + typedef std::set InternalInterfaceSet; + InternalInterfaceSet m_internalInterfacesSet; + + virtual void OnEventReceived(const DPL::Socket::AbstractSocketEvents::AcceptEvent &event) + { + // Retrieve socket sender + SocketType *server = static_cast(event.GetSender()); + + // Is this interface still tracked ? + // It might have disappeared on close + typename InternalInterfaceSet::iterator iterator = m_internalInterfacesSet.find(server); + + if (iterator == m_internalInterfacesSet.end()) + { + LogPedantic("RPC server interface socket disappeared"); + return; + } + + // Accept incoming client + SocketType *client = static_cast(server->Accept()); + if(client == NULL) + { + LogPedantic("Spontaneous accept on socket occurred"); + return; + } + + LogPedantic("Client connected to server: " << client->GetRemoteAddress().ToString()); + + // Open specific connection implementation + AbstractRPCConnection *connection = OpenSpecificConnection(client); + + // Retrieve ID once again + AbstractRPCConnectionID connectionID = static_cast(server); + + // Inform listeners + DPL::Event::EventSupport:: + EmitEvent(AbstractRPCConnectorEvents::ConnectionEstablishedEvent( + connectionID, connection, EventSender(this)), DPL::Event::EmitMode::Queued); + } + +public: + explicit GenericSocketRPCServer() + { + } + + virtual ~GenericSocketRPCServer() + { + // Always close connection + CloseAll(); + } + + AbstractRPCConnectionID Open(const Address &socketAddress) + { + LogPedantic("Starting server: " << socketAddress.ToString()); + + // Alloc new socket + SocketType *socket = new SocketType(); + + // Add socket listener + socket->EventSupport::AddListener(this); + + Try + { + // Open socket + socket->Open(); + + // Bind socket address + socket->Bind(socketAddress); + + // Start listening + socket->Listen(8); + } + Catch (DPL::Socket::AbstractSocket::Exception::Base) + { + // Remove back socket listener + socket->EventSupport::RemoveListener(this); + + // Log debug + LogPedantic("Cannot start server: " << socketAddress.ToString()); + + // Problem with server startup + ReThrowMsg(typename Exception::OpenFailed, socketAddress.ToString()); + } + + // Register new internal connection + m_internalInterfacesSet.insert(socket); + + // Debug info + LogPedantic("Server started on interface: " << socket->GetLocalAddress().ToString()); + + // Return unique identifier + return static_cast(socket); + } + + void Close(AbstractRPCConnectionID connectionID) + { + LogPedantic("Closing server interface..."); + + // Get socket from ID + SocketType *socket = static_cast(connectionID); + + // Find corresponding internal connection + typename InternalInterfaceSet::iterator iterator = m_internalInterfacesSet.find(socket); + + if (iterator == m_internalInterfacesSet.end()) + return; + + // Close socket + socket->Close(); + + // Remove socket listeners + socket->EventSupport::RemoveListener(this); + delete socket; + + m_internalInterfacesSet.erase(iterator); + + // Done + LogPedantic("Closed"); + } + + void CloseAll() + { + while (!m_internalInterfacesSet.empty()) + Close(static_cast(*m_internalInterfacesSet.begin())); + } +}; + +} +} // namespace DPL + +#endif // DPL_GENERIC_SOCKET_RPC_SERVER_H diff --git a/modules/rpc/include/dpl/rpc/rpc_function.h b/modules/rpc/include/dpl/rpc/rpc_function.h new file mode 100644 index 0000000..4a121ff --- /dev/null +++ b/modules/rpc/include/dpl/rpc/rpc_function.h @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file rpc_function.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file for RPC function + */ +#ifndef DPL_RPC_FUNCTION_H +#define DPL_RPC_FUNCTION_H + +#include +#include +#include +#include +#include +#include + +namespace DPL +{ +namespace RPC +{ + +class RPCFunction : public IStream +{ +protected: + BinaryQueue m_buffer; ///< Serialized RPC function call as a binary queue + +public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, ParseFailed) + }; + + /** + * Constructor + */ + RPCFunction() + { + } + + /** + * Constructor + * + * @param buffer Binary queue to copy initialization data from + */ + RPCFunction(const BinaryQueue &buffer) + { + m_buffer.AppendCopyFrom(buffer); + } + + /** + * Destructor + */ + virtual ~RPCFunction() + { + } + + /** + * Append argument to call + * + * @param[in] arg Template based argument to append + * @return none + * @warning Carefully add any pointers to buffer because of template nature of this method + */ + template + void AppendArg(const Type &arg) + { + size_t argSize = sizeof(arg); + m_buffer.AppendCopy(&argSize, sizeof(argSize)); + m_buffer.AppendCopy(&arg, sizeof(arg)); + } + + /** + * Append @a std::string argument to call + * + * @param[in] arg String to append to function call + * @return none + */ + void AppendArg(const std::string &arg) + { + size_t argSize = arg.size(); + m_buffer.AppendCopy(&argSize, sizeof(argSize)); + m_buffer.AppendCopy(arg.c_str(), argSize); + } + + /** + * Append @a DPL::String argument to call + * + * @param[in] arg String to append to function call + * @return none + */ + void AppendArg(const String &arg) + { + std::string localStdString = ToUTF8String(arg); + AppendArg(localStdString); + } + + /** + * Consume argument from call. Arguments are retrieved in non-reversed order + * (same as they were pushed onto RPC function argument stack) + * + * @param[out] arg Reference to output template based argument + * @warning Carefully add any pointers to buffer because of template nature of this method + * @return none + */ + template + void ConsumeArg(Type &arg) + { + Try + { + size_t argSize = sizeof(arg); + m_buffer.FlattenConsume(&argSize, sizeof(argSize)); + + if (argSize != sizeof(arg)) + ThrowMsg(Exception::ParseFailed, "Stream parse CRC failed"); + + m_buffer.FlattenConsume(&arg, sizeof(arg)); + } + Catch (BinaryQueue::Exception::OutOfData) + { + ReThrowMsg(Exception::ParseFailed, "Unexpected end of stream"); + } + } + + /** + * Consume @a std::string argument from call. Arguments are retrieved in non-reversed order + * (same as they were pushed onto RPC function argument stack) + * + * @param[out] arg Reference to output @a std::string argument + * @return none + */ + void ConsumeArg(std::string &arg) + { + Try + { + std::string::size_type size; + m_buffer.FlattenConsume(&size, sizeof(size)); + ScopedArray str(new char[size]); + m_buffer.FlattenConsume(str.Get(), size); + arg = std::string(str.Get(), str.Get() + size); + } + Catch (BinaryQueue::Exception::OutOfData) + { + ReThrowMsg(Exception::ParseFailed, "Unexpected end of stream"); + } + } + + /** + * Consume @a DPL::String argument from call. Arguments are converted to UTF-8 string + * + * @param[out] arg Reference to output @a DPL::String argument + * @return none + */ + void ConsumeArg(String &arg) + { + std::string consumedStdString; + ConsumeArg(consumedStdString); + arg = FromUTF8String(consumedStdString); + } + + /** + * Serialize all function parameters into single binary queue + * + * @return Serialized binary queue representation of RPC function + */ + BinaryQueue Serialize() const + { + return m_buffer; + } + + /** + * Reads binary data from serialized stream + * + * @param num number of bytes to read + * @param bytes buffer for read data + */ + virtual void Read(size_t num, void * bytes) + { + m_buffer.FlattenConsume(bytes, num); + } + + /** + * Writes binary data to serialized stream + * + * @param num number of bytes to write to serialization buffer + * @param bytes buffer for data to write + */ + virtual void Write(size_t num, const void * bytes) + { + m_buffer.AppendCopy(bytes, num); + } +}; + +} +} // namespace DPL + +#endif // DPL_RPC_FUNCTION_H diff --git a/modules/rpc/include/dpl/rpc/unix_socket_rpc_client.h b/modules/rpc/include/dpl/rpc/unix_socket_rpc_client.h new file mode 100644 index 0000000..730a349 --- /dev/null +++ b/modules/rpc/include/dpl/rpc/unix_socket_rpc_client.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file unix_socket_rpc_client.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file for unix socket RPC client + */ +#ifndef DPL_UNIX_SOCKET_RPC_CLIENT_H +#define DPL_UNIX_SOCKET_RPC_CLIENT_H + +#include +#include +#include + +namespace DPL +{ +namespace RPC +{ + +class UnixSocketRPCClient + : public GenericSocketRPCClient +{ +protected: + virtual AbstractRPCConnection *OpenSpecificConnection(DPL::Socket::UnixSocket *socket); + +public: + AbstractRPCConnectionID Open(const std::string &fileName); +}; + +} +} // namespace DPL + +#endif // DPL_UNIX_SOCKET_RPC_CLIENT_H diff --git a/modules/rpc/include/dpl/rpc/unix_socket_rpc_connection.h b/modules/rpc/include/dpl/rpc/unix_socket_rpc_connection.h new file mode 100644 index 0000000..5981596 --- /dev/null +++ b/modules/rpc/include/dpl/rpc/unix_socket_rpc_connection.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file unix_socket_rpc_connection.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file for unix socket RPC connection + */ +#ifndef DPL_UNIX_SOCKET_RPC_CONNECTION_H +#define DPL_UNIX_SOCKET_RPC_CONNECTION_H + +#include +#include + +namespace DPL +{ +namespace RPC +{ + +class UnixSocketRPCConnection + : public GenericSocketRPCConnection +{ +public: + // Socket acquisition + UnixSocketRPCConnection(DPL::Socket::UnixSocket *socket); +}; + +} +} // namespace DPL + +#endif // DPL_UNIX_SOCKET_RPC_CONNECTION_H diff --git a/modules/rpc/include/dpl/rpc/unix_socket_rpc_server.h b/modules/rpc/include/dpl/rpc/unix_socket_rpc_server.h new file mode 100644 index 0000000..a6d7335 --- /dev/null +++ b/modules/rpc/include/dpl/rpc/unix_socket_rpc_server.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file unix_socket_rpc_server.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file for unix socket RPC server + */ +#ifndef DPL_UNIX_SOCKET_RPC_SERVER_H +#define DPL_UNIX_SOCKET_RPC_SERVER_H + +#include +#include +#include + +namespace DPL +{ +namespace RPC +{ + +class UnixSocketRPCServer + : public GenericSocketRPCServer +{ +protected: + virtual AbstractRPCConnection *OpenSpecificConnection(DPL::Socket::UnixSocket *socket); + +public: + AbstractRPCConnectionID Open(const std::string &fileName); +}; + +} +} // namespace DPL + +#endif // DPL_UNIX_SOCKET_RPC_SERVER_H diff --git a/modules/rpc/src/abstract_rpc_connection.cpp b/modules/rpc/src/abstract_rpc_connection.cpp new file mode 100644 index 0000000..b1b2140 --- /dev/null +++ b/modules/rpc/src/abstract_rpc_connection.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/modules/rpc/src/abstract_rpc_connector.cpp b/modules/rpc/src/abstract_rpc_connector.cpp new file mode 100644 index 0000000..63527bc --- /dev/null +++ b/modules/rpc/src/abstract_rpc_connector.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/modules/rpc/src/generic_rpc_connection.cpp b/modules/rpc/src/generic_rpc_connection.cpp new file mode 100644 index 0000000..f087494 --- /dev/null +++ b/modules/rpc/src/generic_rpc_connection.cpp @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file generic_rpc_connection.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of generic RPC connection + */ +#include +#include +#include +#include +#include + +namespace DPL +{ +namespace RPC +{ +namespace // anonymous +{ +namespace Protocol +{ +// Packet definitions +enum PacketType +{ + PacketType_AsyncCall, + PacketType_PingPong +}; + +struct Header +{ + unsigned short size; + unsigned short type; +} DPL_ALIGNED(1); + +struct AsyncCall + : public Header +{ + unsigned char data[1]; +} DPL_ALIGNED(1); + +} // namespace Protocol +} // namespace anonymous + +GenericRPCConnection::GenericRPCConnection(AbstractWaitableInputOutput *inputOutput) + : m_inputOutput(inputOutput) +{ + LogPedantic("Opening generic RPC..."); + WaitableInputOutputExecutionContextSupport::Open(inputOutput); + LogPedantic("Generic RPC opened"); +} + +GenericRPCConnection::~GenericRPCConnection() +{ + // Ensure RPC is closed + LogPedantic("Closing generic RPC..."); + WaitableInputOutputExecutionContextSupport::Close(); + LogPedantic("Generic RPC closed"); +} + +void GenericRPCConnection::AsyncCall(const RPCFunction &function) +{ + LogPedantic("Executing async call"); + + // Create binary call + BinaryQueue serializedCall = function.Serialize(); + + // Append buffers + Protocol::AsyncCall call; + call.size = static_cast(serializedCall.Size()); + call.type = Protocol::PacketType_AsyncCall; + + m_outputStream.AppendCopy(&call, sizeof(Protocol::Header)); + m_outputStream.AppendMoveFrom(serializedCall); + + // Try to feed output with data + Try + { + FeedOutput(); + } + Catch (WaitableInputOutputExecutionContextSupport::Exception::NotOpened) + { + // Error occurred while feeding + ReThrow(AbstractRPCConnection::Exception::AsyncCallFailed); + } +} + +void GenericRPCConnection::Ping() +{ + LogPedantic("Executing ping call"); + + // Append buffers + Protocol::AsyncCall call; + call.size = 0; + call.type = Protocol::PacketType_PingPong; + + m_outputStream.AppendCopy(&call, sizeof(Protocol::Header)); + + // Try to feed output with data + Try + { + FeedOutput(); + } + Catch (WaitableInputOutputExecutionContextSupport::Exception::NotOpened) + { + // Error occurred while feeding + ReThrow(AbstractRPCConnection::Exception::PingFailed); + } +} + +void GenericRPCConnection::OnInputStreamRead() +{ + LogPedantic("Interpreting " << m_inputStream.Size() << " bytes buffer"); + + // Enough bytes to read at least one header ? + if (m_inputStream.Size() >= sizeof(Protocol::Header)) + { + // Begin consuming as much packets as it is possible + while (m_inputStream.Size() >= sizeof(Protocol::Header)) + { + Protocol::Header header; + m_inputStream.Flatten(&header, sizeof(header)); + + if (m_inputStream.Size() >= sizeof(Protocol::Header) + header.size) + { + LogPedantic("Will parse packet of type: " << header.type); + + // Allocate new packet (header + real packet data) + void *binaryPacket = malloc(sizeof(Protocol::Header) + header.size); + + if (binaryPacket == NULL) + throw std::bad_alloc(); + + // Get it from stream + m_inputStream.FlattenConsume(binaryPacket, sizeof(Protocol::Header) + header.size); + + // Parse specific packet + switch (header.type) + { + case Protocol::PacketType_AsyncCall: + { + BinaryQueue call; + + // No need to delete packet data, we can use it + call.AppendUnmanaged(binaryPacket, sizeof(Protocol::Header) + header.size, &BinaryQueue::BufferDeleterFree, NULL); + + // ...but just remove protocol header + call.Consume(sizeof(Protocol::Header)); + + LogPedantic("Async call of size: " << header.size << " parsed"); + + // Call async call event listeners + DPL::Event::EventSupport:: + EmitEvent(AbstractRPCConnectionEvents::AsyncCallEvent( + RPCFunction(call), EventSender(this)), DPL::Event::EmitMode::Queued); + } + break; + + case Protocol::PacketType_PingPong: + { + // Reply with ping/pong + Ping(); + + // Do not need packet data + free(binaryPacket); + + LogPedantic("Ping pong replied"); + } + break; + + default: + LogPedantic("Warning: Unknown packet type"); + free(binaryPacket); + break; + } + } + else + { + LogPedantic("Too few bytes to read packet"); + break; + } + } + } + else + { + LogPedantic("Too few bytes to read header"); + } +} + +void GenericRPCConnection::OnInputStreamClosed() +{ + // Emit closed event + DPL::Event::EventSupport:: + EmitEvent(AbstractRPCConnectionEvents::ConnectionClosedEvent( + EventSender(this)), DPL::Event::EmitMode::Queued); +} + +void GenericRPCConnection::OnInputStreamBroken() +{ + // Emit broken event + DPL::Event::EventSupport:: + EmitEvent(AbstractRPCConnectionEvents::ConnectionBrokenEvent( + EventSender(this)), DPL::Event::EmitMode::Queued); +} + +} +} // namespace DPL diff --git a/modules/rpc/src/generic_socket_rpc_client.cpp b/modules/rpc/src/generic_socket_rpc_client.cpp new file mode 100644 index 0000000..3c09aac --- /dev/null +++ b/modules/rpc/src/generic_socket_rpc_client.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/modules/rpc/src/generic_socket_rpc_connection.cpp b/modules/rpc/src/generic_socket_rpc_connection.cpp new file mode 100644 index 0000000..0786c62 --- /dev/null +++ b/modules/rpc/src/generic_socket_rpc_connection.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/modules/rpc/src/generic_socket_rpc_server.cpp b/modules/rpc/src/generic_socket_rpc_server.cpp new file mode 100644 index 0000000..2472c66 --- /dev/null +++ b/modules/rpc/src/generic_socket_rpc_server.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/modules/rpc/src/unix_socket_rpc_client.cpp b/modules/rpc/src/unix_socket_rpc_client.cpp new file mode 100644 index 0000000..fb24741 --- /dev/null +++ b/modules/rpc/src/unix_socket_rpc_client.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file unix_socket_rpc_client.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of unix socket RPC client + */ +#include +#include + +namespace DPL +{ +namespace RPC +{ +AbstractRPCConnection *UnixSocketRPCClient::OpenSpecificConnection(DPL::Socket::UnixSocket *socket) +{ + // Allocate new UNIX/RPC connection object + UnixSocketRPCConnection *connection = new UnixSocketRPCConnection(socket); + + // Return new connection + return connection; +} + +AbstractRPCConnectionID UnixSocketRPCClient::Open(const std::string &fileName) +{ + return GenericSocketRPCClient::Open(Address(fileName)); +} +} +} // namespace DPL diff --git a/modules/rpc/src/unix_socket_rpc_connection.cpp b/modules/rpc/src/unix_socket_rpc_connection.cpp new file mode 100644 index 0000000..28fea84 --- /dev/null +++ b/modules/rpc/src/unix_socket_rpc_connection.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file unix_socket_rpc_connection.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of unix socket RPC connection + */ +#include + +namespace DPL +{ +namespace RPC +{ +UnixSocketRPCConnection::UnixSocketRPCConnection(DPL::Socket::UnixSocket *socket) + : GenericSocketRPCConnection(socket) +{ +} +} +} // namespace DPL diff --git a/modules/rpc/src/unix_socket_rpc_server.cpp b/modules/rpc/src/unix_socket_rpc_server.cpp new file mode 100644 index 0000000..ea71eb7 --- /dev/null +++ b/modules/rpc/src/unix_socket_rpc_server.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file unix_socket_rpc_server.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of unix socket RPC server + */ +#include +#include + +namespace DPL +{ +namespace RPC +{ +AbstractRPCConnection *UnixSocketRPCServer::OpenSpecificConnection(DPL::Socket::UnixSocket *socket) +{ + // Allocate new UNIX/RPC connection object + UnixSocketRPCConnection *connection = new UnixSocketRPCConnection(socket); + + // Return new connection + return connection; +} + +AbstractRPCConnectionID UnixSocketRPCServer::Open(const std::string &fileName) +{ + return GenericSocketRPCServer::Open(Address(fileName)); +} + +} +} // namespace DPL diff --git a/modules/socket/config.cmake b/modules/socket/config.cmake new file mode 100644 index 0000000..6e097a4 --- /dev/null +++ b/modules/socket/config.cmake @@ -0,0 +1,40 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# @file config.cmake +# @author Lukasz Marek (l.marek@samsung.com) +# @version 1.0 +# @brief +# + +SET(DPL_SOCKET_SOURCES + ${PROJECT_SOURCE_DIR}/modules/socket/src/generic_socket.cpp + ${PROJECT_SOURCE_DIR}/modules/socket/src/unix_socket.cpp + ${PROJECT_SOURCE_DIR}/modules/socket/src/waitable_input_output_execution_context_support.cpp + PARENT_SCOPE +) + +SET(DPL_SOCKET_HEADERS + ${PROJECT_SOURCE_DIR}/modules/socket/include/dpl/socket/abstract_socket.h + ${PROJECT_SOURCE_DIR}/modules/socket/include/dpl/socket/generic_socket.h + ${PROJECT_SOURCE_DIR}/modules/socket/include/dpl/socket/unix_socket.h + ${PROJECT_SOURCE_DIR}/modules/socket/include/dpl/socket/waitable_input_output_execution_context_support.h + PARENT_SCOPE +) + +SET(DPL_SOCKET_INCLUDE_DIR + ${PROJECT_SOURCE_DIR}/modules/socket/include/ + PARENT_SCOPE +) diff --git a/modules/socket/include/dpl/socket/abstract_socket.h b/modules/socket/include/dpl/socket/abstract_socket.h new file mode 100644 index 0000000..90a8fa6 --- /dev/null +++ b/modules/socket/include/dpl/socket/abstract_socket.h @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_socket.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file of abstract socket + */ +#ifndef DPL_ABSTRACT_SOCKET_H +#define DPL_ABSTRACT_SOCKET_H + +#include +#include +#include +#include +#include + +namespace DPL +{ +namespace Socket +{ +namespace AbstractSocketEvents +{ +// Successfuly connected to server socket +DECLARE_GENERIC_EVENT_0(ConnectedEvent) + +// New connection occurred and need to be accepted +DECLARE_GENERIC_EVENT_0(AcceptEvent) + +// Connection has read data waiting +DECLARE_GENERIC_EVENT_0(ReadEvent) + +// Connection write buffer is now empty again and ready to write more +DECLARE_GENERIC_EVENT_0(WriteEvent) +} // namespace AbstractSocketEvents + +class AbstractSocket + : public AbstractWaitableInputOutput, + public DPL::Event::EventSupport, + public DPL::Event::EventSupport, + public DPL::Event::EventSupport, + public DPL::Event::EventSupport +{ +public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) ///< Base abstract socket exception + + DECLARE_EXCEPTION_TYPE(Base, OpenFailed) ///< Fatal error occurred during open socket descriptor. Socket state is inconsistent and it should be not used anymore. + + DECLARE_EXCEPTION_TYPE(Base, ConnectFailed) ///< Fatal error occurred during connect. Socket state is inconsistent and it should be not used anymore. + ///< Warning: This exception does not mean that socket did not succeed to connect, see CannotConnect + ///< for this specific scenario + + DECLARE_EXCEPTION_TYPE(Base, SetNonBlockingFailed) ///< Fatal error occurred during setting socket to non-blocking mode. Socket state is inconsistent and it should be not used anymore. + + DECLARE_EXCEPTION_TYPE(Base, BindFailed) ///< Fatal error occurred during bind. Socket state is inconsistent and it should be not used anymore. + + DECLARE_EXCEPTION_TYPE(Base, AcceptFailed) ///< Fatal error occurred during accept. Socket state is inconsistent and it should be not used anymore. + + DECLARE_EXCEPTION_TYPE(Base, ListenFailed) ///< Fatal error occurred during listen. Socket state is inconsistent and it should be not used anymore. + + DECLARE_EXCEPTION_TYPE(Base, CloseFailed) ///< Fatal error occurred during close. Socket state is inconsistent and it should be not used anymore. + + DECLARE_EXCEPTION_TYPE(Base, ReadFailed) ///< Fatal error occurred during read. Socket state is inconsistent and it should be not used anymore. + ///< Warning: This exception does not mean that connection was broken, see ConnectionBroken + ///< for this specific scenario + + DECLARE_EXCEPTION_TYPE(Base, WriteFailed) ///< Fatal error occurred during write. Socket state is inconsistent and it should be not used anymore. + ///< Warning: This exception does not mean that connection was broken, see ConnectionBroken + ///< for this specific scenario + + DECLARE_EXCEPTION_TYPE(Base, GetPeerNameFailed) ///< Fatal error occurred during getpeername or getsockname. Socket state is inconsistent and it should be not used anymore. + + DECLARE_EXCEPTION_TYPE(Base, CannotConnect) ///< Cannot connect to remote socket. This is not fatal error, socket state is still consistent and it can be reconnected. + + DECLARE_EXCEPTION_TYPE(Base, ConnectionBroken) ///< Connection was broken. This is not fatal error, socket state is still consistent and it can be reconnected. + }; + +public: + virtual ~AbstractSocket() {} + + // Connect to remote host + virtual void Connect(const Address &address) = 0; + + // Open empty, unconnected socket + virtual void Open() = 0; + + // Close connection + virtual void Close() = 0; + + // Bind server socket address + virtual void Bind(const Address &address) = 0; + + // Begin listening for incoming connections + virtual void Listen(int backlog) = 0; + + // Accept waiting connection and create derived class connection + // One should cast resulting pointer to derived class + virtual AbstractSocket *Accept() = 0; + + // Local socket address + virtual Address GetLocalAddress() const = 0; + + // Remote socket address + virtual Address GetRemoteAddress() const = 0; +}; + +} +} // namespace DPL + +#endif // DPL_ABSTRACT_SOCKET_H diff --git a/modules/socket/include/dpl/socket/generic_socket.h b/modules/socket/include/dpl/socket/generic_socket.h new file mode 100644 index 0000000..f54d752 --- /dev/null +++ b/modules/socket/include/dpl/socket/generic_socket.h @@ -0,0 +1,835 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file generic_socket.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file of generic socket + */ +#ifndef DPL_GENERIC_SOCKET_H +#define DPL_GENERIC_SOCKET_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DPL +{ +namespace Socket +{ +// +// Generic abstract socket implementation +// Execution context is inherited +// +template +class GenericSocket + : public AbstractSocket, + private WaitableHandleWatchSupport::WaitableHandleListener +{ +protected: + /** + * Translate generic Address to specific socket kernel structure + * + * @warning Must be implemented in derived class + */ + virtual std::pair TranslateAddressGenericToSpecific(const Address &address) const = 0; + + /** + * Translate specific socket kernel structure to generic Address + * + * @warning Must be implemented in derived class + */ + virtual Address TranslateAddressSpecificToGeneric(sockaddr *, socklen_t) const = 0; + + /** + * Get specific socket kernel structure size + * + * @warning Must be implemented in derived class + */ + virtual socklen_t GetSpecificAddressSize() const = 0; + + /** + * Alloc specific implementation of socket from descriptor + * + * @warning Must be implemented in derived class + */ + virtual SocketType *AllocAcceptedSpecificSocket() const = 0; + + /** + * Alloc specific implementation of socket descriptor + * + * @warning Must be implemented in derived class + */ + virtual int AllocSpecificDescriptor() const = 0; + +private: + // Constants + static const size_t DEFAULT_READ_BUFFER_SIZE = 4096; + + // Socket handle + int m_socket; // FIXME: Consider generalization to WaitableHandle upon leaving nix platform + + // Internal state + enum InternalState + { + InternalState_None, ///< Not connected and not listening state + InternalState_Prepare, ///< Descriptor allocated, but not connected + InternalState_Listening, ///< Listening state + InternalState_Connecting, ///< Connecting state + InternalState_Connected ///< Connected state + }; + + InternalState m_internalState; + + void SetNonBlocking() + { + // Set non-blocking mode + if (fcntl(m_socket, F_SETFL, O_NONBLOCK | fcntl(m_socket, F_GETFL)) == -1) + Throw(AbstractSocket::Exception::SetNonBlockingFailed); + } + + // WaitableHandleWatchSupport::WaitableHandleListener + virtual void OnWaitableHandleEvent(WaitableHandle waitableHandle, WaitMode::Type mode) + { + (void)waitableHandle; + Assert(waitableHandle == m_socket); + + switch (m_internalState) + { + case InternalState_None: + break; + + case InternalState_Prepare: + Assert(0 && "Invalid internal generic socket state!"); + break; + + case InternalState_Listening: + Assert(mode == WaitMode::Read); + + // New client waiting for accept + DPL::Event::EventSupport:: + EmitEvent(AbstractSocketEvents::AcceptEvent( + EventSender(this)), DPL::Event::EmitMode::Queued); + + // Done + break; + + case InternalState_Connecting: + Assert(mode == WaitMode::Write); + + // Connected to server + RemoveConnectWatch(); + m_internalState = InternalState_Connected; + + // Add read watch + AddReadWatch(); + + // Emit event + DPL::Event::EventSupport:: + EmitEvent(AbstractSocketEvents::ConnectedEvent( + EventSender(this)), DPL::Event::EmitMode::Queued); + + // Done + break; + + case InternalState_Connected: + if (mode == WaitMode::Read) + { + // Emit ReadEvent + DPL::Event::EventSupport:: + EmitEvent(AbstractSocketEvents::ReadEvent( + EventSender(this)), DPL::Event::EmitMode::Queued); + } + else if (mode == WaitMode::Write) + { + // Emit WriteEvent + DPL::Event::EventSupport:: + EmitEvent(AbstractSocketEvents::WriteEvent( + EventSender(this)), DPL::Event::EmitMode::Queued); + } + else + { + Assert(0); + } + + break; + + default: + Assert(0); + break; + } + } + + void AddAcceptWatch() + { + WaitableHandleWatchSupport::InheritedContext()->AddWaitableHandleWatch(this, m_socket, WaitMode::Read); + } + + void RemoveAcceptWatch() + { + WaitableHandleWatchSupport::InheritedContext()->RemoveWaitableHandleWatch(this, m_socket, WaitMode::Read); + } + + void AddConnectWatch() + { + WaitableHandleWatchSupport::InheritedContext()->AddWaitableHandleWatch(this, m_socket, WaitMode::Write); + } + + void RemoveConnectWatch() + { + WaitableHandleWatchSupport::InheritedContext()->RemoveWaitableHandleWatch(this, m_socket, WaitMode::Write); + } + + void AddReadWatch() + { + WaitableHandleWatchSupport::InheritedContext()->AddWaitableHandleWatch(this, m_socket, WaitMode::Read); + } + + void RemoveReadWatch() + { + WaitableHandleWatchSupport::InheritedContext()->RemoveWaitableHandleWatch(this, m_socket, WaitMode::Read); + } + + void AddWriteWatch() + { + WaitableHandleWatchSupport::InheritedContext()->AddWaitableHandleWatch(this, m_socket, WaitMode::Write); + } + + void RemoveWriteWatch() + { + WaitableHandleWatchSupport::InheritedContext()->RemoveWaitableHandleWatch(this, m_socket, WaitMode::Write); + } + +public: + GenericSocket() + : m_socket(-1), + m_internalState(InternalState_None) + { + } + + virtual ~GenericSocket() + { + // Always ensure to close socket + Try + { + Close(); + } + Catch(Exception::CloseFailed) + { + LogPedantic("Close failed and ignored"); + } + + // Check consistency + Assert(m_socket == -1); + } + + virtual void Open() + { + if (m_internalState != InternalState_None) + ThrowMsg(AbstractSocket::Exception::OpenFailed, "Invalid socket state, should be 'None'"); + + LogPedantic("Opening socket..."); + + // Check consistency + Assert(m_socket == -1); + + // Allocate specific socket descriptor + m_socket = AllocSpecificDescriptor(); + + // Set socket non-blocking + SetNonBlocking(); + + // State is prepared + m_internalState = InternalState_Prepare; + + LogPedantic("Socket opened"); + } + + virtual void Connect(const Address &address) + { + if (m_internalState != InternalState_Prepare) + ThrowMsg(AbstractSocket::Exception::ConnectFailed, "Invalid socket state, should be 'Prepare'"); + + LogPedantic("Connecting to: " << address.ToString()); + + // Try to convert address + std::pair socketAddress; + + Try + { + // Translate address to specific socket address struct + socketAddress = TranslateAddressGenericToSpecific(address); + } + Catch (Address::Exception::InvalidAddress) + { + // This address is invalid. Cannot connect. + ReThrowMsg(AbstractSocket::Exception::ConnectFailed, address.ToString()); + } + + // Do connect + int result = TEMP_FAILURE_RETRY(connect(m_socket, socketAddress.first, socketAddress.second)); + + if (result == 0) + { + // Immediate connect + LogPedantic("Immediate connected to: " << address.ToString()); + + // Add read watch + AddReadWatch(); + m_internalState = InternalState_Connected; + + // Emit connected event + DPL::Event::EventSupport:: + EmitEvent(AbstractSocketEvents::ConnectedEvent( + EventSender(this)), DPL::Event::EmitMode::Queued); + } + else + { + if (errno == EINTR || errno == EINPROGRESS) + { + LogPedantic("Asynchronous connect in progress: " << address.ToString()); + + // Connecting in progress + AddConnectWatch(); + m_internalState = InternalState_Connecting; + } + else + { + // Free translation structure + free(socketAddress.first); + + // Error occurred + ThrowMsg(AbstractSocket::Exception::ConnectFailed, address.ToString()); + } + } + + // Free translation structure + free(socketAddress.first); + } + + virtual void Close() + { + if (m_internalState == InternalState_None) + return; + + Assert(m_socket != -1); + + if (m_internalState == InternalState_Listening) + { + // Remove watch in listening state + LogPedantic("Removing accept watch"); + RemoveAcceptWatch(); + m_internalState = InternalState_None; + } + else if (m_internalState == InternalState_Connecting) + { + // Remove watch in connecting state + LogPedantic("Removing connect watch"); + RemoveConnectWatch(); + m_internalState = InternalState_None; + } + else if (m_internalState == InternalState_Connected) + { + // Remove watch in connected state + LogPedantic("Removing read watch"); + RemoveReadWatch(); + m_internalState = InternalState_None; + } + else + { + // State must be just prepared only + Assert(m_internalState == InternalState_Prepare); + } + + if (TEMP_FAILURE_RETRY(close(m_socket)) == -1) + Throw(Exception::CloseFailed); + + // Reset socket + m_socket = -1; + + // Reset socket state + m_internalState = InternalState_None; + + LogPedantic("Socket closed"); + } + + virtual void Bind(const Address &address) + { + if (m_internalState != InternalState_Prepare) + ThrowMsg(AbstractSocket::Exception::BindFailed, "Invalid socket state, should be 'Prepare'"); + + LogPedantic("Binding to: " << address.GetAddress() << ":" << address.GetPort()); + + // Translate address to specific socket address struct + std::pair socketAddress = TranslateAddressGenericToSpecific(address); + + // Do bind + if (::bind(m_socket, socketAddress.first, socketAddress.second) == -1) + ThrowMsg(AbstractSocket::Exception::BindFailed, address.ToString()); + + // Free translation structure + free(socketAddress.first); + + // Show info + LogPedantic("Bound to address: " << address.GetAddress() << ":" << address.GetPort()); + } + + virtual void Listen(int backlog) + { + if (m_internalState != InternalState_Prepare) + ThrowMsg(AbstractSocket::Exception::ListenFailed, "Invalid socket state, should be 'None'"); + + LogPedantic("Starting to listen..."); + + // Do listen + if (listen(m_socket, backlog) != 0) + Throw(AbstractSocket::Exception::ListenFailed); + + // Begin read watch + AddAcceptWatch(); + m_internalState = InternalState_Listening; + + LogPedantic("Listen started"); + } + + virtual AbstractSocket *Accept() + { + if (m_internalState != InternalState_Listening) + ThrowMsg(AbstractSocket::Exception::AcceptFailed, "Invalid socket state, should be 'Listening'"); + + LogPedantic("Accepting..."); + + // Do listen + socklen_t length = 0; + int client = TEMP_FAILURE_RETRY(accept(m_socket, NULL, &length)); + + LogPedantic("Socket accept returned " << client); + if (client == -1) + { + // Check if there is any client waiting + if (errno == EWOULDBLOCK || errno == EAGAIN) + return NULL; + int err = errno; + if (errno == ENOENT) + return NULL; + LogPedantic("throwing error. errrno " << err); + // Error occurred + Throw(AbstractSocket::Exception::AcceptFailed); + } + + LogPedantic("Accepted client. Seting up..."); + + // Create derived class type + GenericSocket *acceptedSocket = AllocAcceptedSpecificSocket(); + + // Save client socket specific descriptor + acceptedSocket->m_socket = client; + + // Enter proper states and add read watch + acceptedSocket->AddReadWatch(); + acceptedSocket->m_internalState = InternalState_Connected; + + // Set non-blocking mode for new socket + acceptedSocket->SetNonBlocking(); + + // Show info + LogPedantic("Accepted client set up"); + + // return new conneced client socket + return acceptedSocket; + } + + virtual Address GetLocalAddress() const + { + // FIXME: Additional internal state check + + socklen_t length = GetSpecificAddressSize(); + ScopedFree address(static_cast(calloc(static_cast(length), 1))); + + if (getsockname(m_socket, address.Get(), &length) == -1) + ThrowMsg(AbstractSocket::Exception::GetPeerNameFailed, "Failed to get local address"); + + return TranslateAddressSpecificToGeneric(address.Get(), length); + } + + virtual Address GetRemoteAddress() const + { + // FIXME: Additional internal state check + + socklen_t length = GetSpecificAddressSize(); + ScopedFree address(static_cast(calloc(static_cast(length), 1))); + + if (getpeername(m_socket, address.Get(), &length) == -1) + ThrowMsg(AbstractSocket::Exception::GetPeerNameFailed, "Failed to get remote address"); + + return TranslateAddressSpecificToGeneric(address.Get(), length); + } + + virtual BinaryQueueAutoPtr Read(size_t size) + { + if (m_internalState != InternalState_Connected) + ThrowMsg(AbstractSocket::Exception::AcceptFailed, "Invalid socket state, should be 'Connected'"); + + Try + { + // Adjust bytes to be read + size_t bytesToRead = size > DEFAULT_READ_BUFFER_SIZE ? DEFAULT_READ_BUFFER_SIZE : size; + + // Malloc default read buffer size + // It is unmanaged, so it can be then attached directly to binary queue + void *buffer = malloc(bytesToRead); + + if (buffer == NULL) + throw std::bad_alloc(); + + // Receive bytes from socket + ssize_t result = TEMP_FAILURE_RETRY(recv(m_socket, buffer, bytesToRead, 0)); + + if (result > 0) + { + // Succedded to read socket data + BinaryQueueAutoPtr binaryQueue(new BinaryQueue()); + + // Append unmanaged memory + binaryQueue->AppendUnmanaged(buffer, result, &BinaryQueue::BufferDeleterFree, NULL); + + // Return buffer + return binaryQueue; + } + else if (result == 0) + { + // Socket was gracefuly closed + free(buffer); + + // Return empty buffer + return BinaryQueueAutoPtr(new BinaryQueue()); + } + else + { + // Must first save errno value, because it may be altered + int lastErrno = errno; + + // Free buffer + free(buffer); + + // Interpret error result + switch (lastErrno) + { + case EAGAIN: // = EWOULDBLOCK + // + // * The socket's file descriptor is marked O_NONBLOCK and no data is waiting + // to be received; or MSG_OOB is set and no out-of-band data is available + // and either the socket's file descriptor is marked O_NONBLOCK or the socket + // does not support blocking to await out-of-band data. + // + // return null data buffer to indicate no data waiting + // + return BinaryQueueAutoPtr(); + + case EBADF: + // + // * The socket argument is not a valid file descriptor. + // + // This is internal error + // + ThrowMsg(CommonException::InternalError, "Invalid socket descriptor"); + + case ECONNRESET: + // + // * A connection was forcibly closed by a peer. + // + // In result, we can interpret this error as a broken connection + // + Throw(AbstractSocket::Exception::ConnectionBroken); + + case EINTR: + // + // * The recv() function was interrupted by a signal that was caught, before any + // data was available. + // + // No interrupt here is expected, due to fact that we used TEMP_FAILURE_RETRY + // + ThrowMsg(CommonException::InternalError, "Unexpected interrupt occurred"); + + case EINVAL: + // + // * The MSG_OOB flag is set and no out-of-band data is available. + // + // We did not specified OOB data. This is an error. + // + ThrowMsg(CommonException::InternalError, "Unexpected OOB error occurred"); + + case ENOTCONN: + // + // * A receive is attempted on a connection-mode socket that is not connected. + // + // FIXME: Is this proper exception here ? + // + ThrowMsg(CommonException::InternalError, "Socket is not connected"); + + case ENOTSOCK: + // + // * The socket argument does not refer to a socket. + // + ThrowMsg(CommonException::InternalError, "Handle is not a socket"); + + case EOPNOTSUPP: + // + // * The specified flags are not supported for this socket type or protocol. + // + ThrowMsg(CommonException::InternalError, "Socket flags not supported"); + + case ETIMEDOUT: + // + // * The connection timed out during connection establishment, or due to a transmission timeout on active connection. + // + // In result, we can interpret this error as a broken connection + // + Throw(AbstractSocket::Exception::ConnectionBroken); + + case EIO: + // + // * An I/O error occurred while reading from or writing to the file system. + // + // In result, we can interpret this error as a broken connection + // + Throw(AbstractSocket::Exception::ConnectionBroken); + + case ENOBUFS: + // + // * Insufficient resources were available in the system to perform the operation. + // + ThrowMsg(CommonException::InternalError, "Insufficient system resources"); + + case ENOMEM: + // + // * Insufficient memory was available to fulfill the request. + // + ThrowMsg(CommonException::InternalError, "Insufficient system memory"); + + default: + // Some kernel error occurred, should never happen + ThrowMsg(CommonException::InternalError, "Unknown kernel read error returned"); + break; + } + } + } + Catch (CommonException::InternalError) + { + // If any internal error occurred, this is fatal for Write method + // interpret this as WriteError exception and rethrow + ReThrow(AbstractSocket::Exception::ReadFailed); + } + } + + virtual size_t Write(const BinaryQueue &buffer, size_t bufferSize) + { + if (m_internalState != InternalState_Connected) + ThrowMsg(AbstractSocket::Exception::AcceptFailed, "Invalid socket state, should be 'Connected'"); + + Try + { + // Adjust write size + if (bufferSize > buffer.Size()) + bufferSize = buffer.Size(); + + // FIXME: User write visitor to write ! + // WriteVisitor visitor + + ScopedFree flattened(malloc(bufferSize)); + buffer.Flatten(flattened.Get(), bufferSize); + + // Linux: MSG_NOSIGNAL is supported, but it is not an ideal solution + // FIXME: Should we setup signal PIPE ignoring for whole process ? + // In BSD, there is: setsockopt(c, SOL_SOCKET, SO_NOSIGPIPE, (void *)&on, sizeof(on)) + ssize_t result = TEMP_FAILURE_RETRY(send(m_socket, flattened.Get(), bufferSize, MSG_NOSIGNAL)); + + if (result > 0) + { + // Successfuly written some bytes + return static_cast(result); + } + else if (result == 0) + { + // This is abnormal result + ThrowMsg(CommonException::InternalError, "Invalid socket write result, 0 bytes written"); + } + else if (result == -1) + { + // Interpret error result + switch (errno) + { + case EAGAIN: // = EWOULDBLOCK + // + // * The socket's file descriptor is marked O_NONBLOCK and the requested operation would block. + // + // We should wait for writability + // + return 0; + + case EBADF: + // + // * The socket argument is not a valid file descriptor. + // + // This is internal error + // + ThrowMsg(CommonException::InternalError, "Invalid socket descriptor"); + + case ECONNRESET: + // + // * A connection was forcibly closed by a peer. + // + // In result, we can interpret this error as a broken connection + // + Throw(AbstractSocket::Exception::ConnectionBroken); + + case EDESTADDRREQ: + // + // * The socket is not connection-mode and no peer address is set. + // + // FIXME: Is this proper exception here ? + // + ThrowMsg(CommonException::InternalError, "Socket is not connected"); + + case EINTR: + // + // * A signal interrupted send() before any data was transmitted. + // + // No interrupt here is expected, due to fact that we used TEMP_FAILURE_RETRY + // + ThrowMsg(CommonException::InternalError, "Unexpected interrupt occurred"); + + case EMSGSIZE: + // + // * The message is too large to be sent all at once, as the socket requires. + // + // FIXME: Is this proper exception here ? + // + ThrowMsg(CommonException::InternalError, "Socket message is too big"); + + case ENOTCONN: + // + // * The socket is not connected or otherwise has not had the peer pre-specified. + // + // FIXME: Is this proper exception here ? + // + ThrowMsg(CommonException::InternalError, "Socket is not connected"); + + case ENOTSOCK: + // + // * The socket argument does not refer to a socket. + // + ThrowMsg(CommonException::InternalError, "Handle is not a socket"); + + case EOPNOTSUPP: + // + // * The socket argument is associated with a socket that does not support one or more of the values set in flags. + // + ThrowMsg(CommonException::InternalError, "Socket flags not supported"); + + case EPIPE: + // + // * The socket is shut down for writing, or the socket is connection-mode and + // is no longer connected. In the latter case, and if the socket is of type + // SOCK_STREAM, the SIGPIPE signal is generated to the calling thread. + // + // In result, we can interpret this error as a broken connection + // + Throw(AbstractSocket::Exception::ConnectionBroken); + + case EACCES: + // + // * The calling process does not have the appropriate privileges. + // + // Priviledges might have changed. + // In result, we can interpret this error as a broken connection + // + Throw(AbstractSocket::Exception::ConnectionBroken); + + case EIO: + // + // * An I/O error occurred while reading from or writing to the file system. + // + // In result, we can interpret this error as a broken connection + // + Throw(AbstractSocket::Exception::ConnectionBroken); + + case ENETDOWN: + // + // * The local network interface used to reach the destination is down. + // + // In result, we can interpret this error as a broken connection + // + Throw(AbstractSocket::Exception::ConnectionBroken); + + case ENETUNREACH: + // + // * No route to the network is present. + // + // In result, we can interpret this error as a broken connection + // + Throw(AbstractSocket::Exception::ConnectionBroken); + + case ENOBUFS: + // + // * Insufficient resources were available in the system to perform the operation. + // + ThrowMsg(CommonException::InternalError, "Insufficient system resources"); + + default: + // Some kernel error occurred, should never happen + ThrowMsg(CommonException::InternalError, "Unknown kernel write error returned"); + break; + } + } + } + Catch (CommonException::InternalError) + { + // If any internal error occurred, this is fatal for Write method + // interpret this as WriteError exception and rethrow + ReThrow(AbstractSocket::Exception::WriteFailed); + } + + // Does not apply + return 0; + } + + // AbstractWaitableInput + virtual WaitableHandle WaitableReadHandle() const + { + return m_socket; + } + + // AbstractWaitableOutput + virtual WaitableHandle WaitableWriteHandle() const + { + return m_socket; + } +}; + +} +} // namespace DPL + +#endif // DPL_GENERIC_SOCKET_H diff --git a/modules/socket/include/dpl/socket/unix_socket.h b/modules/socket/include/dpl/socket/unix_socket.h new file mode 100644 index 0000000..3d7b9fe --- /dev/null +++ b/modules/socket/include/dpl/socket/unix_socket.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file unix_socket.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file of unix socket + */ +#ifndef DPL_UNIX_SOCKET_H +#define DPL_UNIX_SOCKET_H + +#include +#include + +namespace DPL +{ +namespace Socket +{ + +class UnixSocket + : public GenericSocket +{ +public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, CreateFailed) + }; + +protected: + /** + * Translate generic Address to specific socket kernel structure + */ + virtual std::pair TranslateAddressGenericToSpecific(const Address &address) const; + + /** + * Translate specific socket kernel structure to generic Address + */ + virtual Address TranslateAddressSpecificToGeneric(sockaddr *, socklen_t) const; + + /** + * Get specific socket kernel structure size + */ + virtual socklen_t GetSpecificAddressSize() const; + + /** + * Alloc specific implementation of socket from descriptor + */ + virtual UnixSocket *AllocAcceptedSpecificSocket() const; + + /** + * Alloc specific implementation of socket descriptor + */ + virtual int AllocSpecificDescriptor() const; + +public: + UnixSocket(); + + virtual void Bind(const Address &address); +}; + +} +} // namespace DPL + +#endif // DPL_GENERIC_SOCKET_H diff --git a/modules/socket/include/dpl/socket/waitable_input_output_execution_context_support.h b/modules/socket/include/dpl/socket/waitable_input_output_execution_context_support.h new file mode 100644 index 0000000..cfdbac2 --- /dev/null +++ b/modules/socket/include/dpl/socket/waitable_input_output_execution_context_support.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file waitable_input_output_execution_context_support.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file for waitable input-output execution context support + */ +#ifndef DPL_WAITABLE_INPUT_OUTPUT_EXECUTION_CONTEXT_SUPPORT_H +#define DPL_WAITABLE_INPUT_OUTPUT_EXECUTION_CONTEXT_SUPPORT_H + +#include +#include +#include + +namespace DPL +{ +namespace Socket +{ + +class WaitableInputOutputExecutionContextSupport + : private WaitableHandleWatchSupport::WaitableHandleListener +{ +public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, AlreadyOpened) + DECLARE_EXCEPTION_TYPE(Base, NotOpened) + DECLARE_EXCEPTION_TYPE(Base, OpenFailed) + DECLARE_EXCEPTION_TYPE(Base, CloseFailed) + }; + +private: + bool m_opened; + AbstractWaitableInputOutput *m_waitableInputOutput; + + // Watch state + bool m_hasReadWatch; + bool m_hasWriteWatch; + + void AddReadWatch(); + void RemoveReadWatch(); + void AddWriteWatch(); + void RemoveWriteWatch(); + + void ReadInput(); + + void CheckedRemoveReadWatch(); + void CheckedRemoveWriteWatch(); + + void CheckedRemoveReadWriteWatch(); + + virtual void OnWaitableHandleEvent(WaitableHandle waitableHandle, WaitMode::Type mode); + +protected: + // Incoming/Outgoing streams + BinaryQueue m_inputStream; + BinaryQueue m_outputStream; + + // Support calbback methods + virtual void OnInputStreamRead() = 0; + virtual void OnInputStreamClosed() = 0; + virtual void OnInputStreamBroken() = 0; + + // Trigger feeding output - after updating output stream + void FeedOutput(); + + // Open/Close destination waitable input-output + void Open(AbstractWaitableInputOutput *waitableInputOutput); + void Close(); + +public: + /** + * Constructor + */ + explicit WaitableInputOutputExecutionContextSupport(); + + /** + * Destructor + */ + virtual ~WaitableInputOutputExecutionContextSupport(); +}; + +} +} // namespace DPL + +#endif // DPL_WAITABLE_INPUT_OUTPUT_EXECUTION_CONTEXT_SUPPORT_H diff --git a/modules/socket/src/generic_socket.cpp b/modules/socket/src/generic_socket.cpp new file mode 100644 index 0000000..a8e2237 --- /dev/null +++ b/modules/socket/src/generic_socket.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file generic_socket.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of generic socket + */ +#include + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/modules/socket/src/unix_socket.cpp b/modules/socket/src/unix_socket.cpp new file mode 100644 index 0000000..f185da3 --- /dev/null +++ b/modules/socket/src/unix_socket.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file unix_socket.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of unix socket + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DPL +{ +namespace Socket +{ + +UnixSocket::UnixSocket() +{ +} + +int UnixSocket::AllocSpecificDescriptor() const +{ + LogPedantic("Creating UNIX socket..."); + + // Create new descriptor + int newSocket = socket(AF_UNIX, SOCK_STREAM, 0); + + if (newSocket == -1) + Throw(Exception::CreateFailed); + + LogPedantic("UNIX socket created"); + + // Return new descriptor + return newSocket; +} + +std::pair UnixSocket::TranslateAddressGenericToSpecific(const Address &address) const +{ + // Allocate new socket address structure + sockaddr_un *sockAddress = static_cast(malloc(sizeof(sockaddr_un))); + if (!sockAddress) throw std::bad_alloc(); + + memset(sockAddress, 0, sizeof(sockaddr_un)); + + // Copy address properties + sockAddress->sun_family = AF_UNIX; + strncpy(sockAddress->sun_path, address.GetAddress().c_str(), sizeof(sockAddress->sun_path) - 1); + 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(sockAddress), sockAddressLength); +} + +Address UnixSocket::TranslateAddressSpecificToGeneric(sockaddr *address, socklen_t) const +{ + // FIXME: Constrain check ? + sockaddr_un *unixAddress = reinterpret_cast(address); + return Address(unixAddress->sun_path); +} + +socklen_t UnixSocket::GetSpecificAddressSize() const +{ + return static_cast(sizeof(sockaddr_un)); +} + +UnixSocket *UnixSocket::AllocAcceptedSpecificSocket() const +{ + return new UnixSocket(); +} + +void UnixSocket::Bind(const Address &address) +{ + // Always remove socket file if any + unlink(address.GetAddress().c_str()); + + // Call base implementation + GenericSocket::Bind(address); + + // Always set proper permissions to the socket file + chmod(address.GetAddress().c_str(), 0777); +} + +} +} // namespace DPL diff --git a/modules/socket/src/waitable_input_output_execution_context_support.cpp b/modules/socket/src/waitable_input_output_execution_context_support.cpp new file mode 100644 index 0000000..7411b49 --- /dev/null +++ b/modules/socket/src/waitable_input_output_execution_context_support.cpp @@ -0,0 +1,288 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file waitable_input_output_execution_context_support.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of waitable input-output execution context support + */ +#include +#include +#include // FIXME: Remove !!! +#include +#include + +namespace DPL +{ +namespace Socket +{ + +namespace // anonymous +{ +const size_t DEFAULT_READ_SIZE = 2048; +} // namespace anonymous + +WaitableInputOutputExecutionContextSupport::WaitableInputOutputExecutionContextSupport() + : m_opened(false), + m_waitableInputOutput(NULL), + m_hasReadWatch(false), + m_hasWriteWatch(false) +{ +} + +WaitableInputOutputExecutionContextSupport::~WaitableInputOutputExecutionContextSupport() +{ + // Ensure support is closed + Close(); +} + +void WaitableInputOutputExecutionContextSupport::Open(AbstractWaitableInputOutput *inputOutput) +{ + if (m_opened) + Throw(Exception::AlreadyOpened); + + LogPedantic("Opening waitable input-output execution context support..."); + + // Save IO handle + m_waitableInputOutput = inputOutput; + + // Register read watch + Assert(m_hasReadWatch == false); + + AddReadWatch(); + m_hasReadWatch = true; + + // Done + m_opened = true; + + LogPedantic("Waitable input-output execution context support opened"); +} + +void WaitableInputOutputExecutionContextSupport::Close() +{ + if (!m_opened) + return; + + LogPedantic("Closing waitable input-output execution context support..."); + + // Remove read and write watches + CheckedRemoveReadWriteWatch(); + + // Set proper state + m_opened = false; + + LogPedantic("Waitable input-output execution context support closed"); +} + +void WaitableInputOutputExecutionContextSupport::AddReadWatch() +{ + WaitableHandleWatchSupport::InheritedContext()->AddWaitableHandleWatch(this, m_waitableInputOutput->WaitableReadHandle(), WaitMode::Read); +} + +void WaitableInputOutputExecutionContextSupport::RemoveReadWatch() +{ + WaitableHandleWatchSupport::InheritedContext()->RemoveWaitableHandleWatch(this, m_waitableInputOutput->WaitableReadHandle(), WaitMode::Read); +} + +void WaitableInputOutputExecutionContextSupport::AddWriteWatch() +{ + WaitableHandleWatchSupport::InheritedContext()->AddWaitableHandleWatch(this, m_waitableInputOutput->WaitableWriteHandle(), WaitMode::Write); +} + +void WaitableInputOutputExecutionContextSupport::RemoveWriteWatch() +{ + WaitableHandleWatchSupport::InheritedContext()->RemoveWaitableHandleWatch(this, m_waitableInputOutput->WaitableWriteHandle(), WaitMode::Write); +} + +void WaitableInputOutputExecutionContextSupport::CheckedRemoveReadWatch() +{ + if (!m_hasReadWatch) + return; + + RemoveReadWatch(); + m_hasReadWatch = false; +} + +void WaitableInputOutputExecutionContextSupport::CheckedRemoveWriteWatch() +{ + if (!m_hasWriteWatch) + return; + + RemoveWriteWatch(); + m_hasWriteWatch = false; +} + +void WaitableInputOutputExecutionContextSupport::CheckedRemoveReadWriteWatch() +{ + // Remove read watch if any + CheckedRemoveReadWatch(); + + // Remove write watch if any + CheckedRemoveWriteWatch(); +} + +void WaitableInputOutputExecutionContextSupport::OnWaitableHandleEvent(WaitableHandle waitableHandle, WaitMode::Type mode) +{ + (void)waitableHandle; + + switch (mode) + { + case WaitMode::Read: + LogPedantic("Read event occurred"); + + // Read and parse bytes + ReadInput(); + + // Done + break; + + case WaitMode::Write: + LogPedantic("Write event occurred"); + + // Push bytes and unregister from write event + FeedOutput(); + + // Unregister write watch only if no more data is available + if (m_outputStream.Empty()) + { + Assert(m_hasWriteWatch == true); + CheckedRemoveWriteWatch(); + } + + // Done + break; + + default: + Assert(0); + break; + } +} + +void WaitableInputOutputExecutionContextSupport::ReadInput() +{ + LogPedantic("Reading input bytes"); + + Try + { + BinaryQueueAutoPtr inputBuffer = m_waitableInputOutput->Read(DEFAULT_READ_SIZE); + + if (inputBuffer.get() == NULL) + { + // No data, should not occur + LogPedantic("WARNING: Spontaneous ReadSocket occurred"); + return; + } + + if (inputBuffer->Empty()) + { + // Connection was closed + OnInputStreamClosed(); + + // Unregister from further event insisting + Assert(m_hasReadWatch == true); + CheckedRemoveReadWriteWatch(); + + // Set proper state + m_opened = false; + + // Done + return; + } + + LogPedantic("Read " << inputBuffer->Size() << " input bytes"); + + // Append all read data + m_inputStream.AppendMoveFrom(*inputBuffer); + } + Catch (AbstractSocket::Exception::ConnectionBroken) // FIXME: Inproper exception abstraction !!! + { + // Some errors occurred while feeding abstract IO + // Interpret connection broken errors, and pass futher other ones + LogPedantic("Abstract IO connection was broken during read"); + + // Signal broken connection + OnInputStreamBroken(); + + // Unregister from further event insisting + Assert(m_hasReadWatch == true); + CheckedRemoveReadWriteWatch(); + + // Set proper state + m_opened = false; + + // Do not continue + return; + } + + // Interpret data + OnInputStreamRead(); +} + +void WaitableInputOutputExecutionContextSupport::FeedOutput() +{ + if (!m_opened) + Throw(Exception::NotOpened); + + // Anything to feed ? + if (m_outputStream.Empty()) + return; + + // OK to feed output + LogPedantic("Feeding output"); + + Try + { + // Try to write some bytes + size_t bytes = m_waitableInputOutput->Write(m_outputStream, m_outputStream.Size()); + + if (bytes < m_outputStream.Size()) + { + // Start exhaustive output feeding if it is blocked and not already started + if (!m_hasWriteWatch) + { + AddWriteWatch(); + m_hasWriteWatch = true; + + LogPedantic("Started exhaustive output feeding"); + } + } + + // Some bytes were written, consume them + m_outputStream.Consume(bytes); + } + Catch (AbstractSocket::Exception::ConnectionBroken) // FIXME: Inproper exception abstraction !!! + { + // Some errors occurred while feeding abstract IO + // Interpret connection broken errors, and pass futher other ones + LogPedantic("Abstract IO connection was broken during write"); + + // Signal broken connection + OnInputStreamBroken(); + + // Unregister from further event insisting + Assert(m_hasReadWatch == true); + CheckedRemoveReadWriteWatch(); + + // Set proper state + m_opened = false; + + // Do not continue + return; + } +} + +} +} // namespace DPL diff --git a/modules/test/config.cmake b/modules/test/config.cmake new file mode 100644 index 0000000..69d5341 --- /dev/null +++ b/modules/test/config.cmake @@ -0,0 +1,38 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# @file 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 +) diff --git a/modules/test/include/dpl/test/test_results_collector.h b/modules/test/include/dpl/test/test_results_collector.h new file mode 100644 index 0000000..6c4e24b --- /dev/null +++ b/modules/test/include/dpl/test/test_results_collector.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_results_collector.h + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + * @brief Header file with declaration of TestResultsCollectorBase + */ + +#ifndef DPL_TEST_RESULTS_COLLECTOR_H +#define DPL_TEST_RESULTS_COLLECTOR_H + +#include +#include +#include +#include +#include +#include + +namespace DPL +{ +namespace Test +{ + +class TestResultsCollectorBase; +typedef DPL::SharedPtr + TestResultsCollectorBasePtr; + +class TestResultsCollectorBase + : private DPL::Noncopyable +{ + public: + typedef TestResultsCollectorBase* (*CollectorConstructorFunc)(); + typedef std::list 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 GetCollectorsNames(); + + private: + typedef std::map ConstructorsMap; + static ConstructorsMap m_constructorsMap; +}; + +} +} + +#endif /* DPL_TEST_RESULTS_COLLECTOR_H */ diff --git a/modules/test/include/dpl/test/test_runner.h b/modules/test/include/dpl/test/test_runner.h new file mode 100644 index 0000000..ab1a626 --- /dev/null +++ b/modules/test/include/dpl/test/test_runner.h @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_runner.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + * @brief This file is the header file of test runner + */ +#ifndef DPL_TEST_RUNNER_H +#define DPL_TEST_RUNNER_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 TestCaseStructList; + typedef std::map TestCaseGroupMap; + TestCaseGroupMap m_testGroups; + + typedef std::set SelectedTestNameSet; + SelectedTestNameSet m_selectedTestNamesSet; + typedef std::set SelectedTestGroupSet; + SelectedTestGroupSet m_selectedTestGroupSet; + std::string m_currentGroup; + + DPL::Atomic m_totalAssertions; + + 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 ArgsList; + int ExecTestRunner(const ArgsList& args); +}; + +typedef DPL::Singleton TestRunnerSingleton; + +} +} // namespace DPL + +#define RUNNER_TEST_GROUP_INIT(GroupName) \ + static int Static##GroupName##Init() \ + { \ + DPL::Test::TestRunnerSingleton::Instance().InitGroup(#GroupName);\ + return 0; \ + } \ + const int DPL_UNUSED Static##GroupName##InitVar = \ + Static##GroupName##Init(); + +#define RUNNER_TEST(Proc) \ + void Proc(); \ + static int Static##Proc##Init() \ + { \ + DPL::Test::TestRunnerSingleton::Instance().RegisterTest(#Proc, &Proc); \ + return 0; \ + } \ + const int DPL_UNUSED Static##Proc##InitVar = Static##Proc##Init(); \ + void Proc() + +//! \brief Returns base name for path + +#define RUNNER_ASSERT_MSG(test, message) \ +do \ +{ \ + DPL::Test::TestRunnerSingleton::Instance().MarkAssertion(); \ + \ + if (!(test)) \ + { \ + std::ostringstream assertMsg; \ + assertMsg << message; \ + throw DPL::Test::TestRunner::TestFailed(#test, __FILE__, __LINE__, assertMsg.str()); \ + } \ +} while (0) + +#define RUNNER_ASSERT(test) RUNNER_ASSERT_MSG(test, "") + +#define RUNNER_FAIL RUNNER_ASSERT(false) + +#define RUNNER_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 diff --git a/modules/test/src/test_results_collector.cpp b/modules/test/src/test_results_collector.cpp new file mode 100644 index 0000000..07a6a69 --- /dev/null +++ b/modules/test/src/test_results_collector.cpp @@ -0,0 +1,529 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_results_collector.h + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + * @brief Implementation file some concrete TestResulstsCollector + */ + +#include +#include +#include +#include +#include + +#include +#include + +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(m_passed) + + static_cast(m_ignored)) + / static_cast(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 m_groupsStats; + std::string m_currentGroup; +}; + + +TestResultsCollectorBase* ConsoleCollector::Constructor() +{ + return new ConsoleCollector(); +} + + +class HtmlCollector + : public TestResultsCollectorBase +{ + public: + static TestResultsCollectorBase* Constructor(); + + private: + HtmlCollector() : m_filename(DEFAULT_HTML_FILE_NAME) {} + + virtual void CollectCurrentTestGroupName(const std::string& name) + { + fprintf(m_fp.Get(),"Starting group %s", name.c_str()); + m_currentGroup = name; + } + + virtual bool Configure() + { + m_fp.Reset(fopen (m_filename.c_str(), "w")); + if (!m_fp) { + LogPedantic("Could not open file " << m_filename << " for writing"); + return false; + } + return true; + } + virtual std::string CollectorSpecificHelp() const + { + return "--file= - name of file for output\n" + " default - index.html\n"; + } + + virtual void Start() + { + Assert(!!m_fp && "File handle must not be null"); + fprintf(m_fp.Get(), + "\n"); + fprintf(m_fp.Get(), + "\n"); + fprintf(m_fp.Get(), "\n"); + fprintf(m_fp.Get(), "
\n");
+        fprintf(m_fp.Get(), "\n");
+    }
+
+    virtual void Finish()
+    {
+        using namespace DPL::Colors::Html;
+        // Show result
+        FOREACH(group, m_groupsStats) {
+            PrintStats(group->first, group->second);
+        }
+        PrintStats("All tests together", m_stats);
+        fprintf(m_fp.Get(), "\n");
+        fprintf(m_fp.Get(), "
\n"); + fprintf(m_fp.Get(), "\n"); + fprintf(m_fp.Get(), "\n"); + } + + virtual bool ParseCollectorSpecificArg(const std::string& arg) + { + 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 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 TestResultsCollectorBase::GetCollectorsNames() +{ + std::vector list; + FOREACH(it, m_constructorsMap) + { + list.push_back(it->first); + } + return list; +} + +TestResultsCollectorBase::ConstructorsMap TestResultsCollectorBase::m_constructorsMap; + +namespace +{ +static int RegisterCollectorConstructors(); +static const int RegisterHelperVariable = RegisterCollectorConstructors(); +int RegisterCollectorConstructors() +{ + (void)RegisterHelperVariable; + + TestResultsCollectorBase::RegisterCollectorConstructor( + "text", + &ConsoleCollector::Constructor); + TestResultsCollectorBase::RegisterCollectorConstructor( + "html", + &HtmlCollector::Constructor); + TestResultsCollectorBase::RegisterCollectorConstructor( + "csv", + &CSVCollector::Constructor); + + return 0; +} + +} + +} +} diff --git a/modules/test/src/test_runner.cpp b/modules/test/src/test_runner.cpp new file mode 100644 index 0000000..8097c23 --- /dev/null +++ b/modules/test/src/test_runner.cpp @@ -0,0 +1,433 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_runner.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of test runner + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +IMPLEMENT_SINGLETON(DPL::Test::TestRunner) + +namespace DPL +{ +namespace Test +{ + +namespace // anonymous +{ + +std::string BaseName(std::string aPath) +{ + ScopedFree path(strdup(aPath.c_str())); + if (NULL == path.Get()) + { + throw std::bad_alloc(); + } + char* baseName = basename(path.Get()); + std::string retValue = baseName; + return retValue; +} + +} // namespace anonymous + +//! \brief Failed test message creator +//! +//! \param[in] aTest string for tested expression +//! \param[in] aFile source file name +//! \param[in] aLine source file line +//! \param[in] aMessage error message +TestRunner::TestFailed::TestFailed(const char* aTest, + const char* aFile, + int aLine, + const std::string &aMessage) +{ + std::ostringstream assertMsg; + assertMsg << "[" << BaseName(aFile) << ":" << aLine + << "] Assertion failed (" + << aTest << ") " << aMessage; + m_message = assertMsg.str(); +} + +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=\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=\tStart from concrete test id"); + fprintf(stderr, " --group=\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=\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, "\n"); +} + +int TestRunner::ExecTestRunner(int argc, char *argv[]) +{ + std::vector args; + for (int i = 0; i < argc; ++i) + { + args.push_back(argv[i]); + } + return ExecTestRunner(args); +} + +void TestRunner::MarkAssertion() +{ + ++m_totalAssertions; +} + +int TestRunner::ExecTestRunner(const ArgsList& value) +{ + 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 diff --git a/modules/utils/config.cmake b/modules/utils/config.cmake new file mode 100644 index 0000000..96efba7 --- /dev/null +++ b/modules/utils/config.cmake @@ -0,0 +1,50 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# @file 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 +) diff --git a/modules/utils/include/file_utils.h b/modules/utils/include/file_utils.h new file mode 100644 index 0000000..77e4aa3 --- /dev/null +++ b/modules/utils/include/file_utils.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file 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 +#include + +#include +#include + +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 diff --git a/modules/utils/include/folder_size.h b/modules/utils/include/folder_size.h new file mode 100644 index 0000000..db51de9 --- /dev/null +++ b/modules/utils/include/folder_size.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * + * @file folder_size.h + * @author Jaroslaw Osmanski (j.osmanski@samsung.com) + * @version 1.0 + * @brief Declaration for function calculating directory size + */ + +#ifndef SRC_COMMON_FOLDER_SIZE_H_ +#define SRC_COMMON_FOLDER_SIZE_H_ + +#include + +#include + +namespace Utils { + +size_t getFolderSize(const std::string& path); + +DPL::String fromFileSizeString(size_t fileSize); + +} + +#endif /* SRC_COMMON_FOLDER_SIZE_H_ */ diff --git a/modules/utils/include/mime_type_utils.h b/modules/utils/include/mime_type_utils.h new file mode 100644 index 0000000..b536c20 --- /dev/null +++ b/modules/utils/include/mime_type_utils.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MIME_TYPE_UTILS_H +#define MIME_TYPE_UTILS_H + +#include +#include + +class MimeTypeUtils +{ + public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, InvalidFileName) + }; + + private: + //TODO use hash_map if possible + static const std::set& getMimeTypesSupportedForIcon(); + static const std::set& getMimeTypesSupportedForStartFile(); + + typedef std::map FileIdentificationMap; + + static DPL::String getFileNameFromPath(const DPL::String& path); + static const FileIdentificationMap& getFileIdentificationMap(); + static DPL::String stripMimeParameters(const DPL::String& mimeType); + + public: + typedef std::map MimeAttributes; + static bool isValidIcon(const DPL::String& path); + static bool isValidStartFile(const DPL::String& path, + const DPL::OptionalString& providedMimeType); + static bool isMimeTypeSupportedForStartFile(const DPL::String& mimeType); + static bool isMimeTypeSupportedForIcon(const DPL::String& mimeType); + static MimeAttributes getMimeAttributes(const DPL::String& mimeType); + ///implements 9.1.10. (Rule for Identifying the Media Type of a File) + ///from W3C packaging specification + static DPL::String identifyFileMimeType(const DPL::String& path); +}; + +#endif /* MIME_TYPE_UTILS_H */ + diff --git a/modules/utils/include/warp_iri.h b/modules/utils/include/warp_iri.h new file mode 100644 index 0000000..901fd15 --- /dev/null +++ b/modules/utils/include/warp_iri.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _WARPIRI_H_ +#define _WARPIRI_H_ + +#include + +#include +#include + +class WarpIRI +{ + static const unsigned int UNKNOWN_PORT = 0; + public: + WarpIRI(); + + void set(const char *iri, + bool domain); + void set(const DPL::String &iristring, + bool domain); + + /* It also checks port and schema */ + bool isSubDomain(const WarpIRI &second) const; + bool isAccessDefinition() const; + // 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 m_host; + DPL::String m_schema; + unsigned int m_port; + bool m_isAccessDefinition; + bool m_isIRIValid; +}; + +#endif // _WarpIRI_H_ diff --git a/modules/utils/include/widget_version.h b/modules/utils/include/widget_version.h new file mode 100644 index 0000000..5f40e72 --- /dev/null +++ b/modules/utils/include/widget_version.h @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file widget_version.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief Header file for widget version + */ +#ifndef WIDGET_VERSION_H +#define WIDGET_VERSION_H + +#include +#include +#include + +/* + * Note: This class also support non-WAC compliant version numbers + * + * WAC Waikiki Beta Release Core Specification: Widget Runtime + * 10 Dec 2010 + * + * WL-3370 The WRT MUST process widget packages as an update when received under the following conditions: + * + * - the Widget Id matches the Widget Id of an installed widget + * - the Widget version number is greater (as a compared string) than that of the installed widget, or no version + * information was provided for the installed widget + * + * To ensure that a string comparison of widget versions can reliably determine which version is an updated widget, + * WAC will mandate a specific version string format for WAC widgets. All widgets coming through the WAC channel + * will be required to have version strings in this format. Side-loaded widgets may have any format and, in this + * case, there is no requirement that the WRT support version detection for update of these widgets. + * + * The widget version format is the rec-version-tag grammar as described in [Widget Packaging]: + * + * rec-version-tag = 1*DIGIT "." 1*DIGIT [ "." 1*DIGIT] *[ 1*ALPHA / SP / 1*DIGIT ] + * + * Examples of rec-version-tag: + * + * 1.0 + * 1.10.1 beta1 + * 1.02.12 RC1 + * + * WL-3371 The WRT MUST use the following widget version comparison algorithm to compare WAC widget version strings: + * + * - prepare the version strings for comparison: + * - all leading zeros are discarded + * - the optional *[ 1*ALPHA / SP / 1*DIGIT ] part, if present, is discarded + * - the resulting numbers are then in the format major.minor[.micro] + * - Version A = Amajor.Aminor[.Amicro] is equal to Version B = Bmajor.Bminor[.Bmicro] if and only if: + * - Amajor Bmajor + * - Aminor Bminor + * - both Amicro and Bmicro are present and Amicro == Bmicro; or both Amicro and Bmicro are absent. + * - Version A = Amajor.Aminor[.Amicro] is greater than Version B = Bmajor.Bminor[.Bmicro] if and only if: + * - Amajor > Bmajor; or + * - Amajor Bmajor && Aminor > Bminor; or + * - Amajor Bmajor && Aminor == Bminor && both Amicro and Bmicro are present and Amicro > Bmicro; or Bmicro is absent. + */ +class WidgetVersion +{ + private: + bool m_isWac; + DPL::String m_raw; + + DPL::String m_major; + DPL::String m_minor; + DPL::Optional m_micro; + DPL::Optional m_optional; + + void WacCertify(const DPL::String &major, + const DPL::String &minor, + const DPL::Optional µ, + const DPL::Optional &optional); + + public: + explicit WidgetVersion(const DPL::String &str = DPL::String()); + WidgetVersion(const DPL::String &major, + const DPL::String &minor, + const DPL::Optional µ, + const DPL::Optional &optional); + + bool IsWac() const; + const DPL::String &Raw() const; + + const DPL::String &Major() const; + const DPL::String &Minor() const; + const DPL::Optional &Micro() const; + const DPL::Optional &Optional() const; +}; + +bool operator<(const WidgetVersion &left, + const WidgetVersion &right); +bool operator<=(const WidgetVersion &left, + const WidgetVersion &right); +bool operator>(const WidgetVersion &left, + const WidgetVersion &right); +bool operator>=(const WidgetVersion &left, + const WidgetVersion &right); +bool operator==(const WidgetVersion &left, + const WidgetVersion &right); +bool operator!=(const WidgetVersion &left, + const WidgetVersion &right); +std::ostream & operator<<(std::ostream& stream, + const WidgetVersion& version); + +#endif // WIDGET_VERSION_H diff --git a/modules/utils/include/wrt_global_settings.h b/modules/utils/include/wrt_global_settings.h new file mode 100644 index 0000000..9a51cd1 --- /dev/null +++ b/modules/utils/include/wrt_global_settings.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file 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_ */ diff --git a/modules/utils/include/wrt_global_settings_internal.h b/modules/utils/include/wrt_global_settings_internal.h new file mode 100644 index 0000000..ac57956 --- /dev/null +++ b/modules/utils/include/wrt_global_settings_internal.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file 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_ diff --git a/modules/utils/include/wrt_utility.h b/modules/utils/include/wrt_utility.h new file mode 100644 index 0000000..30f8114 --- /dev/null +++ b/modules/utils/include/wrt_utility.h @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 + +#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_ + diff --git a/modules/utils/src/file_utils.cpp b/modules/utils/src/file_utils.cpp new file mode 100644 index 0000000..097fd4a --- /dev/null +++ b/modules/utils/src/file_utils.cpp @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file file_utils.cpp + * @author Bartosz Janiak (b.janiak@samsung.com) + * @version 1.0 + */ + + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +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()); + } +} +} diff --git a/modules/utils/src/folder_size.cpp b/modules/utils/src/folder_size.cpp new file mode 100644 index 0000000..87646f7 --- /dev/null +++ b/modules/utils/src/folder_size.cpp @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * + * @file folder_size.cpp + * @author Jaroslaw Osmanski (j.osmanski@samsung.com) + * @version 1.0 + * @brief Implementation for function calculating directory size + */ + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +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 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 +struct Pre; + +template +struct Pre +{ + static const double value = Pre::value * stepSize; + static std::string printSize(double fileSize) + { + if(fileSize >= Pre::value) { + double now = fileSize / Pre::value; + std::ostringstream outputStream; + outputStream.setf(std::ios::fixed, std::ios::floatfield); + outputStream.precision(2); + outputStream << now << Postfix::get(); + return outputStream.str(); + } else { + return Pre::printSize(fileSize); + } + + } +}; + +template<> +struct Pre<> +{ + static const double value; + static std::string printSize(double /*fileSize*/) + { + return "0B"; + } + +}; +const double Pre<>::value = 1.0; + +typedef Pre FolderSizeToStringType; +} //anonymous namespace + + +DPL::String fromFileSizeString(size_t fileSize) +{ + + std::string output = + FolderSizeToStringType::printSize(static_cast(fileSize)); + return DPL::FromUTF8String(output); +} + +} // end of namespace Utils diff --git a/modules/utils/src/mime_type_utils.cpp b/modules/utils/src/mime_type_utils.cpp new file mode 100644 index 0000000..988c1a3 --- /dev/null +++ b/modules/utils/src/mime_type_utils.cpp @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include + +#include + +#include + +const std::set& MimeTypeUtils::getMimeTypesSupportedForIcon() +{ + static std::set set; + DPL::String (*s)(const std::string&) = DPL::FromASCIIString; + if (set.empty()) { + set.insert(s("image/gif")); + set.insert(s("image/png")); + set.insert(s("image/vnd.microsoft.icon")); + set.insert(s("image/svg+xml")); + set.insert(s("image/jpeg")); + } + return set; +} + +const std::set& MimeTypeUtils::getMimeTypesSupportedForStartFile() +{ + static std::set set; + DPL::String (*s)(const std::string&) = DPL::FromASCIIString; + if (set.empty()) { + set.insert(s("text/html")); + set.insert(s("application/xhtml+xml")); + } + return set; +} + +bool MimeTypeUtils::isMimeTypeSupportedForStartFile(const DPL::String& mimeType) +{ + return getMimeTypesSupportedForStartFile().count(stripMimeParameters( + mimeType)) > 0; +} + +const MimeTypeUtils::FileIdentificationMap& MimeTypeUtils:: + getFileIdentificationMap() +{ + static FileIdentificationMap map; + DPL::String (*s)(const std::string&) = DPL::FromASCIIString; + if (map.empty()) { + map[s(".html")] = s("text/html"); + map[s(".htm")] = s("text/html"); + map[s(".css")] = s("text/css"); + map[s(".js")] = s("application/javascript"); + map[s(".xml")] = s("application/xml"); + map[s(".txt")] = s("text/plain"); + map[s(".wav")] = s("audio/x-wav"); + map[s(".xhtml")] = s("application/xhtml+xml"); + map[s(".xht")] = s("application/xhtml+xml"); + map[s(".gif")] = s("image/gif"); + map[s(".png")] = s("image/png"); + map[s(".ico")] = s("image/vnd.microsoft.icon"); + map[s(".svg")] = s("image/svg+xml"); + map[s(".jpg")] = s("image/jpeg"); + } + return map; +} + +bool MimeTypeUtils::isMimeTypeSupportedForIcon(const DPL::String& mimeType) +{ + return getMimeTypesSupportedForIcon().count(stripMimeParameters(mimeType)) + > 0; +} + +DPL::String MimeTypeUtils::stripMimeParameters(const DPL::String& mimeType) +{ + size_t parametersStart = mimeType.find_first_of(L';'); + if (parametersStart != DPL::String::npos) { + return mimeType.substr(0, parametersStart); + } else { + return mimeType; + } +} + +MimeTypeUtils::MimeAttributes MimeTypeUtils::getMimeAttributes( + const DPL::String& mimeType) +{ + MimeAttributes attributes; + std::vector tokens; + DPL::Tokenize(mimeType, L";=", std::back_inserter(tokens)); + for (unsigned int i = 1; i < tokens.size(); i += 2) { + attributes[tokens[i]] = tokens[i + 1]; + } + return attributes; +} + +bool MimeTypeUtils::isValidIcon(const DPL::String& path) +{ + return getMimeTypesSupportedForIcon().count(identifyFileMimeType(path)) > 0; +} + +bool MimeTypeUtils::isValidStartFile(const DPL::String& path, + const DPL::OptionalString& providedMimeType) +{ + DPL::String mimeType = (!!providedMimeType) ? stripMimeParameters( + *providedMimeType) : identifyFileMimeType(path); + return getMimeTypesSupportedForStartFile().count(mimeType) > 0; +} + +DPL::String MimeTypeUtils::getFileNameFromPath(const DPL::String& path) +{ + size_t lastSlashPos = path.find_last_of(L'/'); + return path.substr(lastSlashPos + 1); +} + +DPL::String MimeTypeUtils::identifyFileMimeType(const DPL::String& path) +{ + DPL::String name = getFileNameFromPath(path); //step 4 + + if (name.size() == 0) { + ThrowMsg(Exception::InvalidFileName, "Path should contain a file name."); + } + + size_t lastFullStop = name.find_last_of(L'.'); + if (lastFullStop != 0 && lastFullStop != DPL::String::npos) { //step 5 + DPL::String extension = name.substr(lastFullStop); //step 6 & 7 + if (extension.size() > 0) { //step 8 + //step 9 + std::transform(extension.begin(), extension.end(), + extension.begin(), ::towlower); + FileIdentificationMap::const_iterator it = + getFileIdentificationMap().find(extension); + if (it != getFileIdentificationMap().end()) { + return it->second; + } + } + } + //TODO step 10 - sniff + return DPL::FromASCIIString("application/sniff"); +} diff --git a/modules/utils/src/warp_iri.cpp b/modules/utils/src/warp_iri.cpp new file mode 100644 index 0000000..a296ea5 --- /dev/null +++ b/modules/utils/src/warp_iri.cpp @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * This file have been implemented in compliance with W3C WARP SPEC. + * but there are some patent issue between W3C WARP SPEC and APPLE. + * so if you want to use this file, refer to the README file in root directory + */ + +#include +#include +#include +#include +#include +#include +#include + +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(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(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 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; +} diff --git a/modules/utils/src/widget_version.cpp b/modules/utils/src/widget_version.cpp new file mode 100644 index 0000000..0bf91c1 --- /dev/null +++ b/modules/utils/src/widget_version.cpp @@ -0,0 +1,371 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file widget_version.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief Implementation file for widget version + */ +#include +#include +#include +#include +#include + +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(left.size()) - 1; i >= 0; --i) { + if (left[i] < right[i]) { + return true; + } + + if (left[i] > right[i]) { + return false; + } + } + + // Equal + return false; +} + +bool WacCertifyNumberString(const DPL::String &str) +{ + for (DPL::String::const_iterator i = str.begin(); i != str.end(); ++i) { + if (!IsDigit(*i)) { + return false; + } + } + + return true; +} + +bool WacCertifyAlphaNumberStringSpace(const DPL::String &str) +{ + for (DPL::String::const_iterator i = str.begin(); i != str.end(); ++i) { + if (!IsDigit(*i) && !IsAlpha(*i) && !IsSp(*i)) { + return false; + } + } + + return true; +} +} // anonymous + +WidgetVersion::WidgetVersion(const DPL::String &str) : + m_isWac(false), + m_raw(str) +{ + LogDebug("Parsing version string: " << str); + + // Split optional an mandatory parts + size_t optionalPartPosition = str.find( + WAC_CERTIFY_MANDATORY_VS_OPTIONAL_SPLIT_CHAR); + + DPL::String mandatoryPart; + DPL::Optional optionalPart; + + if (optionalPartPosition == DPL::String::npos) { + mandatoryPart = str; + } else { + mandatoryPart = str.substr(0, optionalPartPosition); + optionalPart = str.substr(optionalPartPosition + 1, DPL::String::npos); + } + + LogDebug("Mandatory part is: " << mandatoryPart); + LogDebug("Optional part is: " << optionalPart); + + // Split string and construct version + std::vector parts; + DPL::Tokenize(mandatoryPart, + WAC_CERTIFY_MANDATORY_NUMBER_PART_SPLIT_CHAR, + std::back_inserter(parts), + false); + + LogDebug("Tokenized mandatory parts: " << parts.size()); + + if (parts.size() != WAC_CERTIFY_MANDATORY_PART_LOW_COUNT && + parts.size() != WAC_CERTIFY_MANDATORY_PART_HIGH_COUNT) { + return; + } + + DPL::String major; + DPL::String minor; + DPL::Optional micro; + + // Certify for Wac + major = parts[WAC_CERTIFY_MANDATORY_PART_MAJOR_INDEX]; + minor = parts[WAC_CERTIFY_MANDATORY_PART_MINOR_INDEX]; + + if (parts.size() == WAC_CERTIFY_MANDATORY_PART_HIGH_COUNT) { + micro = parts[WAC_CERTIFY_MANDATORY_PART_MICRO_INDEX]; + } + + WacCertify(major, minor, micro, optionalPart); +} + +WidgetVersion::WidgetVersion(const DPL::String &major, + const DPL::String &minor, + const DPL::Optional µ, + const DPL::Optional &optional) : + m_isWac(false) +{ + // Create Raw version + m_raw += major; + m_raw += WAC_CERTIFY_MANDATORY_NUMBER_PART_SPLIT_CHAR; + m_raw += minor; + 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 µ, + const DPL::Optional &optional) +{ + LogDebug("Certyfing..."); + + LogDebug("Major candidate: " << major); + LogDebug("Minor candidate: " << minor); + LogDebug("Micro candidate: " << micro); + LogDebug("Optional candidate: " << optional); + + // Check strings + if (major.empty() || !WacCertifyNumberString(major)) { + LogDebug("Major version not certified!"); + return; + } + + if (minor.empty() || !WacCertifyNumberString(minor)) { + LogDebug("Minor version not certified!"); + return; + } + + if (!!micro && (micro->empty() || !WacCertifyNumberString(*micro))) { + LogDebug("Microversion not certified!"); + return; + } + + if (!!optional && + (optional->empty() || !WacCertifyAlphaNumberStringSpace(*optional))) { + LogDebug("Optional version not certified!"); + return; + } + + // OK + m_major = major; + m_minor = minor; + m_micro = micro; + m_optional = optional; + + m_isWac = true; + + LogDebug("Certified."); +} + +bool WidgetVersion::IsWac() const +{ + return m_isWac; +} + +const DPL::String &WidgetVersion::Raw() const +{ + return m_raw; +} + +const DPL::String &WidgetVersion::Major() const +{ + return m_major; +} + +const DPL::String &WidgetVersion::Minor() const +{ + return m_minor; +} + +const DPL::Optional &WidgetVersion::Micro() const +{ + return m_micro; +} + +const DPL::Optional &WidgetVersion::Optional() const +{ + return m_optional; +} + +bool operator<(const WidgetVersion &left, + const WidgetVersion &right) +{ + 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; +} diff --git a/modules/utils/src/wrt_global_settings.cpp b/modules/utils/src/wrt_global_settings.cpp new file mode 100644 index 0000000..8695e8a --- /dev/null +++ b/modules/utils/src/wrt_global_settings.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file wrt_global_settings.cpp + * @version 1.0 + * @author Pawel Sikorski(p.sikorski@samsung.com) + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @brief runtime + */ +#include +#include +#include +#include +#include + +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; +} +} diff --git a/modules/utils/src/wrt_global_settings_internal.cpp b/modules/utils/src/wrt_global_settings_internal.cpp new file mode 100644 index 0000000..7940cd1 --- /dev/null +++ b/modules/utils/src/wrt_global_settings_internal.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file wrt_global_settings_internal.cpp + * @version 0.6 + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + */ + +#include +#include +#include +#include + +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 diff --git a/modules/utils/src/wrt_utility.cpp b/modules/utils/src/wrt_utility.cpp new file mode 100644 index 0000000..f7ecd7d --- /dev/null +++ b/modules/utils/src/wrt_utility.cpp @@ -0,0 +1,362 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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; +} + diff --git a/modules/vcore/CMakeLists.txt b/modules/vcore/CMakeLists.txt new file mode 100644 index 0000000..8c492f4 --- /dev/null +++ b/modules/vcore/CMakeLists.txt @@ -0,0 +1,30 @@ +#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) diff --git a/modules/vcore/src/CMakeLists.txt b/modules/vcore/src/CMakeLists.txt new file mode 100644 index 0000000..5d56cda --- /dev/null +++ b/modules/vcore/src/CMakeLists.txt @@ -0,0 +1,132 @@ +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 + ) + diff --git a/modules/vcore/src/orm/DESCRIPTION b/modules/vcore/src/orm/DESCRIPTION new file mode 100644 index 0000000..7d25d0d --- /dev/null +++ b/modules/vcore/src/orm/DESCRIPTION @@ -0,0 +1 @@ +Scripts required to create vcoredatabase. diff --git a/modules/vcore/src/orm/gen_db_md5.sh b/modules/vcore/src/orm/gen_db_md5.sh new file mode 100755 index 0000000..a81d5f7 --- /dev/null +++ b/modules/vcore/src/orm/gen_db_md5.sh @@ -0,0 +1,5 @@ +#!/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} + diff --git a/modules/vcore/src/orm/orm_generator_vcore.h b/modules/vcore/src/orm/orm_generator_vcore.h new file mode 100644 index 0000000..862bc80 --- /dev/null +++ b/modules/vcore/src/orm/orm_generator_vcore.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ORM_GENERATOR_VCORE_H +#define ORM_GENERATOR_VCORE_H + +#define ORM_GENERATOR_DATABASE_NAME vcore_db_definitions +#include +#undef ORM_GENERATOR_DATABASE_NAME + +#endif // ORM_GENERATOR_VCORE_H diff --git a/modules/vcore/src/orm/vcore_db b/modules/vcore/src/orm/vcore_db new file mode 100644 index 0000000..71080da --- /dev/null +++ b/modules/vcore/src/orm/vcore_db @@ -0,0 +1,20 @@ +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; +) diff --git a/modules/vcore/src/orm/vcore_db_definitions b/modules/vcore/src/orm/vcore_db_definitions new file mode 100644 index 0000000..61018c4 --- /dev/null +++ b/modules/vcore/src/orm/vcore_db_definitions @@ -0,0 +1,6 @@ +DATABASE_START(vcore) + +#include "vcore_db" +#include "version_db" + +DATABASE_END() diff --git a/modules/vcore/src/orm/vcore_db_sql_generator.h b/modules/vcore/src/orm/vcore_db_sql_generator.h new file mode 100644 index 0000000..76f0448 --- /dev/null +++ b/modules/vcore/src/orm/vcore_db_sql_generator.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//Do not include this file directly! It is used only for SQL code generation. + +#include + +#include "vcore_db_definitions" diff --git a/modules/vcore/src/orm/version_db b/modules/vcore/src/orm/version_db new file mode 100644 index 0000000..7e20d8d --- /dev/null +++ b/modules/vcore/src/orm/version_db @@ -0,0 +1,5 @@ +SQL( + BEGIN TRANSACTION; + CREATE TABLE DB_CHECKSUM (version INT); + COMMIT; +) diff --git a/modules/vcore/src/vcore/Base64.cpp b/modules/vcore/src/vcore/Base64.cpp new file mode 100644 index 0000000..b772178 --- /dev/null +++ b/modules/vcore/src/vcore/Base64.cpp @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "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 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 diff --git a/modules/vcore/src/vcore/Base64.h b/modules/vcore/src/vcore/Base64.h new file mode 100644 index 0000000..520662e --- /dev/null +++ b/modules/vcore/src/vcore/Base64.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _BASE64_H_ +#define _BASE64_H_ + +#include +#include +#include + +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 diff --git a/modules/vcore/src/vcore/CRL.cpp b/modules/vcore/src/vcore/CRL.cpp new file mode 100644 index 0000000..98643df --- /dev/null +++ b/modules/vcore/src/vcore/CRL.cpp @@ -0,0 +1,500 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#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(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(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 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 diff --git a/modules/vcore/src/vcore/CRL.h b/modules/vcore/src/vcore/CRL.h new file mode 100644 index 0000000..9ba64bb --- /dev/null +++ b/modules/vcore/src/vcore/CRL.h @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*! + * @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 +#include +#include +#include + +#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 CRLDataPtr; + typedef std::list 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_ diff --git a/modules/vcore/src/vcore/CachedCRL.cpp b/modules/vcore/src/vcore/CachedCRL.cpp new file mode 100644 index 0000000..08448bf --- /dev/null +++ b/modules/vcore/src/vcore/CachedCRL.cpp @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 +#include + +#include +#include +#include + +#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 diff --git a/modules/vcore/src/vcore/CachedCRL.h b/modules/vcore/src/vcore/CachedCRL.h new file mode 100644 index 0000000..65e6509 --- /dev/null +++ b/modules/vcore/src/vcore/CachedCRL.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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_ */ diff --git a/modules/vcore/src/vcore/CachedOCSP.cpp b/modules/vcore/src/vcore/CachedOCSP.cpp new file mode 100644 index 0000000..21a8122 --- /dev/null +++ b/modules/vcore/src/vcore/CachedOCSP.cpp @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 +#include + +#include +#include +#include + +#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 diff --git a/modules/vcore/src/vcore/CachedOCSP.h b/modules/vcore/src/vcore/CachedOCSP.h new file mode 100644 index 0000000..517e49f --- /dev/null +++ b/modules/vcore/src/vcore/CachedOCSP.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * + * @file 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_ */ diff --git a/modules/vcore/src/vcore/CertStoreType.h b/modules/vcore/src/vcore/CertStoreType.h new file mode 100644 index 0000000..7cf6232 --- /dev/null +++ b/modules/vcore/src/vcore/CertStoreType.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file + * @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(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_ diff --git a/modules/vcore/src/vcore/Certificate.cpp b/modules/vcore/src/vcore/Certificate.cpp new file mode 100644 index 0000000..9ec2868 --- /dev/null +++ b/modules/vcore/src/vcore/Certificate.cpp @@ -0,0 +1,493 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 + +#include +#include + +#include + +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(tmp.c_str()); + size = static_cast(tmp.size()); + } else { + ptr = reinterpret_cast(der.c_str()); + size = static_cast(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(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( + 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(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( + 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(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( + 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(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 +Certificate::getCrlUris() const +{ + std::list result; + + STACK_OF(DIST_POINT)* distPoints = + static_cast( + 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(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 diff --git a/modules/vcore/src/vcore/Certificate.h b/modules/vcore/src/vcore/Certificate.h new file mode 100644 index 0000000..de7636d --- /dev/null +++ b/modules/vcore/src/vcore/Certificate.h @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +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 CertificatePtr; +typedef std::list CertificateList; + +class Certificate : public DPL::EnableSharedFromThis +{ + public: + typedef std::vector Fingerprint; + typedef DPL::String AltName; + typedef std::set 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 getCrlUris() const; + + protected: + DPL::OptionalString getField(FieldType type, + int fieldNid) const; + + X509 *m_x509; +}; +} // namespace ValidationCore + +#endif diff --git a/modules/vcore/src/vcore/CertificateCacheDAO.cpp b/modules/vcore/src/vcore/CertificateCacheDAO.cpp new file mode 100644 index 0000000..04956a3 --- /dev/null +++ b/modules/vcore/src/vcore/CertificateCacheDAO.cpp @@ -0,0 +1,275 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * + * + * @file CertificateCacheDAO.cpp + * @author Tomasz Swierczek (t.swierczek@samsung.com) + * @version 0.1 + * @brief CertificateCacheDAO implementation + */ + +#include "CertificateCacheDAO.h" +#include "VCorePrivate.h" + +#include +#include +#include +#include +#include + +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 e1( + DPL::FromUTF8String(cert_chain)); + Equals 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 e1( + DPL::FromUTF8String(cached_status->cert_chain)); + Equals e2( + cached_status->end_entity_check ? 1 : 0); + + VCORE_DB_SELECT(select, OCSPResponseStorage, &ThreadInterface()) + + select->Where(And(e1,e2)); + std::list 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 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 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 e1( + DPL::FromUTF8String(cached_data->distribution_point)); + + select->Where(e1); + std::list 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 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 diff --git a/modules/vcore/src/vcore/CertificateCacheDAO.h b/modules/vcore/src/vcore/CertificateCacheDAO.h new file mode 100644 index 0000000..ba26091 --- /dev/null +++ b/modules/vcore/src/vcore/CertificateCacheDAO.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 +#include + +#include + +#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 OCSPCachedStatusList; + +struct CRLCachedData +{ + std::string distribution_point; + std::string crl_body; + time_t next_update_time; +}; + +typedef std::list 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_ */ diff --git a/modules/vcore/src/vcore/CertificateCollection.cpp b/modules/vcore/src/vcore/CertificateCollection.cpp new file mode 100644 index 0000000..988c510 --- /dev/null +++ b/modules/vcore/src/vcore/CertificateCollection.cpp @@ -0,0 +1,266 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include + +#include + +#include +#include +#include + +#include + +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 +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 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 + diff --git a/modules/vcore/src/vcore/CertificateCollection.h b/modules/vcore/src/vcore/CertificateCollection.h new file mode 100644 index 0000000..67b9ce9 --- /dev/null +++ b/modules/vcore/src/vcore/CertificateCollection.h @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _WRT_ENGINE_SRC_VALIDATION_CORE_CERTIFICATECOLLECTION_H_ +#define _WRT_ENGINE_SRC_VALIDATION_CORE_CERTIFICATECOLLECTION_H_ + +#include +#include + +#include + +#include + +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 CertificateCollectionList; +} // namespace ValidationCore + +#endif // _WRT_ENGINE_SRC_VALIDATION_CORE_CERTIFICATECHAIN_H_ diff --git a/modules/vcore/src/vcore/CertificateConfigReader.cpp b/modules/vcore/src/vcore/CertificateConfigReader.cpp new file mode 100644 index 0000000..2a61940 --- /dev/null +++ b/modules/vcore/src/vcore/CertificateConfigReader.cpp @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file + * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) + * @version 1.0 + * @brief + */ +#include "CertificateConfigReader.h" + +#include + +#include + +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(c) - 'a'; + } + if (c >= 'A' && c <= 'F') { + return 10 + static_cast(c) - 'A'; + } + if (c >= '0' && c <= '9') { + return static_cast(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(s)); + s = 0; + byteDescLen = 0; + } else { + Assert(0 && "Unussported fingerprint format in xml file."); + } + } + identificator.add(fingerprint, m_certificateDomain); +} +} // namespace ValidationCore diff --git a/modules/vcore/src/vcore/CertificateConfigReader.h b/modules/vcore/src/vcore/CertificateConfigReader.h new file mode 100644 index 0000000..92e000e --- /dev/null +++ b/modules/vcore/src/vcore/CertificateConfigReader.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file + * @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 +#include + +#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 + m_parserSchema; +}; +} // namespace ValidationCore + +#endif // _WRT_ENGINE_SRC_INSTALLER_CORE_VALIDATION_CORE_CERTIFICATE_CONFIG_READER_H_ diff --git a/modules/vcore/src/vcore/CertificateIdentifier.h b/modules/vcore/src/vcore/CertificateIdentifier.h new file mode 100644 index 0000000..f9ed48c --- /dev/null +++ b/modules/vcore/src/vcore/CertificateIdentifier.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file + * @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 + +#include + +#include "Certificate.h" +#include "CertStoreType.h" + +namespace ValidationCore { +class CertificateIdentifier : public DPL::Noncopyable +{ + public: + typedef std::map 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_ diff --git a/modules/vcore/src/vcore/CertificateLoader.cpp b/modules/vcore/src/vcore/CertificateLoader.cpp new file mode 100644 index 0000000..3bc50de --- /dev/null +++ b/modules/vcore/src/vcore/CertificateLoader.cpp @@ -0,0 +1,725 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include +#include +#include + +#include "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(static_cast(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 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 (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 + diff --git a/modules/vcore/src/vcore/CertificateLoader.h b/modules/vcore/src/vcore/CertificateLoader.h new file mode 100644 index 0000000..64c38ac --- /dev/null +++ b/modules/vcore/src/vcore/CertificateLoader.h @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _CERTIFICATELOADER_H_ +#define _CERTIFICATELOADER_H_ + +#include +#include + +#include +#include + +#include + +#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_ diff --git a/modules/vcore/src/vcore/CertificateStorage.h b/modules/vcore/src/vcore/CertificateStorage.h new file mode 100644 index 0000000..7fbcb6b --- /dev/null +++ b/modules/vcore/src/vcore/CertificateStorage.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef VCORE_SRC_VCORE_CERTIFICATESTORAGE_H +#define VCORE_SRC_VCORE_CERTIFICATESTORAGE_H + +#include +#include + +namespace ValidationCore { +typedef std::list < X509* > X509CertificatesList; +} + +#endif // VCORE_SRC_VCORE_CERTIFICATESTORAGE_H diff --git a/modules/vcore/src/vcore/CertificateVerifier.cpp b/modules/vcore/src/vcore/CertificateVerifier.cpp new file mode 100644 index 0000000..f05662a --- /dev/null +++ b/modules/vcore/src/vcore/CertificateVerifier.cpp @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 +#include +#include + +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 diff --git a/modules/vcore/src/vcore/CertificateVerifier.h b/modules/vcore/src/vcore/CertificateVerifier.h new file mode 100644 index 0000000..ea77812 --- /dev/null +++ b/modules/vcore/src/vcore/CertificateVerifier.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*! + * @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_ + diff --git a/modules/vcore/src/vcore/Config.cpp b/modules/vcore/src/vcore/Config.cpp new file mode 100644 index 0000000..7dfaedf --- /dev/null +++ b/modules/vcore/src/vcore/Config.cpp @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 +IMPLEMENT_SINGLETON(ValidationCore::Config) diff --git a/modules/vcore/src/vcore/Config.h b/modules/vcore/src/vcore/Config.h new file mode 100644 index 0000000..0783cd1 --- /dev/null +++ b/modules/vcore/src/vcore/Config.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _SRC_VALIDATION_CORE_VALIDATION_CORE_CONFIG_H_ +#define _SRC_VALIDATION_CORE_VALIDATION_CORE_CONFIG_H_ + +#include + +#include + +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 ConfigSingleton; + +} // namespace ValidationCore + +#endif // _SRC_VALIDATION_CORE_VALIDATION_CORE_CONFIG_H_ + diff --git a/modules/vcore/src/vcore/Database.cpp b/modules/vcore/src/vcore/Database.cpp new file mode 100644 index 0000000..6d363af --- /dev/null +++ b/modules/vcore/src/vcore/Database.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 +#include +#include + +#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; diff --git a/modules/vcore/src/vcore/Database.h b/modules/vcore/src/vcore/Database.h new file mode 100644 index 0000000..7c30bc1 --- /dev/null +++ b/modules/vcore/src/vcore/Database.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 +#include +#include +#include + +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 *tlsCommand ## Ptr = NULL; \ + { \ + DPL::Mutex::ScopedLock lock(&g_vcoreDbQueriesMutex); \ + if (!tlsCommand ## Ptr) { \ + static DPL::ThreadLocalVariable tmp; \ + tlsCommand ## Ptr = &tmp; \ + } \ + } \ + DPL::ThreadLocalVariable &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 diff --git a/modules/vcore/src/vcore/DeveloperModeValidator.cpp b/modules/vcore/src/vcore/DeveloperModeValidator.cpp new file mode 100644 index 0000000..7c30d49 --- /dev/null +++ b/modules/vcore/src/vcore/DeveloperModeValidator.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 +#include +#include +#include +#include + +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 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(phoneInfo.szNumber); + } + + LogDebug("Phone MEID: " << phoneMEIDString); + if (MEIDList.end() == + std::find(MEIDList.begin(), MEIDList.end(), phoneMEIDString)) + { + Throw(Exception::NoTargetRestrictionSatisfied); + } + } + LogDebug("exit: ok"); +} + +} //ValidationCore diff --git a/modules/vcore/src/vcore/DeveloperModeValidator.h b/modules/vcore/src/vcore/DeveloperModeValidator.h new file mode 100644 index 0000000..a99076c --- /dev/null +++ b/modules/vcore/src/vcore/DeveloperModeValidator.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 +#include +#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 */ + diff --git a/modules/vcore/src/vcore/IAbstractResponseCache.h b/modules/vcore/src/vcore/IAbstractResponseCache.h new file mode 100644 index 0000000..38a6fa8 --- /dev/null +++ b/modules/vcore/src/vcore/IAbstractResponseCache.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * + * + * @file 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_ */ diff --git a/modules/vcore/src/vcore/OCSP.cpp b/modules/vcore/src/vcore/OCSP.cpp new file mode 100644 index 0000000..d276b87 --- /dev/null +++ b/modules/vcore/src/vcore/OCSP.cpp @@ -0,0 +1,538 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#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(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 certIdCont(certId); + // this smart ptr is commented out in purpose. request + // manages certIdmemory (which was done in createRequest above) + SSLSmartContainer 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 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 requestCont(newRequest); + + OCSP_CERTID* certId = addSerial(argCert, argIssuer); + + if (!certId) { + LogWarning("OCSP: Unable to create a serial id"); + return CreateRequestResult(); + } + SSLSmartContainer 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 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(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 diff --git a/modules/vcore/src/vcore/OCSP.h b/modules/vcore/src/vcore/OCSP.h new file mode 100644 index 0000000..5f60da0 --- /dev/null +++ b/modules/vcore/src/vcore/OCSP.h @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#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 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 ScopedSoupSession; + typedef WRT::ScopedGPointer 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 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 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 m_pTrustedStore; + SoupWrapper::SoupMessageSendSync m_soupMessage; +}; +} // ValidationCore + +#endif //ifndef WRT_ENGINE_SRC_VALIDATION_CORE_ENGINE_OCSP_H_ diff --git a/modules/vcore/src/vcore/OCSPCertMgrUtil.cpp b/modules/vcore/src/vcore/OCSPCertMgrUtil.cpp new file mode 100644 index 0000000..794ecfa --- /dev/null +++ b/modules/vcore/src/vcore/OCSPCertMgrUtil.cpp @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 +#include +#include +#include +#include +#include +#include + +#include + +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 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 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 diff --git a/modules/vcore/src/vcore/OCSPCertMgrUtil.h b/modules/vcore/src/vcore/OCSPCertMgrUtil.h new file mode 100644 index 0000000..a93a42e --- /dev/null +++ b/modules/vcore/src/vcore/OCSPCertMgrUtil.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @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 + +#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 + diff --git a/modules/vcore/src/vcore/OCSPUtil.c b/modules/vcore/src/vcore/OCSPUtil.c new file mode 100644 index 0000000..451884a --- /dev/null +++ b/modules/vcore/src/vcore/OCSPUtil.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @author Tomasz Morawski(t.morawski@samsung.com) + * @version 0.1 + * @brief + */ + +#include + +/* + * 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; +} diff --git a/modules/vcore/src/vcore/ParserSchema.h b/modules/vcore/src/vcore/ParserSchema.h new file mode 100644 index 0000000..6fabff8 --- /dev/null +++ b/modules/vcore/src/vcore/ParserSchema.h @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file ParserSchema.h + * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) + * @version 1.0 + * @brief + */ +#ifndef _PARSERSCHEMA_H_ +#define _PARSERSCHEMA_H_ + +#include +#include + +#include + +#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 +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 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 diff --git a/modules/vcore/src/vcore/ReferenceValidator.cpp b/modules/vcore/src/vcore/ReferenceValidator.cpp new file mode 100644 index 0000000..d56eea8 --- /dev/null +++ b/modules/vcore/src/vcore/ReferenceValidator.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include + +#include +#include + +#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; +} +} diff --git a/modules/vcore/src/vcore/ReferenceValidator.h b/modules/vcore/src/vcore/ReferenceValidator.h new file mode 100644 index 0000000..5f05095 --- /dev/null +++ b/modules/vcore/src/vcore/ReferenceValidator.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _REFERENCEVALIDATOR_H_ +#define _REFERENCEVALIDATOR_H_ + +#include + +#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_ diff --git a/modules/vcore/src/vcore/RevocationCheckerBase.cpp b/modules/vcore/src/vcore/RevocationCheckerBase.cpp new file mode 100644 index 0000000..f0e43e7 --- /dev/null +++ b/modules/vcore/src/vcore/RevocationCheckerBase.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*! + * @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 + +#include + +#include + +#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 diff --git a/modules/vcore/src/vcore/RevocationCheckerBase.h b/modules/vcore/src/vcore/RevocationCheckerBase.h new file mode 100644 index 0000000..3ce934d --- /dev/null +++ b/modules/vcore/src/vcore/RevocationCheckerBase.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*! + * @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 + +#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_ + diff --git a/modules/vcore/src/vcore/SSLContainers.h b/modules/vcore/src/vcore/SSLContainers.h new file mode 100644 index 0000000..e18cb00 --- /dev/null +++ b/modules/vcore/src/vcore/SSLContainers.h @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 +#include + +/* + * default deleter functor with no overloaded operator() + */ +template +struct MySSLFree {}; + +/* + * macro for defining custom deleters for openssl structs + * usage DECLARE_DELETER(OpenSSLType) + */ +#define DECLARE_DELETER(Type) template<> \ + struct MySSLFree \ + { \ + 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 smartptr = ptrToOpenSSLType + * remember to add OpenSSLType to macro list few lines above + */ +template > +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 + T & operator = (S& pContainer) + { + return *this; + } + + /* + * internal data + */ + T* m_pData; +}; + +#endif /* _SSLCONTAINERS_H */ + diff --git a/modules/vcore/src/vcore/SaxReader.cpp b/modules/vcore/src/vcore/SaxReader.cpp new file mode 100644 index 0000000..5bef911 --- /dev/null +++ b/modules/vcore/src/vcore/SaxReader.cpp @@ -0,0 +1,308 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 +#include +#include + +#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(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(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(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(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(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(text); + /* + * free text and return the val + */ + xmlFree(text); + return value; +} + +SaxReader::NodeType SaxReader::type() +{ + xmlReaderTypes type = + static_cast(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(buff->content), size); + xmlBufferFree(buff); +} +} // namespace ValidationCore diff --git a/modules/vcore/src/vcore/SaxReader.h b/modules/vcore/src/vcore/SaxReader.h new file mode 100644 index 0000000..816405f --- /dev/null +++ b/modules/vcore/src/vcore/SaxReader.h @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 +#include +#include + +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_ diff --git a/modules/vcore/src/vcore/SignatureData.h b/modules/vcore/src/vcore/SignatureData.h new file mode 100644 index 0000000..c0b7aad --- /dev/null +++ b/modules/vcore/src/vcore/SignatureData.h @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 +#include +#include + +#include +#include +#include + +#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 IMEIList; + typedef std::list 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 SignatureDataSet; +} + +#endif diff --git a/modules/vcore/src/vcore/SignatureFinder.cpp b/modules/vcore/src/vcore/SignatureFinder.cpp new file mode 100644 index 0000000..ed2a27f --- /dev/null +++ b/modules/vcore/src/vcore/SignatureFinder.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 +#include +#include + +#include + +#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 diff --git a/modules/vcore/src/vcore/SignatureFinder.h b/modules/vcore/src/vcore/SignatureFinder.h new file mode 100644 index 0000000..0e04213 --- /dev/null +++ b/modules/vcore/src/vcore/SignatureFinder.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 +#include + +#include + +#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 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 diff --git a/modules/vcore/src/vcore/SignatureReader.cpp b/modules/vcore/src/vcore/SignatureReader.cpp new file mode 100644 index 0000000..cf7540c --- /dev/null +++ b/modules/vcore/src/vcore/SignatureReader.cpp @@ -0,0 +1,582 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 diff --git a/modules/vcore/src/vcore/SignatureReader.h b/modules/vcore/src/vcore/SignatureReader.h new file mode 100644 index 0000000..e6368fc --- /dev/null +++ b/modules/vcore/src/vcore/SignatureReader.h @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 +#include + +#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 m_parserSchema; +}; +} + +#endif diff --git a/modules/vcore/src/vcore/SignatureValidator.cpp b/modules/vcore/src/vcore/SignatureValidator.cpp new file mode 100644 index 0000000..e965ecc --- /dev/null +++ b/modules/vcore/src/vcore/SignatureValidator.cpp @@ -0,0 +1,265 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include + +#include + +#include "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(fingerprint[i])); + outString += buff; + } + + // remove trailing ":" + outString.erase(outString.end() - 1); + return outString; +} +} // namespace ValidationCore diff --git a/modules/vcore/src/vcore/SignatureValidator.h b/modules/vcore/src/vcore/SignatureValidator.h new file mode 100644 index 0000000..aa381cb --- /dev/null +++ b/modules/vcore/src/vcore/SignatureValidator.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _SIGNATUREVALIDATOR_H_ +#define _SIGNATUREVALIDATOR_H_ + +#include + +#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_ diff --git a/modules/vcore/src/vcore/SoupMessageSendAsync.cpp b/modules/vcore/src/vcore/SoupMessageSendAsync.cpp new file mode 100644 index 0000000..d8bb132 --- /dev/null +++ b/modules/vcore/src/vcore/SoupMessageSendAsync.cpp @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ diff --git a/modules/vcore/src/vcore/SoupMessageSendAsync.h b/modules/vcore/src/vcore/SoupMessageSendAsync.h new file mode 100644 index 0000000..c6900e2 --- /dev/null +++ b/modules/vcore/src/vcore/SoupMessageSendAsync.h @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 +#include + +#include + +#include + +#include "SoupMessageSendBase.h" + +namespace SoupWrapper { + +class SoupMessageSendAsync + : public SoupMessageSendBase + , public DPL::Event::ICDelegateSupport +{ + typedef DPL::Event::ICDelegate 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(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(opaque); + + // call the delegate to outside! + return; + } + + // Error protocol // + if (m_tryLeft <= 0) { + m_status = STATUS_IDLE; + delete static_cast(opaque); + + // call the delegate to outside with error! + return; + } + + // create delegate and send the request once again. + sendAsyncIteration(reinterpret_cast(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(userdata); + opaque->dlg(session, msg, userdata); + } + + int m_tryLeft; + + GMainContext *m_mainContext; + SoupSession *m_soupSession; + SoupMessage *m_soupMessage; +}; + +} // namespace ValidationCore + +#endif diff --git a/modules/vcore/src/vcore/SoupMessageSendBase.cpp b/modules/vcore/src/vcore/SoupMessageSendBase.cpp new file mode 100644 index 0000000..4d1fafa --- /dev/null +++ b/modules/vcore/src/vcore/SoupMessageSendBase.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 +#include +#include + +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 diff --git a/modules/vcore/src/vcore/SoupMessageSendBase.h b/modules/vcore/src/vcore/SoupMessageSendBase.h new file mode 100644 index 0000000..aaa5fb4 --- /dev/null +++ b/modules/vcore/src/vcore/SoupMessageSendBase.h @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*! + * @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 +#include +#include + +#include + +namespace SoupWrapper { + +class SoupMessageSendBase { + public: + + typedef std::vector MessageBuffer; + typedef std::map 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 diff --git a/modules/vcore/src/vcore/SoupMessageSendSync.cpp b/modules/vcore/src/vcore/SoupMessageSendSync.cpp new file mode 100644 index 0000000..bca8e3e --- /dev/null +++ b/modules/vcore/src/vcore/SoupMessageSendSync.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 +#include + +#include + +#include + +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 > + proxy(vconf_get_str(VCONFKEY_NETWORK_PROXY), free); + + std::unique_ptr > + 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 diff --git a/modules/vcore/src/vcore/SoupMessageSendSync.h b/modules/vcore/src/vcore/SoupMessageSendSync.h new file mode 100644 index 0000000..ebb451d --- /dev/null +++ b/modules/vcore/src/vcore/SoupMessageSendSync.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*! + * @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 + +namespace SoupWrapper { + +class SoupMessageSendSync : public SoupMessageSendBase { + public: + RequestStatus sendSync(); + protected: + typedef WRT::ScopedGPointer ScopedSoupMessage; + typedef WRT::ScopedGPointer ScopedSoupSession; + typedef WRT::ScopedGPointer ScopedGMainContext; +}; + +} // namespace ValidationCore + +#endif diff --git a/modules/vcore/src/vcore/VCore.cpp b/modules/vcore/src/vcore/VCore.cpp new file mode 100644 index 0000000..60bf47e --- /dev/null +++ b/modules/vcore/src/vcore/VCore.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file VCore.cpp + * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) + * @brief + */ + +#include +#include +#include +#include +#include +#include +#include + +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 + diff --git a/modules/vcore/src/vcore/VCore.h b/modules/vcore/src/vcore/VCore.h new file mode 100644 index 0000000..bb3029a --- /dev/null +++ b/modules/vcore/src/vcore/VCore.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 + +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_ + diff --git a/modules/vcore/src/vcore/VCorePrivate.h b/modules/vcore/src/vcore/VCorePrivate.h new file mode 100644 index 0000000..ed85958 --- /dev/null +++ b/modules/vcore/src/vcore/VCorePrivate.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 +#include +#include +#include + +namespace ValidationCore { +DPL::DB::ThreadDatabaseSupport& ThreadInterface(void); +} // namespace ValidationCore + +#endif // _VCORE_SRC_VCORE_VCORE_H_ + diff --git a/modules/vcore/src/vcore/ValidatorCommon.h b/modules/vcore/src/vcore/ValidatorCommon.h new file mode 100644 index 0000000..8815239 --- /dev/null +++ b/modules/vcore/src/vcore/ValidatorCommon.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 +#include +#include + +namespace ValidationCore { +typedef std::set< std::string > ReferenceSet; +typedef std::list< std::string > ObjectList; + +/* + * base deleter func + */ +template +struct ValidatorCoreUniversalFree {}; + +// Template Specialization +#define VC_DECLARE_DELETER(type, function) \ + template <> \ + struct ValidatorCoreUniversalFree { \ + void universal_free(type *ptr){ \ + if (ptr) { \ + function(ptr); } \ + } \ + }; + +template +class AutoPtr +{ + public: + AutoPtr(T *ptr) : + m_data(ptr) + { + } + + AutoPtr(const AutoPtr &second) + { + m_data = second.m_data; + second.m_data = 0; + } + + AutoPtr & operator=(const AutoPtr &second) + { + if (this != &second) { + ValidatorCoreUniversalFree 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 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_ diff --git a/modules/vcore/src/vcore/ValidatorFactories.cpp b/modules/vcore/src/vcore/ValidatorFactories.cpp new file mode 100644 index 0000000..bd72237 --- /dev/null +++ b/modules/vcore/src/vcore/ValidatorFactories.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file + * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) + * @version 1.0 + * @brief + */ +#include + +#include + +#include +#include +#include + +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 diff --git a/modules/vcore/src/vcore/ValidatorFactories.h b/modules/vcore/src/vcore/ValidatorFactories.h new file mode 100644 index 0000000..075eef1 --- /dev/null +++ b/modules/vcore/src/vcore/ValidatorFactories.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file + * @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 + +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_ diff --git a/modules/vcore/src/vcore/VerificationStatus.cpp b/modules/vcore/src/vcore/VerificationStatus.cpp new file mode 100644 index 0000000..98199ad --- /dev/null +++ b/modules/vcore/src/vcore/VerificationStatus.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#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 diff --git a/modules/vcore/src/vcore/VerificationStatus.h b/modules/vcore/src/vcore/VerificationStatus.h new file mode 100644 index 0000000..67eecac --- /dev/null +++ b/modules/vcore/src/vcore/VerificationStatus.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#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_ diff --git a/modules/vcore/src/vcore/WacOrigin.cpp b/modules/vcore/src/vcore/WacOrigin.cpp new file mode 100644 index 0000000..7ca0174 --- /dev/null +++ b/modules/vcore/src/vcore/WacOrigin.cpp @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file + * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) + * @version 1.0 + * @brief + */ +#include "WacOrigin.h" + +#include +#include +#include + +#include <> + +#include +#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(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 diff --git a/modules/vcore/src/vcore/WacOrigin.h b/modules/vcore/src/vcore/WacOrigin.h new file mode 100644 index 0000000..d706fe3 --- /dev/null +++ b/modules/vcore/src/vcore/WacOrigin.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file + * @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 + +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_ diff --git a/modules/vcore/src/vcore/XmlsecAdapter.cpp b/modules/vcore/src/vcore/XmlsecAdapter.cpp new file mode 100644 index 0000000..2c3f231 --- /dev/null +++ b/modules/vcore/src/vcore/XmlsecAdapter.cpp @@ -0,0 +1,397 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 +#include + +#include +#include +#include + +#ifndef XMLSEC_NO_XSLT +#include +#endif /* XMLSEC_NO_XSLT */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "XmlsecAdapter.h" +#include +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(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(dsigRefCtx->digestMethod->id + ->name); + std::string strDigest(pDigest); + LogInfo("reference digest method: " << + reinterpret_cast(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( + 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 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 diff --git a/modules/vcore/src/vcore/XmlsecAdapter.h b/modules/vcore/src/vcore/XmlsecAdapter.h new file mode 100644 index 0000000..4104c88 --- /dev/null +++ b/modules/vcore/src/vcore/XmlsecAdapter.h @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 + +#include +#include +#include + +#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 XmlSecSingleton; +} // namespace ValidationCore +#endif // _XMLSECVERIFICATOR_H_ diff --git a/modules/vcore/src/vcore/scoped_gpointer.h b/modules/vcore/src/vcore/scoped_gpointer.h new file mode 100644 index 0000000..78772df --- /dev/null +++ b/modules/vcore/src/vcore/scoped_gpointer.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 +#include + +#include +#include + +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 +class ScopedGPointer : public DPL::ScopedResource +{ + typedef ScopedGPointerPolicy Policy; + typedef DPL::ScopedResource BaseType; + + public: + explicit ScopedGPointer(typename Policy::Type pointer = + Policy::NullValue()) : + BaseType(pointer) + { + } + + Class *operator->() const throw() + { + Assert(this->m_value != Policy::NullValue() && + "Dereference of scoped NULL pointer!"); + return static_cast(this->m_value); + } + + Class & operator *() const throw() + { + Assert(this->m_value != Policy::NullValue() && + "Dereference of scoped NULL pointer!"); + return *static_cast(this->m_value); + } +}; +} // namespace WRT + +#endif // WRT_ENGINE_SRC_COMMON_SCOPED_GPOINTER_H diff --git a/modules/widget_dao/CMakeLists.txt b/modules/widget_dao/CMakeLists.txt new file mode 100644 index 0000000..82403c9 --- /dev/null +++ b/modules/widget_dao/CMakeLists.txt @@ -0,0 +1,142 @@ +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 + ) diff --git a/modules/widget_dao/dao/WrtDatabase.cpp b/modules/widget_dao/dao/WrtDatabase.cpp new file mode 100644 index 0000000..f3fabe6 --- /dev/null +++ b/modules/widget_dao/dao/WrtDatabase.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#include +#include +#include +#include + +namespace WrtDB { + +const char* WrtDatabase::Address() +{ + using namespace WrtDB; + return GlobalConfig::GetWrtDatabaseFilePath(); +} + +DPL::DB::SqlConnection::Flag::Type WrtDatabase::Flags() +{ + return DPL::DB::SqlConnection::Flag::UseLucene; +} + +DPL::DB::ThreadDatabaseSupport WrtDatabase::m_interface( + WrtDatabase::Address(), + WrtDatabase::Flags()); + +void WrtDatabase::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); +} + +} diff --git a/modules/widget_dao/dao/bind_to_dao.h b/modules/widget_dao/dao/bind_to_dao.h new file mode 100644 index 0000000..9b9c2d3 --- /dev/null +++ b/modules/widget_dao/dao/bind_to_dao.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file 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(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(obj); + ExtObject extObject((instance->*argGetter)()); + return (extObject.*externalGetter)(); + } +}; + +} // namespace WrtDB + +#endif diff --git a/modules/widget_dao/dao/common_dao_types.cpp b/modules/widget_dao/dao/common_dao_types.cpp new file mode 100644 index 0000000..94e1222 --- /dev/null +++ b/modules/widget_dao/dao/common_dao_types.cpp @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * + * @file 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 + +#include + +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 diff --git a/modules/widget_dao/dao/config_parser_data.cpp b/modules/widget_dao/dao/config_parser_data.cpp new file mode 100644 index 0000000..d2550cc --- /dev/null +++ b/modules/widget_dao/dao/config_parser_data.cpp @@ -0,0 +1,424 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file config_parser_data.cpp + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 0.1 + * @brief + */ +#include +#include +#include +#include + +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 opt = str; + NormalizeString(opt); + str = *opt; +} + +void NormalizeString (DPL::Optional& txt) +{ + if (!!txt) { + std::string tmp = DPL::ToUTF8String(*txt); + const xmlChar* str = reinterpret_cast(tmp.c_str()); + if (!xmlCheckUTF8(str)) { + LogError("Not valid UTF8"); + return; + } + + int i = 0; + xmlChar* c; + while ((c = const_cast(xmlUTF8Strpos(str, i))) != NULL) { + if (!IsSpace(c)) { + break; + } + ++i; + } + + xmlChar* tmpnew = xmlUTF8Strndup(c, xmlUTF8Strlen(c) + 1); + bool first = false; + xmlChar* s = tmpnew; + while ((c = const_cast(xmlUTF8Strpos(str, i))) != NULL) { + if (IsSpace(c)) { + first = true; + ++i; + } else { + if (c[0] == 0x0) { + break; + } + if (first) { + xmlChar space[6] = { 0x20 }; + CopyChar(s, space); + s += xmlUTF8Size(s); + first = false; + } + CopyChar(s, c); + s += xmlUTF8Size(s); + ++i; + } + } + s[0] = 0x0; + txt = DPL::FromUTF8String(reinterpret_cast(tmpnew)); + xmlFree(tmpnew); + } +} + +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 diff --git a/modules/widget_dao/dao/feature_dao.cpp b/modules/widget_dao/dao/feature_dao.cpp new file mode 100644 index 0000000..60c7151 --- /dev/null +++ b/modules/widget_dao/dao/feature_dao.cpp @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * This file contains the definition of feature dao class. + * + * @file widget_dao.cpp + * @author Jaroslaw Osmanski (j.osmanski@samsung.com) + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @version 1.0 + * @brief This file contains the definition of feature configuration. + */ + +#include +#include +#include +#include +#include + +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( + DPL::FromUTF8String(*itdev))); + + deviceCapID = + select->GetSingleValue(); + } 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 diff --git a/modules/widget_dao/dao/feature_dao_read_only.cpp b/modules/widget_dao/dao/feature_dao_read_only.cpp new file mode 100644 index 0000000..adf11e9 --- /dev/null +++ b/modules/widget_dao/dao/feature_dao_read_only.cpp @@ -0,0 +1,322 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file feature_dao_read_only.cpp + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + * @brief This file contains the implementation of feature dao read only + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace WrtDB { + +FeatureDAOReadOnly::FeatureDAOReadOnly(FeatureHandle featureHandle) : + m_featureHandle(featureHandle) +{ + if (!isFeatureInstalled(m_featureHandle)) { + std::ostringstream exc; + exc << "Feature " << m_featureHandle << " not installed."; + LogError(exc.str()); + ThrowMsg(FeatureDAOReadOnly::Exception::FeatureNotExist, exc.str()); + } +} + +FeatureDAOReadOnly::FeatureDAOReadOnly(const std::string &featureName) +{ + LogDebug("FeatureDAOReadOnly ( " << featureName << " )"); + Try { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + WRT_DB_SELECT(select, FeaturesList, &WrtDatabase::interface()) + select->Where(Equals( + DPL::FromUTF8String(featureName))); + + m_featureHandle = select->GetSingleValue(); + LogDebug(" >> FeatureHandle retrieved: " << m_featureHandle); + } + Catch(DPL::DB::SqlConnection::Exception::Base){ + ReThrowMsg(FeatureDAOReadOnly::Exception::DatabaseError, + "Failure during creating FeatureDAOReadOnly"); + } +} + +#define GET_PLUGIN_DATA(func) \ + Try { \ + DPL::DB::ORM::wrt::ScopedTransaction transaction(&WrtDatabase::interface()); \ + LogDebug(# func << ". FeatureHandle: " << m_featureHandle); \ + std::string ret = PluginDAOReadOnly(GetPluginHandle()).func(); \ + transaction.Commit(); \ + return ret; \ + } \ + Catch(DPL::DB::SqlConnection::Exception::Base) { \ + std::ostringstream failure("Failure during "); \ + failure << # func; \ + ReThrowMsg(FeatureDAOReadOnly::Exception::DatabaseError, \ + failure.str()); \ + } + +std::string FeatureDAOReadOnly::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(m_featureHandle)); + + std::string ret = DPL::ToUTF8String( + select->GetSingleValue< FeaturesList::FeatureName>()); + + LogDebug(" >> Feature name: " << ret); + return ret; + } + Catch(DPL::DB::SqlConnection::Exception::Base){ + ReThrowMsg(FeatureDAOReadOnly::Exception::DatabaseError, + "Failure during getting GetName"); + } +} + +DbPluginHandle FeatureDAOReadOnly::GetPluginHandle() const +{ + LogDebug("Getting Plugin handle. FHandle: " << m_featureHandle); + Try { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + WRT_DB_SELECT(select, FeaturesList, &WrtDatabase::interface()) + select->Where(Equals(m_featureHandle)); + + DbPluginHandle pluginHandle = + select->GetSingleValue< FeaturesList::PluginPropertiesId>(); + + LogDebug(" >> Plugin Handle: " << pluginHandle); + return pluginHandle; + } + Catch(DPL::DB::SqlConnection::Exception::Base){ + ReThrowMsg(FeatureDAOReadOnly::Exception::DatabaseError, + "Failure during getting Plugin Handle"); + } +} + +FeatureHandleList FeatureDAOReadOnly::GetHandleList() +{ + LogDebug("Getting FeatureHandle list."); + Try { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + WRT_DB_SELECT(select, FeaturesList, &WrtDatabase::interface()) + + FeatureHandleList ret = + select->GetValueList(); + + std::ostringstream handles; + FOREACH(it, ret) + handles << *it << " "; + LogDebug(" >> FeatureHandle list retrieved: (" << handles << ")"); + + return ret; + } + Catch(DPL::DB::SqlConnection::Exception::Base){ + ReThrowMsg(FeatureDAOReadOnly::Exception::DatabaseError, + "Failure during getting FeatureHandle list"); + } +} + +bool FeatureDAOReadOnly::isFeatureInstalled(const std::string &featureName) +{ + LogDebug("Check if Feature is installed. Name: " << featureName); + Try { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + WRT_DB_SELECT(select, FeaturesList, &WrtDatabase::interface()) + select->Where(Equals( + DPL::FromUTF8String(featureName))); + + FeaturesList::Select::RowList rows = select->GetRowList(); + + bool flag = !rows.empty(); + LogDebug(" >> Feature " << featureName << + (flag ? " found." : " not found.")); + + return flag; + } + Catch(DPL::DB::SqlConnection::Exception::Base) { + ReThrowMsg(FeatureDAOReadOnly::Exception::DatabaseError, + "Failure during checking if Feature is installed"); + } +} + +bool FeatureDAOReadOnly::isFeatureInstalled(FeatureHandle handle) +{ + LogDebug("Check if Feature is installed. Handle: " << handle); + Try + { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + WRT_DB_SELECT(select, FeaturesList, &WrtDatabase::interface()) + select->Where(Equals(handle)); + + FeaturesList::Select::RowList rows = select->GetRowList(); + + bool flag = !rows.empty(); + LogDebug(" >> Feature " << handle << + (flag ? " found." : " not found.")); + + return flag; + } + Catch(DPL::DB::SqlConnection::Exception::Base){ + ReThrowMsg(FeatureDAOReadOnly::Exception::DatabaseError, + "Failure during checking if Feature is installed"); + } +} + +bool FeatureDAOReadOnly::isDeviceCapabilityInstalled( + const std::string &deviceCapName) +{ + LogDebug("Check if DeviceCap is installed. Name: " << deviceCapName); + Try { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + WRT_DB_SELECT(select, DeviceCapabilities, &WrtDatabase::interface()) + select->Where(Equals( + DPL::FromUTF8String(deviceCapName))); + + DeviceCapabilities::Select::RowList rows = select->GetRowList(); + + bool flag = !rows.empty(); + LogDebug(" >> Device Cap " << deviceCapName << + (flag ? "found." : "not found.")); + + return flag; + } + Catch(DPL::DB::SqlConnection::Exception::Base){ + ReThrowMsg(FeatureDAOReadOnly::Exception::DatabaseError, + "Failure during checking if DeviceCap is installed"); + } +} + +FeatureDAOReadOnly::DeviceCapabilitiesList +FeatureDAOReadOnly::GetDeviceCapabilities() const +{ + Try { + LogDebug("Get DeviceCap. FeatureHandle: " << m_featureHandle); + DPL::DB::ORM::wrt::ScopedTransaction transaction(&WrtDatabase::interface()); + + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + WRT_DB_SELECT(selectDevCP, FeatureDeviceCapProxy, &WrtDatabase::interface()) + selectDevCP->Where(Equals( + m_featureHandle)); + + DeviceCapabilitiesList devCap; + + std::list deviceIDs = + selectDevCP->GetValueList(); + FOREACH(devCId, deviceIDs) + { + WRT_DB_SELECT(selectDevC, DeviceCapabilities, &WrtDatabase::interface()) + selectDevC->Where(Equals(*devCId)); + + DPL::String devNames = + selectDevC->GetSingleValue(); + + devCap.insert(DPL::ToUTF8String(devNames)); + } + + transaction.Commit(); + return devCap; + } + Catch(DPL::DB::SqlConnection::Exception::Base){ + ReThrowMsg(FeatureDAOReadOnly::Exception::DatabaseError, + "Failure during getting DeviceCapabilities names"); + } +} + +FeatureHandleListPtr FeatureDAOReadOnly::GetFeatureHandleListForPlugin( + DbPluginHandle pluginHandle) +{ + LogDebug("Getting FeatureHandle list for pluginHandle: " << pluginHandle); + Try { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + + WRT_DB_SELECT(select, FeaturesList, &WrtDatabase::interface()) + select->Where(Equals(pluginHandle)); + + FeatureHandleListPtr handles(new FeatureHandleList); + FeatureHandleList ret = + select->GetValueList(); + + FOREACH(it, ret) + { + LogDebug("feature handle: " << *it); + handles->push_back(*it); + } + + return handles; + } + Catch(DPL::DB::SqlConnection::Exception::Base){ + ReThrowMsg( + FeatureDAOReadOnly::Exception::DatabaseError, + "Failure during getting FeatureHandle Set for plugin handle"); + } +} + +} // namespace WrtDB diff --git a/modules/widget_dao/dao/global_config.cpp b/modules/widget_dao/dao/global_config.cpp new file mode 100644 index 0000000..bf68cc4 --- /dev/null +++ b/modules/widget_dao/dao/global_config.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include + +#include +#include + +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 + diff --git a/modules/widget_dao/dao/global_dao.cpp b/modules/widget_dao/dao/global_dao.cpp new file mode 100644 index 0000000..6f1f406 --- /dev/null +++ b/modules/widget_dao/dao/global_dao.cpp @@ -0,0 +1,471 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 +#include +#include +#include +#include +#include +#include + +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(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(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(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(powder.category), + And(Equals(powder.level), + Equals(powder.context)))); + delWithContext->Execute(); + } else { + WRT_DB_DELETE(delWithoutContext, PowderRules, &WrtDatabase::interface()) + delWithoutContext->Where( + And(Equals(powder.category), + And(Equals(powder.level), + Is(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(oldRule.category), + And(Equals(oldRule.level), + Equals(oldRule.context)))); + updateWithContext->Values(row); + updateWithContext->Execute(); + } else { + WRT_DB_UPDATE(updateWithoutContext, PowderRules, &WrtDatabase::interface()) + updateWithoutContext->Where( + And(Equals(oldRule.category), + And(Equals(oldRule.level), + Is(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(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(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 savedData = + GetAutoSaveIdPasswd(url); + + if (!savedData.IsNull()) { + WRT_DB_UPDATE(update, AutoSaveIdPasswd, &WrtDatabase::interface()) + + update->Where(Equals(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(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(DPL::FromASCIIString(uri))); + deleteFrom->Execute(); + } Catch(DPL::DB::SqlConnection::Exception::Base) { + ReThrowMsg(GlobalDAO::Exception::DatabaseError, + "Failed to removed white URI from AdultBlackList"); + } +} + +} // namespace WrtDB diff --git a/modules/widget_dao/dao/global_dao_read_only.cpp b/modules/widget_dao/dao/global_dao_read_only.cpp new file mode 100644 index 0000000..cb26a1e --- /dev/null +++ b/modules/widget_dao/dao/global_dao_read_only.cpp @@ -0,0 +1,396 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file 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 + +#include +#include +#include +#include +#include +#include +#include +#include + +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 list = + select->GetValueList(); + 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(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(); + } + 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(); + } + 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(); +} + +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(); +} + +bool GlobalDAOReadOnly::GetSecureByDefault() +{ + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + WRT_DB_SELECT(select, GlobalProperties, &WrtDatabase::interface()) + return select->GetSingleValue(); +} + +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(); + } + 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 result = + select->GetSingleValue(); + 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 result = + select->GetSingleValue(); + 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(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(powder.category), + And(Equals(powder.level), + Equals(powder.context)))); + return !selWithContext->GetRowList().empty(); + } else { + WRT_DB_SELECT(selWithoutContext, PowderRules, &WrtDatabase::interface()) + selWithoutContext->Where( + And(Equals(powder.category), + And(Equals(powder.level), + Is(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 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(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( + 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( + select->GetSingleValue()); + } + 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(key)); + DPL::Optional agent = + select->GetSingleValue(); + 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(apifeature)); + featureUUID = select->GetSingleValue(); + } + + { + WRT_DB_SELECT(select, FeatureDeviceCapProxy, &WrtDatabase::interface()) + select->Where(Equals( + featureUUID)); + rows = select->GetRowList(); + } + + FOREACH(it, rows){ + WRT_DB_SELECT(select, DeviceCapabilities, &WrtDatabase::interface()) + select->Where(Equals( + it->Get_DeviceCapID())); + result.insert(select-> + GetSingleValue()); + } + + return result; + }Catch(DPL::DB::SqlConnection::Exception::Base){ + ReThrowMsg(GlobalDAOReadOnly::Exception::DatabaseError, + "Failed to update roaming network data usage"); + } +} + +DPL::Optional + 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(url)); + AutoSaveIdPasswd::Select::RowList rows = select->GetRowList(); + + if (rows.empty()) { + return DPL::Optional::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 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 diff --git a/modules/widget_dao/dao/path_builder.cpp b/modules/widget_dao/dao/path_builder.cpp new file mode 100644 index 0000000..4d91bbf --- /dev/null +++ b/modules/widget_dao/dao/path_builder.cpp @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file PathBuilder.cpp + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief Implementation file for PathBuilde class. + */ +#include +#include + +namespace WrtDB { +namespace { +const char PATH_SEPARATOR = '/'; +} + +class PathBuilderImpl : DPL::Noncopyable +{ + public: + PathBuilderImpl() + { + } + + explicit PathBuilderImpl(const std::string& path) : + m_stream(path, std::ios_base::app) + { + } + + void Append(const std::string& path) + { + // TODO Check additionally if last char is not separator. + if (m_stream.tellp() > 0) { + m_stream << PATH_SEPARATOR; + } + m_stream << path; + } + + void Concat(const std::string& arg) + { + m_stream << arg; + } + + void Concat(int arg) + { + m_stream << arg; + } + + void Reset() + { + m_stream.clear(); + m_stream.str(""); + } + + bool Empty() + { + return (m_stream.tellp() == 0); + } + + std::string GetFullPath() const + { + return m_stream.str(); + } + + private: + std::ostringstream m_stream; +}; + +PathBuilder::PathBuilder() : m_impl(new PathBuilderImpl()) +{ +} + +PathBuilder::PathBuilder(const std::string& path) : + m_impl(new PathBuilderImpl(path)) +{ +} + +PathBuilder::~PathBuilder() +{ + delete m_impl; +} + +PathBuilder& PathBuilder::Append(const std::string& path) +{ + m_impl->Append(path); + return *this; +} + +PathBuilder& PathBuilder::Concat(const std::string& arg) +{ + m_impl->Concat(arg); + return *this; +} + +PathBuilder& PathBuilder::Concat(int arg) +{ + m_impl->Concat(arg); + return *this; +} + +PathBuilder& PathBuilder::Reset() +{ + m_impl->Reset(); + return *this; +} + +bool PathBuilder::Empty() const +{ + return m_impl->Empty(); +} + +std::string PathBuilder::GetFullPath() const +{ + return m_impl->GetFullPath(); +} + +} // namespace WrtDB diff --git a/modules/widget_dao/dao/plugin_dao.cpp b/modules/widget_dao/dao/plugin_dao.cpp new file mode 100644 index 0000000..7941efb --- /dev/null +++ b/modules/widget_dao/dao/plugin_dao.cpp @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file plugin_dao.cpp + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @author Grzegorz Krawczyk (g.krawczyk@samsung.com) + * @version 1.0 + * @brief This file contains the definition of plugin dao class. + */ + +#include +#include +#include +#include +#include +#include + +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(pluginHandle)); + + update->Values(row); + update->Execute(); + transaction.Commit(); + } + Catch(DPL::DB::SqlConnection::Exception::Base) + { + ReThrowMsg(PluginDAO::Exception::DatabaseError, + "Failed in RegisterLibraryDependencies"); + } +} + +} // namespace WrtDB diff --git a/modules/widget_dao/dao/plugin_dao_read_only.cpp b/modules/widget_dao/dao/plugin_dao_read_only.cpp new file mode 100644 index 0000000..edb376d --- /dev/null +++ b/modules/widget_dao/dao/plugin_dao_read_only.cpp @@ -0,0 +1,428 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file plugin_dao_read_only.cpp + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + * @brief This file contains the implementation of plugin dao read only + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace WrtDB { + +namespace { + +typedef DPL::DB::ORM::wrt::PluginProperties::Row PluginRow; + +PluginRow getPluginRow(DbPluginHandle pluginHandle) +{ + LogDebug("Getting plugin row. Handle: " << pluginHandle); + Try { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + WRT_DB_SELECT(select, PluginProperties, &WrtDatabase::interface()) + select->Where(Equals( + pluginHandle)); + + PluginProperties::Select::RowList rows = select->GetRowList(); + if (rows.empty()) { + ThrowMsg(PluginDAOReadOnly::Exception::PluginNotExist, + "Cannot find plugin. Handle: " + pluginHandle); + } + return rows.front(); + } + Catch(DPL::DB::SqlConnection::Exception::Base) { + ReThrowMsg(PluginDAOReadOnly::Exception::DatabaseError, + "Failed in GetPluginRow"); + } +} +} + +PluginDAOReadOnly::PluginDAOReadOnly(DbPluginHandle pluginHandle) : + m_pluginHandle(pluginHandle) +{ + if (!isPluginInstalled(m_pluginHandle)) { + LogError("Plugin " << m_pluginHandle << " not installed."); + Throw(PluginDAOReadOnly::Exception::PluginNotExist); + } + + checkInstallationCompleted(); +} + +PluginDAOReadOnly::PluginDAOReadOnly(const std::string &libraryName) +{ + LogDebug("PluginDAOReadOnly ( " << libraryName << " )"); + Try { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + WRT_DB_SELECT(select, PluginProperties, &WrtDatabase::interface()) + select->Where(Equals( + DPL::FromUTF8String(libraryName))); + + PluginProperties::Select::RowList rows = select->GetRowList(); + if (!rows.empty()) { + m_pluginHandle = rows.front().Get_PluginPropertiesId(); + } else { + ThrowMsg(PluginDAOReadOnly::Exception::PluginNotExist, + "Cannot find plugin: [" + libraryName + "]"); + } + LogDebug(" >> Handle for this plugin: " << m_pluginHandle); + + checkInstallationCompleted(); + } + Catch(DPL::DB::SqlConnection::Exception::Base) { + ReThrowMsg(PluginDAOReadOnly::Exception::DatabaseError, + "Failed to connect to database"); + } +} + +void PluginDAOReadOnly::checkInstallationCompleted() +{ + if (getInstallationStateForHandle(m_pluginHandle) + != PluginDAOReadOnly::INSTALLATION_COMPLETED) { + LogError("Plugin " << m_pluginHandle << " installation not completed"); + Throw(PluginDAOReadOnly::Exception::PluginInstallationNotCompleted); + } +} + +bool PluginDAOReadOnly::isPluginInstalled(const std::string &libraryName) +{ + LogDebug("Check if Library is installed. LibraryName: " << libraryName); + Try { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + WRT_DB_SELECT(select, PluginProperties, &WrtDatabase::interface()) + select->Where(Equals( + DPL::FromUTF8String(libraryName))); + + PluginProperties::Select::RowList rows = select->GetRowList(); + + bool flag = !rows.empty(); + LogDebug(" >> Plugin " << libraryName << + (flag ? " found." : " not found.")); + + return flag; + } + Catch(DPL::DB::SqlConnection::Exception::Base) { + ReThrowMsg(PluginDAOReadOnly::Exception::DatabaseError, + "Failed in isPluginInstalled"); + } +} + +PluginHandleList PluginDAOReadOnly::getPluginHandleList() +{ + LogDebug("Getting plugin handle list."); + Try { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + WRT_DB_SELECT(select, PluginProperties, &WrtDatabase::interface()) + + PluginHandleList ret = + select->GetValueList(); + + std::ostringstream handles; + FOREACH(it, ret) + handles << *it << " "; + LogDebug(" >> PluginHandle list retrieved: (" << handles << ")"); + + return ret; + } + Catch(DPL::DB::SqlConnection::Exception::Base) { + ReThrowMsg(PluginDAOReadOnly::Exception::DatabaseError, + "Failed in GetPluginHandleList"); + } +} + +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(m_pluginHandle)); + + PluginDependencies::Select::RowList rows = select->GetRowList(); + + if (!rows.empty()) { + FOREACH(it, rows) + { + dependencies->insert(it->Get_RequiredPluginPropertiesId()); + } + } + + return dependencies; + } + Catch(DPL::DB::SqlConnection::Exception::Base) { + ReThrowMsg(PluginDAOReadOnly::Exception::DatabaseError, + "Failed in GetLibraryDependencies"); + } +} + +DbPluginHandle PluginDAOReadOnly::getPluginHandleForImplementedObject( + const std::string& objectName) +{ + LogDebug("GetPluginHandle for object: " << objectName); + + Try + { + DbPluginHandle pluginHandle = INVALID_PLUGIN_HANDLE; + + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + + WRT_DB_SELECT(select, PluginImplementedObjects, &WrtDatabase::interface()) + select->Where( + Equals( + DPL::FromUTF8String(objectName))); + + PluginImplementedObjects::Select::RowList rows = select->GetRowList(); + + if (!rows.empty()) { + pluginHandle = rows.front().Get_PluginPropertiesId(); + } else { + LogWarning("PluginHandle for object not found"); + } + return pluginHandle; + } + Catch(DPL::DB::SqlConnection::Exception::Base) { + ReThrowMsg(PluginDAOReadOnly::Exception::DatabaseError, + "Failed in GetPluginHandleForImplementedObject"); + } +} + +ImplementedObjectsList PluginDAOReadOnly::getImplementedObjectsForPluginHandle( + DbPluginHandle handle) +{ + LogDebug("getImplementedObjects for pluginHandle: " << handle); + + Try + { + ImplementedObjectsList objectList; + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + + WRT_DB_SELECT(select, PluginImplementedObjects, &WrtDatabase::interface()) + select->Where( + Equals(handle)); + + PluginImplementedObjects::Select::RowList rows = select->GetRowList(); + + if (!rows.empty()) { + FOREACH(it, rows) + { + objectList.push_back(DPL::ToUTF8String(it->Get_PluginObject())); + } + } else { + LogWarning("PluginHandle for object not found"); + } + return objectList; + } + Catch(DPL::DB::SqlConnection::Exception::Base) { + ReThrowMsg(PluginDAOReadOnly::Exception::DatabaseError, + "Failed in GetPluginHandleForImplementedObject"); + } +} + +PluginObjectsDAO::ObjectsPtr PluginDAOReadOnly::getRequiredObjectsForPluginHandle( + DbPluginHandle handle) +{ + Try + { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + + PluginObjectsDAO::ObjectsPtr objects = + PluginObjectsDAO::ObjectsPtr(new PluginObjectsDAO::Objects); + + WRT_DB_SELECT(select, PluginRequiredObjects, &WrtDatabase::interface()) + select->Where( + Equals(handle)); + + PluginRequiredObjects::Select::RowList rows = select->GetRowList(); + + if (!rows.empty()) { + FOREACH(it, rows) + { + objects->insert(DPL::ToUTF8String(it->Get_PluginObject())); + } + } + + return objects; + } + Catch(DPL::DB::SqlConnection::Exception::Base) { + ReThrowMsg(PluginDAOReadOnly::Exception::DatabaseError, + "Failed in GetRequiredObjectsForPluginHandle"); + } +} + +PluginHandleSetPtr PluginDAOReadOnly::getPluginHandleByStatus( + PluginInstallationState state) +{ + Try + { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + + PluginHandleSetPtr handleSet(new PluginHandleSet); + + WRT_DB_SELECT(select, PluginProperties, &WrtDatabase::interface()) + select->Where( + Equals(ToInt(state))); + + PluginProperties::Select::RowList rows = select->GetRowList(); + + if (!rows.empty()) { + FOREACH(it, rows) + { + handleSet->insert(it->Get_PluginPropertiesId()); + } + } + + return handleSet; + } + Catch(DPL::DB::SqlConnection::Exception::Base) { + ReThrowMsg(PluginDAOReadOnly::Exception::DatabaseError, + "Failed in GetPluginHandleByStatus"); + } +} + +PluginDAOReadOnly::PluginInstallationState PluginDAOReadOnly::getInstallationStatus() const +{ + PluginRow row = getPluginRow(m_pluginHandle); + return ToState(row.Get_InstallationState()); +} + +PluginDAOReadOnly::PluginInstallationState PluginDAOReadOnly::getInstallationStateForHandle( + DbPluginHandle handle) +{ + Try + { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + + WRT_DB_SELECT(select, PluginProperties, &WrtDatabase::interface()) + select->Where( + Equals(handle)); + + PluginProperties::Select::RowList rows = select->GetRowList(); + + if (!rows.empty()) { + return ToState(rows.front().Get_InstallationState()); + } + LogError("Data in DB are invalid. Missing field"); + return UNKNOWN_ERROR; + } + Catch(DPL::DB::SqlConnection::Exception::Base) { + ReThrowMsg(PluginDAOReadOnly::Exception::DatabaseError, + "Failed in GetStatusForHandle"); + } +} + +bool PluginDAOReadOnly::isPluginInstalled(DbPluginHandle pluginHandle) +{ + Try { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + WRT_DB_SELECT(select, PluginProperties, &WrtDatabase::interface()) + select->Where( + Equals(pluginHandle)); + + PluginProperties::Select::RowList rows = select->GetRowList(); + + bool flag = !rows.empty(); + + return flag; + } + Catch(DPL::DB::SqlConnection::Exception::Base) { + ReThrowMsg(PluginDAOReadOnly::Exception::DatabaseError, + "Failed in isPluginInstalled"); + } +} + +} // namespace WrtDB diff --git a/modules/widget_dao/dao/property_dao.cpp b/modules/widget_dao/dao/property_dao.cpp new file mode 100644 index 0000000..95ba056 --- /dev/null +++ b/modules/widget_dao/dao/property_dao.cpp @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file property_dao.h + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @version 1.0 + * @brief This file contains the definition of property dao class. + */ + +#include +#include +#include +#include +#include +#include +#include + +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(widgetHandle), + Equals(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(widgetHandle), + Equals(key))); + + update->Values(row); + update->Execute(); + } + transaction.Commit(); + } + Catch(DPL::DB::SqlConnection::Exception::Base){ + ReThrowMsg(PropertyDAOReadOnly::Exception::DatabaseError, + "Failure during setting/updating property"); + } +} + +void RegisterProperties(DbWidgetHandle widgetHandle, + 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 diff --git a/modules/widget_dao/dao/property_dao_read_only.cpp b/modules/widget_dao/dao/property_dao_read_only.cpp new file mode 100644 index 0000000..74208af --- /dev/null +++ b/modules/widget_dao/dao/property_dao_read_only.cpp @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * property_dao_read_only.cpp + * + * Created on: Nov 16, 2011 + * Author: Krzysztof Jackiewicz(k.jackiewicz@samsung.com) + */ + +#include +#include +#include +#include +#include +#include + +namespace WrtDB { +namespace PropertyDAOReadOnly { + +namespace { + +typedef DPL::DB::ORM::wrt::WidgetPreference::key_name::ColumnType + ORMWidgetPropertyKey; +typedef DPL::DB::ORM::wrt::WidgetPreference::key_value::ColumnType + ORMWidgetPropertyValue; +typedef std::list ORMWidgetPreferenceList; +typedef std::list ORMWidgetPropertyKeyList; + + +void convertPropertyKey(const ORMWidgetPropertyKey& ormKey, + WidgetPropertyKey& key) +{ + key = ormKey; +} + +void convertPropertyValue(const ORMWidgetPropertyValue& ormPropertyVal, + WidgetPropertyValue& propertyVal) +{ + propertyVal = ormPropertyVal; +} + +void convertWidgetPreferenceRow(const ORMWidgetPreferenceList& ormWidgetPrefRow, + WidgetPreferenceList& prefRow) +{ + FOREACH(it, ormWidgetPrefRow) { + WidgetPreferenceRow row; + + row.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(widgetHandle)); + keyList = select->GetValueList(); + + WidgetPropertyKeyList retKeyList; + + convertWidgetPropertyKeyList(keyList, retKeyList); + return retKeyList; + } + Catch(DPL::DB::SqlConnection::Exception::Base){ + ReThrowMsg(Exception::DatabaseError, + "Failure during getting propertykey list"); + } +} + +WidgetPreferenceList GetPropertyList(DbWidgetHandle widgetHandle) +{ + 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(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(widgetHandle), + Equals(key))); + + ORMWidgetPropertyValue ormPropValue = + select->GetSingleValue(); + + WidgetPropertyValue propValue; + + convertPropertyValue(ormPropValue, propValue); + + return propValue; + } + Catch(DPL::DB::SqlConnection::Exception::Base){ + ReThrowMsg(Exception::DatabaseError, + "Failure during getting property"); + } +} + +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(widgetHandle), + Equals(key))); + + return select->GetSingleValue(); + } + Catch(DPL::DB::SqlConnection::Exception::Base){ + ReThrowMsg(Exception::DatabaseError, + "Failure during checking readonly flag for property"); + } +} + +} // namespace PropertyDAOReadOnly +} // namespace WrtDB diff --git a/modules/widget_dao/dao/webruntime_database.cpp b/modules/widget_dao/dao/webruntime_database.cpp new file mode 100644 index 0000000..bc24fbe --- /dev/null +++ b/modules/widget_dao/dao/webruntime_database.cpp @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file webruntime_database.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file contains the definition of webruntime database + */ +#include + +DPL::Mutex g_wrtDbQueriesMutex; + diff --git a/modules/widget_dao/dao/widget_dao.cpp b/modules/widget_dao/dao/widget_dao.cpp new file mode 100644 index 0000000..be33379 --- /dev/null +++ b/modules/widget_dao/dao/widget_dao.cpp @@ -0,0 +1,600 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * This file contains the definition of widget dao class. + * + * @file widget_dao.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @author Bartosz Janiak (b.janiak@samsung.com) + * @author Yang Jie (jie2.yang@samsung.com) + * @author Koeun Choi(koeun.choi@samsung.com) + * @author Pawel Sikorski(p.sikorski@samsung.com) + * @version 1.0 + * @brief This file contains the definition of Configuration. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +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(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(widgetHandle), + Equals(*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(widgetHandle), + Equals(*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 ( + 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(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 diff --git a/modules/widget_dao/dao/widget_dao_read_only.cpp b/modules/widget_dao/dao/widget_dao_read_only.cpp new file mode 100644 index 0000000..d3c9377 --- /dev/null +++ b/modules/widget_dao/dao/widget_dao_read_only.cpp @@ -0,0 +1,1094 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * This file contains the declaration of widget dao class. + * + * @file widget_dao_read_only.cpp + * @author Yang Jie (jie2.yang@samsung.com) + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @version 1.0 + * @brief This file contains the declaration of widget dao + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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(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(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(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(m_widgetHandle), + Equals(languageTag))); + LocalizedWidgetInfo::Row info = select->GetSingleRow(); + WidgetLocalizedInfo result; + + result.name = info.Get_widget_name(); + result.shortName = info.Get_widget_shortname(); + result.description = info.Get_widget_description(); + result.license = info.Get_widget_license(); + result.licenseHref = info.Get_widget_license_href(); + + transaction.Commit(); + return result; + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get localized info") +} + +DbWidgetFeatureSet WidgetDAOReadOnly::getFeaturesList() const +{ + LogDebug("Getting FeaturesList. Handle: " << m_widgetHandle); + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + 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(m_widgetHandle)); + + DbWidgetFeatureSet resultSet; + typedef std::list RowList; + RowList list = select->GetRowList(); + + for (RowList::iterator i = list.begin(); i != list.end(); ++i) { + DbWidgetFeature feature; + feature.name = i->Get_name(); + feature.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( + widgetFeatureId)); + + WidgetParamMap resultMap; + typedef std::list 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(m_widgetHandle), + Equals( + DPL::FromUTF8String(featureName)))); + + wrt::WidgetFeature::Select::RowList rows = select->GetRowList(); + transaction.Commit(); + return !rows.empty(); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to check for feature") +} + +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(m_widgetHandle)); + std::list values = + select->GetValueList(); + 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(); + } + 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(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(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(m_widgetHandle)); + + std::list chainList = select->GetRowList(); + + CertificateChainList result; + + FOREACH(iter, chainList) + result.push_back(DPL::ToUTF8String(iter->Get_encoded_chain())); + return result; +} + +DbWidgetSize WidgetDAOReadOnly::getPreferredSize() const +{ + WidgetInfoRow row = getWidgetInfoRow(m_widgetHandle); + + DbWidgetSize size; + size.width = row.Get_widget_width(); + size.height = row.Get_widget_height(); + + LogDebug("Return size wxh = " << + (!!size.width ? *size.width : -1) << " x " << + (!!size.height ? *size.height : -1)); + + return size; +} + +WidgetType WidgetDAOReadOnly::getWidgetType() const +{ + WidgetInfoRow row = getWidgetInfoRow(m_widgetHandle); + DPL::OptionalInt result = row.Get_widget_type(); + return WidgetType(static_cast(*result)); +} + +WidgetGUID WidgetDAOReadOnly::getGUID() const +{ + WidgetInfoRow row = getWidgetInfoRow(m_widgetHandle); + return row.Get_widget_id(); +} + +DPL::OptionalString WidgetDAOReadOnly::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 WidgetDAOReadOnly::getVersion() const +{ + WidgetInfoRow row = getWidgetInfoRow(m_widgetHandle); + return row.Get_widget_version(); +} + +DPL::Optional WidgetDAOReadOnly::getAuthorName() const +{ + WidgetInfoRow row = getWidgetInfoRow(m_widgetHandle); + return row.Get_author_name(); +} + +DPL::Optional WidgetDAOReadOnly::getAuthorEmail() const +{ + WidgetInfoRow row = getWidgetInfoRow(m_widgetHandle); + return row.Get_author_email(); +} + +DPL::Optional WidgetDAOReadOnly::getAuthorHref() const +{ + WidgetInfoRow row = getWidgetInfoRow(m_widgetHandle); + return row.Get_author_href(); +} + +DPL::Optional WidgetDAOReadOnly::getMinimumWacVersion() const +{ + WidgetInfoRow row = getWidgetInfoRow(m_widgetHandle); + return row.Get_min_version(); +} + +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(m_widgetHandle)); + WidgetExtendedInfo::Select::RowList rows = select->GetRowList(); + + if (rows.empty()) { + ThrowMsg(WidgetDAOReadOnly::Exception::WidgetNotExist, + "Cannot find widget. Handle: " << m_widgetHandle); + } + + DPL::Optional 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(*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(*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(*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(m_widgetHandle)); + + WidgetExtendedInfo::Select::RowList rows = select->GetRowList(); + if (rows.empty()) { + ThrowMsg(WidgetDAOReadOnly::Exception::WidgetNotExist, + "Cannot find widget. Handle: " << m_widgetHandle); + } + + return static_cast(rows.front().Get_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(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(*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(m_widgetHandle)); + + WidgetExtendedInfo::Select::RowList rows = select->GetRowList(); + if (rows.empty()) { + ThrowMsg(WidgetDAOReadOnly::Exception::WidgetNotExist, + "Cannot find widget. Handle: " << m_widgetHandle); + } + + return static_cast(*rows.front().Get_install_time()); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get widdget install time") +} + +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(m_widgetHandle)); + + std::list list = + select->GetRowList(); + WidgetLocalizedIconList ret; + FOREACH(it,list) + { + WidgetLocalizedIconRow icon = {it->Get_app_id(), + it->Get_icon_id(), + it->Get_widget_locale()}; + ret.push_back(icon); + } + return ret; + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get icon data") +} + +WidgetDAOReadOnly::WidgetIconList WidgetDAOReadOnly::getIconList() const +{ + //TODO check widget existance + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + WRT_DB_SELECT(select, wrt::WidgetIcon, &WrtDatabase::interface()) + select->Where(Equals(m_widgetHandle)); + + std::list list = + select->GetRowList(); + WidgetIconList ret; + FOREACH(it,list) + { + WidgetIconRow icon = {it->Get_icon_id(), + it->Get_app_id(), + it->Get_icon_src(), + it->Get_icon_width(), + it->Get_icon_height()}; + ret.push_back(icon); + } + return ret; + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get icon data") +} + +WidgetDAOReadOnly::LocalizedStartFileList WidgetDAOReadOnly::getLocalizedStartFileList() const +{ + //TODO check widget existance + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + WRT_DB_SELECT(select, WidgetLocalizedStartFile, &WrtDatabase::interface()) + select->Where(Equals( + m_widgetHandle)); + select->OrderBy("start_file_id ASC"); + + std::list list = + select->GetRowList(); + LocalizedStartFileList ret; + FOREACH(it,list) + { + WidgetLocalizedStartFileRow file = {it->Get_start_file_id(), + it->Get_app_id(), + it->Get_widget_locale(), + it->Get_type(), + it->Get_encoding()}; + ret.push_back(file); + } + return ret; + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get start file list data") +} + +WidgetDAOReadOnly::WidgetStartFileList WidgetDAOReadOnly::getStartFileList() const +{ + //TODO check widget existance + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + WRT_DB_SELECT(select, WidgetStartFile, &WrtDatabase::interface()) + select->Where(Equals(m_widgetHandle)); + select->OrderBy("start_file_id ASC"); + + std::list list = + select->GetRowList(); + WidgetStartFileList ret; + FOREACH(it,list) + { + WidgetStartFileRow file = {it->Get_start_file_id(), + it->Get_app_id(), + it->Get_src()}; + ret.push_back(file); + } + return ret; + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get start file list data") +} + +WindowModeList WidgetDAOReadOnly::getWindowModes() const +{ + //TODO check widget existance + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + WRT_DB_SELECT(select, WidgetWindowModes, &WrtDatabase::interface()) + select->Where(Equals(m_widgetHandle)); + + return select->GetValueList(); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get window modes") +} + +std::string WidgetDAOReadOnly::getBaseFolder() const +{ + WidgetInfoRow row = getWidgetInfoRow(m_widgetHandle); + DPL::Optional ret = row.Get_base_folder(); + std::string baseFolder; + if (!ret.IsNull()) { + baseFolder = DPL::ToUTF8String(*ret); + } + + if (!baseFolder.empty()) { + baseFolder += "/"; + } + + return baseFolder; +} + +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( + m_widgetHandle)); + select->OrderBy("chainid"); + WidgetCertificateFingerprint::Select::RowList rows = + select->GetRowList(); + + WidgetCertificateDataList outlCertificateData; + FOREACH(it, rows) + { + WidgetCertificateData data; + + data.owner = + static_cast (it->Get_owner()); + data.type = + static_cast (it->Get_type()); + data.chainId = it->Get_chainid(); + DPL::Optional md5 = it->Get_md5_fingerprint(); + data.strMD5Fingerprint = + md5.IsNull() ? "" : DPL::ToUTF8String(*md5); + DPL::Optional sha1 = it->Get_sha1_fingerprint(); + data.strSHA1Fingerprint = + sha1.IsNull() ? "" : DPL::ToUTF8String(*sha1); + DPL::Optional cname = it->Get_common_name(); + data.strCommonName = + cname.IsNull() ? DPL::FromUTF8String("") : *cname; + + outlCertificateData.push_back(data); + } + return outlCertificateData; + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get fingerprint list") +} + +FingerPrintList WidgetDAOReadOnly::getKeyFingerprints( + WidgetCertificateData::Owner owner, + WidgetCertificateData::Type type) const +{ + //TODO check widget existance + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + WRT_DB_SELECT(select, WidgetCertificateFingerprint, &WrtDatabase::interface()) + select->Where(And(And( + Equals(m_widgetHandle), + Equals(owner)), + Equals(type))); + + WidgetCertificateFingerprint::Select::RowList rows = + select->GetRowList(); + + FingerPrintList keys; + FOREACH(it, rows) + { + DPL::Optional md5 = it->Get_md5_fingerprint(); + keys.push_back(md5.IsNull() ? "" : DPL::ToUTF8String(*md5)); + DPL::Optional 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(m_widgetHandle), + Equals(owner)), + Equals(type))); + + WidgetCertificateFingerprint::Select::RowList rows = + select->GetRowList(); + + WidgetCertificateCNList out; + FOREACH(it, rows) + { + DPL::Optional cname = it->Get_common_name(); + out.push_back(cname.IsNull() ? "" : DPL::ToUTF8String(*cname)); + } + return out; + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get key common name") +} + +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(m_widgetHandle), + Equals( + DPL::FromUTF8String(resourceId)))); + + std::list 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(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(m_widgetHandle)); + return select->GetValueList(); + } + 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(m_widgetHandle)); + select->Distinct(); + return select->GetValueList(); +} + +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(m_widgetHandle)); + typedef std::list 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( + it->Get_id())); + typedef std::list 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(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(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 diff --git a/modules/widget_dao/include/dpl/wrt-dao-ro/WrtDatabase.h b/modules/widget_dao/include/dpl/wrt-dao-ro/WrtDatabase.h new file mode 100644 index 0000000..86a0980 --- /dev/null +++ b/modules/widget_dao/include/dpl/wrt-dao-ro/WrtDatabase.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef WRT_SRC_CONFIGURATION_WRTDATABASE_H_ +#define WRT_SRC_CONFIGURATION_WRTDATABASE_H_ + +#include + +namespace WrtDB { + +class WrtDatabase +{ + public: + static const char *Address(); + static DPL::DB::SqlConnection::Flag::Type Flags(); + static void 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 */ + diff --git a/modules/widget_dao/include/dpl/wrt-dao-ro/common_dao_types.h b/modules/widget_dao/include/dpl/wrt-dao-ro/common_dao_types.h new file mode 100644 index 0000000..6913766 --- /dev/null +++ b/modules/widget_dao/include/dpl/wrt-dao-ro/common_dao_types.h @@ -0,0 +1,487 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 +#include +#include +#include +#include +#include +#include + +namespace WrtDB { +namespace Powder { + +typedef std::set 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 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 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 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 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 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 m_deviceCapabilities; + + bool operator< (const Feature& obj) const + { + return m_name < obj.m_name; + } + }; + typedef std::set 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 Objects; + typedef DPL::SharedPtr 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 WidgetAccessInfoList; + +typedef std::list 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 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 DbWidgetFeatureSet; + +/** + * @brief Default container with DbWidgetHandle's + */ +typedef std::list 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 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 WidgetApplicationServiceList; +#endif /* WRT_SRC_CONFIGURATION_COMMON_DAO_TYPES_H_ */ diff --git a/modules/widget_dao/include/dpl/wrt-dao-ro/config_parser_data.h b/modules/widget_dao/include/dpl/wrt-dao-ro/config_parser_data.h new file mode 100644 index 0000000..a2d92ef --- /dev/null +++ b/modules/widget_dao/include/dpl/wrt-dao-ro/config_parser_data.h @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file config_parser_data.h + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 0.1 + * @brief + */ +#ifndef CONFIG_PARSER_DATA_H_ +#define CONFIG_PARSER_DATA_H_ + +#include +#include +#include +#include +#include +#include +#include + +namespace WrtDB { + +void NormalizeString(DPL::OptionalString& txt); +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 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 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 IconsList; + + struct LocalizedData + { + DPL::OptionalString name; + DPL::OptionalString shortName; + + DPL::OptionalString description; + + DPL::OptionalString license; + DPL::OptionalString licenseFile; + DPL::OptionalString licenseHref; + }; + typedef std::map LocalizedDataSet; + + struct Preference + { + Preference(const DPL::String& name, + bool readonly = false) : + name(name), + value(), + readonly(readonly) + { + } + DPL::String name; + DPL::OptionalString value; + bool readonly; + bool operator==(const Preference&) const; + bool operator!=(const Preference&) const; + bool operator >(const Preference&) const; + bool operator>=(const Preference&) const; + bool operator <(const Preference&) const; + bool operator<=(const Preference&) const; + }; + typedef std::set PreferencesList; + typedef std::set StringsList; + + struct AccessInfo + { + AccessInfo(const DPL::String& strIRI, + bool bSubdomainAccess) : m_strIRI(strIRI), + m_bSubDomainAccess(bSubdomainAccess) + { + } + + bool operator==(const AccessInfo&) const; + bool operator!=(const AccessInfo&) const; + bool operator <(const AccessInfo&) const; + + DPL::String m_strIRI; + bool m_bSubDomainAccess; + }; + typedef std::set AccessInfoSet; + + struct Setting + { + Setting(const DPL::String& name, + const DPL::String& value) : + m_name(name), + m_value(value) + { + } + DPL::String m_name; + DPL::String m_value; + + bool operator==(const Setting&) const; + bool operator!=(const Setting&) const; + bool operator >(const Setting&) const; + bool operator>=(const Setting&) const; + bool operator <(const Setting&) const; + bool operator<=(const Setting&) const; + }; + + typedef std::set SettingsList; + + struct 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 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_ diff --git a/modules/widget_dao/include/dpl/wrt-dao-ro/feature_dao_read_only.h b/modules/widget_dao/include/dpl/wrt-dao-ro/feature_dao_read_only.h new file mode 100644 index 0000000..9bd8945 --- /dev/null +++ b/modules/widget_dao/include/dpl/wrt-dao-ro/feature_dao_read_only.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file feature_dao_read_only.h + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + * @brief This file contains the declaration of feature dao read only + */ + +#ifndef WRT_SRC_CONFIGURATION_FEATURE_DAO_READ_ONLY_H_ +#define WRT_SRC_CONFIGURATION_FEATURE_DAO_READ_ONLY_H_ + +#include +#include +#include +#include +#include "feature_model.h" +#include +#include + +namespace WrtDB { + +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 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_ */ diff --git a/modules/widget_dao/include/dpl/wrt-dao-ro/feature_model.h b/modules/widget_dao/include/dpl/wrt-dao-ro/feature_model.h new file mode 100644 index 0000000..13b959c --- /dev/null +++ b/modules/widget_dao/include/dpl/wrt-dao-ro/feature_model.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file feature_model.h + * @author Pawel Sikorski (p.sikorski@samgsung.com) + * @version + * @brief This file contains FeatureModel, FeatureHandle definitions. + */ +#ifndef FEATURE_MODEL_H +#define FEATURE_MODEL_H + +#include +#include +#include +#include +#include +#include +#include + +namespace WrtDB { + +typedef int FeatureHandle; +typedef std::list FeatureHandleList; +typedef DPL::SharedPtr FeatureHandleListPtr; + +typedef int FeatureSetHandle; +typedef std::list FeatureSetHandleList; + +class FeatureModel : public DPL::Event::Model +{ + public: + DPL::Event::Property FHandle; + DPL::Event::Property Name; + + DPL::Event::Property > DeviceCapabilities; + DPL::Event::Property PHandle; + + FeatureModel(FeatureHandle handle) : + FHandle(this, handle), + Name(this), + DeviceCapabilities(this), + PHandle(this, -1) + { + } +}; + +typedef DPL::SharedPtr FeatureModelPtr; + +} // namespace WrtDB + +#endif // FEATURE_MODEL_H diff --git a/modules/widget_dao/include/dpl/wrt-dao-ro/global_config.h b/modules/widget_dao/include/dpl/wrt-dao-ro/global_config.h new file mode 100644 index 0000000..bda207b --- /dev/null +++ b/modules/widget_dao/include/dpl/wrt-dao-ro/global_config.h @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file global_config.h + * @author Yang Jie (jie2.yang@samsung.com) + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file contains global WRT config + */ +#ifndef GLOBAL_CONFIG_H +#define GLOBAL_CONFIG_H + +#include +#include + +namespace WrtDB { +namespace GlobalConfig { +/** + * WRT database path + */ +inline const char* GetWrtDatabaseFilePath() +{ + return "/opt/dbspace/.wrt.db"; +} + +/** + * WRT 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 diff --git a/modules/widget_dao/include/dpl/wrt-dao-ro/global_dao_read_only.h b/modules/widget_dao/include/dpl/wrt-dao-ro/global_dao_read_only.h new file mode 100644 index 0000000..2feafca --- /dev/null +++ b/modules/widget_dao/include/dpl/wrt-dao-ro/global_dao_read_only.h @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file 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 +#include +#include + +#include +#include + +#include + +namespace WrtDB { + +typedef std::list WidgetPackageList; +typedef std::set 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 GetAutoSaveIdPasswd( + const DPL::String &url); + + protected: + GlobalDAOReadOnly() + { + } +}; + +} // namespace WrtDB + +#endif // WRT_SRC_CONFIGURATION_GLOBAL_DAO_READ_ONLY_H_ diff --git a/modules/widget_dao/include/dpl/wrt-dao-ro/path_builder.h b/modules/widget_dao/include/dpl/wrt-dao-ro/path_builder.h new file mode 100644 index 0000000..18fcca3 --- /dev/null +++ b/modules/widget_dao/include/dpl/wrt-dao-ro/path_builder.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file PathBuilder.h + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief Header file for PathBuilder class. + */ +#ifndef WRT_UTILS_PATHBUILDER_H +#define WRT_UTILS_PATHBUILDER_H + +#include +#include + +namespace WrtDB { + +class PathBuilderImpl; + +class PathBuilder : private DPL::Noncopyable +{ + public: + PathBuilder(); + explicit PathBuilder(const std::string& path); + + ~PathBuilder(); + + PathBuilder& Append(const std::string& path); + + PathBuilder& Concat(const std::string& arg); + PathBuilder& Concat(int arg); + + PathBuilder& Reset(); + + bool Empty() const; + + std::string GetFullPath() const; + + private: + PathBuilderImpl* m_impl; +}; + +} // namespace WrtDB + +#endif diff --git a/modules/widget_dao/include/dpl/wrt-dao-ro/plugin_dao_read_only.h b/modules/widget_dao/include/dpl/wrt-dao-ro/plugin_dao_read_only.h new file mode 100644 index 0000000..2341316 --- /dev/null +++ b/modules/widget_dao/include/dpl/wrt-dao-ro/plugin_dao_read_only.h @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file plugin_dao_read_only.h + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + * @brief This file contains the declaration of plugin dao read only + */ + + +#ifndef WRT_SRC_CONFIGURATION_PLUGIN_DAO_READ_ONLY_H_ +#define WRT_SRC_CONFIGURATION_PLUGIN_DAO_READ_ONLY_H_ + +#include +#include +#include +#include +#include + +namespace WrtDB { + +typedef std::list PluginHandleList; +typedef std::set PluginHandleSet; +typedef std::list ImplementedObjectsList; +typedef DPL::SharedPtr PluginHandleSetPtr; + +//TODO make it friend to FeatureDAO or inherit +class PluginDAOReadOnly +{ + public: + enum PluginInstallationState + { + INSTALLATION_DEFAULT, + //when plugin data are up to date and plugin model may be created + INSTALLATION_COMPLETED, + //installation is in progress, some data may not be valid + INSTALLATION_IN_PROGRESS, + //installation not completed due to missing dependency + INSTALLATION_WAITING, + + UNKNOWN_ERROR + }; + + static int ToInt(PluginInstallationState state) + { + return static_cast(state); + } + + static PluginInstallationState ToState(int state) + { + return static_cast(state); + } + + /** + * PluginDAO Exception classes + */ + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, DatabaseError) + DECLARE_EXCEPTION_TYPE(Base, PluginNotExist) + DECLARE_EXCEPTION_TYPE(Base, PluginInstallationNotCompleted) + }; + + public: + PluginDAOReadOnly(DbPluginHandle pluginHandle); + PluginDAOReadOnly(const std::string &libraryName); + + static PluginHandleList getPluginHandleList(); + + static 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_ */ diff --git a/modules/widget_dao/include/dpl/wrt-dao-ro/property_dao_read_only.h b/modules/widget_dao/include/dpl/wrt-dao-ro/property_dao_read_only.h new file mode 100644 index 0000000..50b3dab --- /dev/null +++ b/modules/widget_dao/include/dpl/wrt-dao-ro/property_dao_read_only.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * property_dao_read_only.h + * + * Created on: Nov 16, 2011 + * Author: Krzysztof Jackiewicz(k.jackiewicz@samsung.com) + */ + +#ifndef PROPERTY_DAO_READ_ONLY_H_ +#define PROPERTY_DAO_READ_ONLY_H_ + +#include +#include +#include +#include +#include + +namespace WrtDB { +namespace PropertyDAOReadOnly { + +typedef DPL::String WidgetPropertyKey; +typedef DPL::OptionalString WidgetPropertyValue; + +typedef std::list WidgetPropertyKeyList; + +struct WidgetPreferenceRow { + int app_id; + WidgetPropertyKey key_name; + WidgetPropertyValue key_value; + DPL::OptionalInt readonly; +}; + +typedef std::list WidgetPreferenceList; + +/** + * PropertyDAO Exception classes + */ +class Exception +{ + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, DatabaseError) + DECLARE_EXCEPTION_TYPE(Base, ReadOnlyProperty) +}; + +/* 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_ */ diff --git a/modules/widget_dao/include/dpl/wrt-dao-ro/webruntime_database.h b/modules/widget_dao/include/dpl/wrt-dao-ro/webruntime_database.h new file mode 100644 index 0000000..96afd44 --- /dev/null +++ b/modules/widget_dao/include/dpl/wrt-dao-ro/webruntime_database.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file webruntime_database.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file contains the declaration of webruntime database + */ +#ifndef WRT_ENGINE_SRC_CONFIGURATION_WEBRUNTIME_DATABASE_H +#define WRT_ENGINE_SRC_CONFIGURATION_WEBRUNTIME_DATABASE_H + +#include +#include + +extern DPL::Mutex g_wrtDbQueriesMutex; + +#define WRT_DB_INTERNAL(tlsCommand, InternalType, interface) \ + static DPL::ThreadLocalVariable *tlsCommand ## Ptr = NULL; \ + { \ + DPL::Mutex::ScopedLock lock(&g_wrtDbQueriesMutex); \ + if (!tlsCommand ## Ptr) { \ + static DPL::ThreadLocalVariable tmp; \ + tlsCommand ## Ptr = &tmp; \ + } \ + } \ + DPL::ThreadLocalVariable &tlsCommand = *tlsCommand ## Ptr; \ + if (tlsCommand.IsNull()) { tlsCommand = InternalType(interface); } + +#define WRT_DB_SELECT(name, type, interface) WRT_DB_INTERNAL(name, type::Select, interface) + +#define WRT_DB_INSERT(name, type, interface) WRT_DB_INTERNAL(name, type::Insert, interface) + +#define WRT_DB_UPDATE(name, type, interface) WRT_DB_INTERNAL(name, type::Update, interface) + +#define WRT_DB_DELETE(name, type, interface) WRT_DB_INTERNAL(name, type::Delete, interface) + +#endif // WRT_ENGINE_SRC_CONFIGURATION_WEBRUNTIME_DATABASE_H diff --git a/modules/widget_dao/include/dpl/wrt-dao-ro/widget_config.h b/modules/widget_dao/include/dpl/wrt-dao-ro/widget_config.h new file mode 100644 index 0000000..bd1ee00 --- /dev/null +++ b/modules/widget_dao/include/dpl/wrt-dao-ro/widget_config.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file widget_config.h + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief Implementation file for widget config. + */ +#ifndef SRC_DOMAIN_WIDGET_CONFIG_H +#define SRC_DOMAIN_WIDGET_CONFIG_H + +#include +#include + +#include +#include +#include + +namespace WrtDB { +namespace WidgetConfig { + +inline std::string GetWidgetBasePath(DPL::String 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 diff --git a/modules/widget_dao/include/dpl/wrt-dao-ro/widget_dao_read_only.h b/modules/widget_dao/include/dpl/wrt-dao-ro/widget_dao_read_only.h new file mode 100644 index 0000000..9dbd580 --- /dev/null +++ b/modules/widget_dao/include/dpl/wrt-dao-ro/widget_dao_read_only.h @@ -0,0 +1,709 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * This file contains the declaration of widget dao class. + * + * @file widget_dao_read_only.h + * @author Yang Jie (jie2.yang@samsung.com) + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @version 1.0 + * @brief This file contains the declaration of widget dao + */ + +#ifndef _WRT_SRC_CONFIGURATION_WIDGET_DAO_READ_ONLY_H_ +#define _WRT_SRC_CONFIGURATION_WIDGET_DAO_READ_ONLY_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 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 WidgetCertificateDataList; + +typedef DPL::String Locale; +typedef std::set 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 StartFilePropertiesForLocalesMap; + struct LocalizedStartFile + { + DPL::String path; + StartFilePropertiesForLocalesMap propertiesForLocales; + }; + + typedef std::list LocalizedIconList; + typedef std::list 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 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 WidgetCertificateCNList; +typedef std::list LanguageTagList; +typedef std::list HostList; +typedef std::list FingerPrintList; +typedef std::list 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 WidgetLocalizedIconList; + + struct WidgetIconRow + { + int iconId; + int appId; + DPL::String iconSrc; + DPL::OptionalInt iconWidth; + DPL::OptionalInt iconHeight; + }; + typedef std::list WidgetIconList; + + struct WidgetStartFileRow + { + int startFileId; + int appId; + DPL::String src; + }; + typedef std::list WidgetStartFileList; + + struct WidgetLocalizedStartFileRow + { + int startFileId; + int appId; + DPL::String widgetLocale; + DPL::String type; + DPL::String encoding; + }; + typedef std::list LocalizedStartFileList; + + + /** + * This is a constructor. + * + * @param[in] widgetHandle application id of widget. + */ + WidgetDAOReadOnly(DbWidgetHandle widgetHandle); + + /** + * 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_ + diff --git a/modules/widget_dao/include/dpl/wrt-dao-rw/feature_dao.h b/modules/widget_dao/include/dpl/wrt-dao-rw/feature_dao.h new file mode 100644 index 0000000..94b5cb7 --- /dev/null +++ b/modules/widget_dao/include/dpl/wrt-dao-rw/feature_dao.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * This file contains the declaration of feature dao class. + * + * @file feature_dao.h + * @author Jaroslaw Osmanski (j.osmanski@samsung.com) + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @version 1.0 + * @brief This file contains the declaration of feature dao + */ +#ifndef _FEATURE_DAO_H +#define _FEATURE_DAO_H + +#include + +namespace WrtDB { +namespace FeatureDAO { + FeatureHandle RegisterFeature(const PluginMetafileData::Feature &feature, + const DbPluginHandle pluginHandle); + + FeatureHandle RegisterStrangeFeature(const std::string& featureName); +} // namespace FeatureDB +} // namespace WrtDB + +#endif /* _FEATURE_DAO_H */ + diff --git a/modules/widget_dao/include/dpl/wrt-dao-rw/global_dao.h b/modules/widget_dao/include/dpl/wrt-dao-rw/global_dao.h new file mode 100644 index 0000000..51c9f38 --- /dev/null +++ b/modules/widget_dao/include/dpl/wrt-dao-rw/global_dao.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file 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 + +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_ */ diff --git a/modules/widget_dao/include/dpl/wrt-dao-rw/plugin_dao.h b/modules/widget_dao/include/dpl/wrt-dao-rw/plugin_dao.h new file mode 100644 index 0000000..e8a86d3 --- /dev/null +++ b/modules/widget_dao/include/dpl/wrt-dao-rw/plugin_dao.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * This file contains the declaration of plugin dao class. + * + * @file plugin_dao.h + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @version 1.0 + * @brief This file contains the declaration of plugin dao + */ + +#ifndef WRT_SRC_CONFIGURATION_PLUGIN_DAO_H_ +#define WRT_SRC_CONFIGURATION_PLUGIN_DAO_H_ + +#include + +namespace WrtDB { + +class PluginDAO : public PluginDAOReadOnly +{ + public: + PluginDAO(DbPluginHandle pluginHandle); + PluginDAO(const std::string &libraryName); + + static DbPluginHandle registerPlugin( + const PluginMetafileData& metafile, + const std::string& pluginPath); + + static void registerPluginImplementedObject( + const std::string& objectName, + DbPluginHandle pluginHandle); + + static void registerPluginRequiredObject( + const std::string& objectName, + DbPluginHandle pluginHandle); + + static void registerPluginLibrariesDependencies( + DbPluginHandle plugin, + const PluginHandleSetPtr& dependencies); + + static void setPluginInstallationStatus( + DbPluginHandle, + PluginInstallationState); +}; + +} // namespace WrtDB + +#endif /* WRT_SRC_CONFIGURATION_PLUGIN_DAO_H_ */ diff --git a/modules/widget_dao/include/dpl/wrt-dao-rw/property_dao.h b/modules/widget_dao/include/dpl/wrt-dao-rw/property_dao.h new file mode 100644 index 0000000..d75dc59 --- /dev/null +++ b/modules/widget_dao/include/dpl/wrt-dao-rw/property_dao.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file property_dao.h + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @version 1.0 + * @brief This file contains the declaration of property dao + */ + +#ifndef WRT_SRC_CONFIGURATION_PROPERTY_DAO_H_ +#define WRT_SRC_CONFIGURATION_PROPERTY_DAO_H_ + +#include + +namespace WrtDB { + +struct WidgetRegisterInfo; //forward declaration + +namespace PropertyDAO { + +void RemoveProperty(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_ */ diff --git a/modules/widget_dao/include/dpl/wrt-dao-rw/widget_dao.h b/modules/widget_dao/include/dpl/wrt-dao-rw/widget_dao.h new file mode 100644 index 0000000..1b8b507 --- /dev/null +++ b/modules/widget_dao/include/dpl/wrt-dao-rw/widget_dao.h @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * This file contains the declaration of widget dao class. + * + * @file widget_dao.h + * @author Yang Jie (jie2.yang@samsung.com) + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @version 1.0 + * @brief This file contains the declaration of widget dao + */ +#ifndef WIDGET_DAO_H +#define WIDGET_DAO_H + +#include +#include +#include +#include +#include +#include +#include + +namespace WrtDB { + +class WidgetDAO : public WidgetDAOReadOnly +{ + public: + typedef std::list 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 diff --git a/modules/widget_dao/orm/gen_db_md5.sh b/modules/widget_dao/orm/gen_db_md5.sh new file mode 100755 index 0000000..38587b7 --- /dev/null +++ b/modules/widget_dao/orm/gen_db_md5.sh @@ -0,0 +1,19 @@ +#!/bin/sh +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +CHECKSUM=`cat ${2} ${3} 2>/dev/null | md5sum 2>/dev/null | cut -d\ -f1 2>/dev/null` +echo "#define DB_CHECKSUM DB_VERSION_${CHECKSUM}" > ${1} +echo "#define DB_CHECKSUM_STR \"DB_VERSION_${CHECKSUM}\"" >> ${1} + diff --git a/modules/widget_dao/orm/iana_db b/modules/widget_dao/orm/iana_db new file mode 100644 index 0000000..ffd41ea --- /dev/null +++ b/modules/widget_dao/orm/iana_db @@ -0,0 +1,8957 @@ +SQL(BEGIN IMMEDIATE TRANSACTION;) +CREATE_TABLE(iana_records) + COLUMN_NOT_NULL(REC_ID, INT,) + COLUMN_NOT_NULL(TYPE, INT,) + COLUMN(TAG, VARCHAR(256),) + COLUMN(SUBTAG, VARCHAR(256),) + COLUMN(DESCRIPTION, VARCHAR(256),) + COLUMN(ADDED, VARCHAR(256),) + COLUMN(DEPRECATED, INT,) + COLUMN(PREFERRED_VALUE, INT,) + COLUMN(PREFIX, VARCHAR(256),) + COLUMN(SUPPRESS_SCRIPT, VARCHAR(256),) + COLUMN(MACRO_LANGUAGE, VARCHAR(256),) + COLUMN(SCOPE, VARCHAR(256),) + COLUMN(COMMENTS, VARCHAR(256),) +CREATE_TABLE_END() +SQL( +INSERT INTO "iana_records" VALUES(0,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1,0,NULL,'aa','afar','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2,0,NULL,'ab','abkhazian','1129420800',NULL,NULL,NULL,'cyrl',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3,0,NULL,'ae','avestan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4,0,NULL,'af','afrikaans','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5,0,NULL,'ak','akan','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(6,0,NULL,'am','amharic','1129420800',NULL,NULL,NULL,'ethi',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7,0,NULL,'an','aragonese','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8,0,NULL,'ar','arabic','1129420800',NULL,NULL,NULL,'arab',NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(9,0,NULL,'as','assamese','1129420800',NULL,NULL,NULL,'beng',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(10,0,NULL,'av','avaric','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(11,0,NULL,'ay','aymara','1129420800',NULL,NULL,NULL,'latn',NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(12,0,NULL,'az','azerbaijani','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(13,0,NULL,'ba','bashkir','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(14,0,NULL,'be','belarusian','1129420800',NULL,NULL,NULL,'cyrl',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(15,0,NULL,'bg','bulgarian','1129420800',NULL,NULL,NULL,'cyrl',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(16,0,NULL,'bh','bihari languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(17,0,NULL,'bi','bislama','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(18,0,NULL,'bm','bambara','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(19,0,NULL,'bn','bengali','1129420800',NULL,NULL,NULL,'beng',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(20,0,NULL,'bo','tibetan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(21,0,NULL,'br','breton','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(22,0,NULL,'bs','bosnian','1129420800',NULL,NULL,NULL,'latn','sh',NULL,NULL); +INSERT INTO "iana_records" VALUES(23,0,NULL,'ca','catalan','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(23,0,NULL,'ca','valencian','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(24,0,NULL,'ce','chechen','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(25,0,NULL,'ch','chamorro','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(26,0,NULL,'co','corsican','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(27,0,NULL,'cr','cree','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(28,0,NULL,'cs','czech','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(29,0,NULL,'cu','church slavic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(29,0,NULL,'cu','church slavonic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(29,0,NULL,'cu','old bulgarian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(29,0,NULL,'cu','old church slavonic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(29,0,NULL,'cu','old slavonic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(30,0,NULL,'cv','chuvash','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(31,0,NULL,'cy','welsh','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(32,0,NULL,'da','danish','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(33,0,NULL,'de','german','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(34,0,NULL,'dv','dhivehi','1129420800',NULL,NULL,NULL,'thaa',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(34,0,NULL,'dv','divehi','1129420800',NULL,NULL,NULL,'thaa',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(34,0,NULL,'dv','maldivian','1129420800',NULL,NULL,NULL,'thaa',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(35,0,NULL,'dz','dzongkha','1129420800',NULL,NULL,NULL,'tibt',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(36,0,NULL,'ee','ewe','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(37,0,NULL,'el','modern greek (1453-)','1129420800',NULL,NULL,NULL,'grek',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(38,0,NULL,'en','english','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(39,0,NULL,'eo','esperanto','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(40,0,NULL,'es','castilian','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(40,0,NULL,'es','spanish','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(41,0,NULL,'et','estonian','1129420800',NULL,NULL,NULL,'latn',NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(42,0,NULL,'eu','basque','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(43,0,NULL,'fa','persian','1129420800',NULL,NULL,NULL,'arab',NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(44,0,NULL,'ff','fulah','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(45,0,NULL,'fi','finnish','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(46,0,NULL,'fj','fijian','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(47,0,NULL,'fo','faroese','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(48,0,NULL,'fr','french','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(49,0,NULL,'fy','western frisian','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(50,0,NULL,'ga','irish','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(51,0,NULL,'gd','gaelic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(51,0,NULL,'gd','scottish gaelic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(52,0,NULL,'gl','galician','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(53,0,NULL,'gn','guarani','1129420800',NULL,NULL,NULL,'latn',NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(54,0,NULL,'gu','gujarati','1129420800',NULL,NULL,NULL,'gujr',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(55,0,NULL,'gv','manx','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(56,0,NULL,'ha','hausa','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(57,0,NULL,'he','hebrew','1129420800',NULL,NULL,NULL,'hebr',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(58,0,NULL,'hi','hindi','1129420800',NULL,NULL,NULL,'deva',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(59,0,NULL,'ho','hiri motu','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(60,0,NULL,'hr','croatian','1129420800',NULL,NULL,NULL,'latn','sh',NULL,NULL); +INSERT INTO "iana_records" VALUES(61,0,NULL,'ht','haitian','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(61,0,NULL,'ht','haitian creole','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(62,0,NULL,'hu','hungarian','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(63,0,NULL,'hy','armenian','1129420800',NULL,NULL,NULL,'armn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(64,0,NULL,'hz','herero','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(65,0,NULL,'ia','interlingua (international auxiliary language association)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(66,0,NULL,'id','indonesian','1129420800',NULL,NULL,NULL,'latn','ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(67,0,NULL,'ie','interlingue','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(67,0,NULL,'ie','occidental','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(68,0,NULL,'ig','igbo','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(69,0,NULL,'ii','nuosu','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(69,0,NULL,'ii','sichuan yi','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(70,0,NULL,'ik','inupiaq','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(71,0,NULL,'in','indonesian','1129420800',599616000,'id',NULL,'latn','ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(72,0,NULL,'io','ido','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(73,0,NULL,'is','icelandic','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(74,0,NULL,'it','italian','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(75,0,NULL,'iu','inuktitut','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(76,0,NULL,'iw','hebrew','1129420800',599616000,'he',NULL,'hebr',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(77,0,NULL,'ja','japanese','1129420800',NULL,NULL,NULL,'jpan',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(78,0,NULL,'ji','yiddish','1129420800',599616000,'yi',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(79,0,NULL,'jv','javanese','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(80,0,NULL,'jw','javanese','1129420800',997660800,'jv',NULL,NULL,NULL,NULL,'published by error in table 1 of iso 639:1988'); +INSERT INTO "iana_records" VALUES(81,0,NULL,'ka','georgian','1129420800',NULL,NULL,NULL,'geor',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(82,0,NULL,'kg','kongo','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(83,0,NULL,'ki','gikuyu','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(83,0,NULL,'ki','kikuyu','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(84,0,NULL,'kj','kuanyama','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(84,0,NULL,'kj','kwanyama','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(85,0,NULL,'kk','kazakh','1129420800',NULL,NULL,NULL,'cyrl',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(86,0,NULL,'kl','greenlandic','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(86,0,NULL,'kl','kalaallisut','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(87,0,NULL,'km','central khmer','1129420800',NULL,NULL,NULL,'khmr',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(88,0,NULL,'kn','kannada','1129420800',NULL,NULL,NULL,'knda',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(89,0,NULL,'ko','korean','1129420800',NULL,NULL,NULL,'kore',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(90,0,NULL,'kr','kanuri','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(91,0,NULL,'ks','kashmiri','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(92,0,NULL,'ku','kurdish','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(93,0,NULL,'kv','komi','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(94,0,NULL,'kw','cornish','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(95,0,NULL,'ky','kirghiz','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(95,0,NULL,'ky','kyrgyz','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(96,0,NULL,'la','latin','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(97,0,NULL,'lb','letzeburgesch','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(97,0,NULL,'lb','luxembourgish','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(98,0,NULL,'lg','ganda','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(99,0,NULL,'li','limburgan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(99,0,NULL,'li','limburger','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(99,0,NULL,'li','limburgish','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(100,0,NULL,'ln','lingala','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(101,0,NULL,'lo','lao','1129420800',NULL,NULL,NULL,'laoo',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(102,0,NULL,'lt','lithuanian','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(103,0,NULL,'lu','luba-katanga','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(104,0,NULL,'lv','latvian','1129420800',NULL,NULL,NULL,'latn',NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(105,0,NULL,'mg','malagasy','1129420800',NULL,NULL,NULL,'latn',NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(106,0,NULL,'mh','marshallese','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(107,0,NULL,'mi','maori','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(108,0,NULL,'mk','macedonian','1129420800',NULL,NULL,NULL,'cyrl',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(109,0,NULL,'ml','malayalam','1129420800',NULL,NULL,NULL,'mlym',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(110,0,NULL,'mn','mongolian','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(111,0,NULL,'mo','moldavian','1129420800',1227312000,'ro',NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(111,0,NULL,'mo','moldovan','1129420800',1227312000,'ro',NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(112,0,NULL,'mr','marathi','1129420800',NULL,NULL,NULL,'deva',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(113,0,NULL,'ms','malay (macrolanguage)','1129420800',NULL,NULL,NULL,'latn',NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(114,0,NULL,'mt','maltese','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(115,0,NULL,'my','burmese','1129420800',NULL,NULL,NULL,'mymr',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(116,0,NULL,'na','nauru','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(117,0,NULL,'nb','norwegian bokmÃ¥l','1129420800',NULL,NULL,NULL,'latn','no',NULL,NULL); +INSERT INTO "iana_records" VALUES(118,0,NULL,'nd','north ndebele','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(119,0,NULL,'ne','nepali','1129420800',NULL,NULL,NULL,'deva',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(120,0,NULL,'ng','ndonga','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(121,0,NULL,'nl','dutch','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(121,0,NULL,'nl','flemish','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(122,0,NULL,'nn','norwegian nynorsk','1129420800',NULL,NULL,NULL,'latn','no',NULL,NULL); +INSERT INTO "iana_records" VALUES(123,0,NULL,'no','norwegian','1129420800',NULL,NULL,NULL,'latn',NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(124,0,NULL,'nr','south ndebele','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(125,0,NULL,'nv','navaho','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(125,0,NULL,'nv','navajo','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(126,0,NULL,'ny','chewa','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(126,0,NULL,'ny','chichewa','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(126,0,NULL,'ny','nyanja','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(127,0,NULL,'oc','occitan (post 1500)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(128,0,NULL,'oj','ojibwa','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(129,0,NULL,'om','oromo','1129420800',NULL,NULL,NULL,'latn',NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(130,0,NULL,'or','oriya','1129420800',NULL,NULL,NULL,'orya',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(131,0,NULL,'os','ossetian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(131,0,NULL,'os','ossetic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(132,0,NULL,'pa','panjabi','1129420800',NULL,NULL,NULL,'guru',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(132,0,NULL,'pa','punjabi','1129420800',NULL,NULL,NULL,'guru',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(133,0,NULL,'pi','pali','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(134,0,NULL,'pl','polish','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(135,0,NULL,'ps','pashto','1129420800',NULL,NULL,NULL,'arab',NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(135,0,NULL,'ps','pushto','1129420800',NULL,NULL,NULL,'arab',NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(136,0,NULL,'pt','portuguese','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(137,0,NULL,'qu','quechua','1129420800',NULL,NULL,NULL,'latn',NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(138,0,NULL,'rm','romansh','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(139,0,NULL,'rn','rundi','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(140,0,NULL,'ro','moldavian','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(140,0,NULL,'ro','moldovan','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(140,0,NULL,'ro','romanian','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(141,0,NULL,'ru','russian','1129420800',NULL,NULL,NULL,'cyrl',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(142,0,NULL,'rw','kinyarwanda','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(143,0,NULL,'sa','sanskrit','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(144,0,NULL,'sc','sardinian','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(145,0,NULL,'sd','sindhi','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(146,0,NULL,'se','northern sami','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(147,0,NULL,'sg','sango','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(148,0,NULL,'sh','serbo-croatian','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage','sr, hr, bs are preferred for most modern uses'); +INSERT INTO "iana_records" VALUES(149,0,NULL,'si','sinhala','1129420800',NULL,NULL,NULL,'sinh',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(149,0,NULL,'si','sinhalese','1129420800',NULL,NULL,NULL,'sinh',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(150,0,NULL,'sk','slovak','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(151,0,NULL,'sl','slovenian','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(152,0,NULL,'sm','samoan','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(153,0,NULL,'sn','shona','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(154,0,NULL,'so','somali','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(155,0,NULL,'sq','albanian','1129420800',NULL,NULL,NULL,'latn',NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(156,0,NULL,'sr','serbian','1129420800',NULL,NULL,NULL,NULL,'sh',NULL,NULL); +INSERT INTO "iana_records" VALUES(157,0,NULL,'ss','swati','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(158,0,NULL,'st','southern sotho','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(159,0,NULL,'su','sundanese','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(160,0,NULL,'sv','swedish','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(161,0,NULL,'sw','swahili (macrolanguage)','1129420800',NULL,NULL,NULL,'latn',NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(162,0,NULL,'ta','tamil','1129420800',NULL,NULL,NULL,'taml',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(163,0,NULL,'te','telugu','1129420800',NULL,NULL,NULL,'telu',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(164,0,NULL,'tg','tajik','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(165,0,NULL,'th','thai','1129420800',NULL,NULL,NULL,'thai',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(166,0,NULL,'ti','tigrinya','1129420800',NULL,NULL,NULL,'ethi',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(167,0,NULL,'tk','turkmen','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(168,0,NULL,'tl','tagalog','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(169,0,NULL,'tn','tswana','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(170,0,NULL,'to','tonga (tonga islands)','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(171,0,NULL,'tr','turkish','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(172,0,NULL,'ts','tsonga','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(173,0,NULL,'tt','tatar','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(174,0,NULL,'tw','twi','1129420800',NULL,NULL,NULL,NULL,'ak',NULL,NULL); +INSERT INTO "iana_records" VALUES(175,0,NULL,'ty','tahitian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(176,0,NULL,'ug','uighur','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(176,0,NULL,'ug','uyghur','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(177,0,NULL,'uk','ukrainian','1129420800',NULL,NULL,NULL,'cyrl',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(178,0,NULL,'ur','urdu','1129420800',NULL,NULL,NULL,'arab',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(179,0,NULL,'uz','uzbek','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(180,0,NULL,'ve','venda','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(181,0,NULL,'vi','vietnamese','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(182,0,NULL,'vo','volapük','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(183,0,NULL,'wa','walloon','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(184,0,NULL,'wo','wolof','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(185,0,NULL,'xh','xhosa','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(186,0,NULL,'yi','yiddish','1129420800',NULL,NULL,NULL,'hebr',NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(187,0,NULL,'yo','yoruba','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(188,0,NULL,'za','chuang','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(188,0,NULL,'za','zhuang','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(189,0,NULL,'zh','chinese','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(190,0,NULL,'zu','zulu','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(191,0,NULL,'aaa','ghotuo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(192,0,NULL,'aab','alumu-tesu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(193,0,NULL,'aac','ari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(194,0,NULL,'aad','amal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(195,0,NULL,'aae','arbëreshë albanian','1248825600',NULL,NULL,NULL,NULL,'sq',NULL,NULL); +INSERT INTO "iana_records" VALUES(196,0,NULL,'aaf','aranadan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(197,0,NULL,'aag','ambrak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(198,0,NULL,'aah','abu'' arapesh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(199,0,NULL,'aai','arifama-miniafia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(200,0,NULL,'aak','ankave','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(201,0,NULL,'aal','afade','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(202,0,NULL,'aam','aramanik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(203,0,NULL,'aan','anambé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(204,0,NULL,'aao','algerian saharan arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(205,0,NULL,'aap','pará arára','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(206,0,NULL,'aaq','eastern abnaki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(207,0,NULL,'aas','aasáx','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(208,0,NULL,'aat','arvanitika albanian','1248825600',NULL,NULL,NULL,NULL,'sq',NULL,NULL); +INSERT INTO "iana_records" VALUES(209,0,NULL,'aau','abau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(210,0,NULL,'aav','austro-asiatic languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(211,0,NULL,'aaw','solong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(212,0,NULL,'aax','mandobo atas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(213,0,NULL,'aaz','amarasi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(214,0,NULL,'aba','abé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(215,0,NULL,'abb','bankon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(216,0,NULL,'abc','ambala ayta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(217,0,NULL,'abd','manide','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(218,0,NULL,'abe','western abnaki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(219,0,NULL,'abf','abai sungai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(220,0,NULL,'abg','abaga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(221,0,NULL,'abh','tajiki arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(222,0,NULL,'abi','abidji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(223,0,NULL,'abj','aka-bea','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(224,0,NULL,'abl','lampung nyo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(225,0,NULL,'abm','abanyom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(226,0,NULL,'abn','abua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(227,0,NULL,'abo','abon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(228,0,NULL,'abp','abellen ayta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(229,0,NULL,'abq','abaza','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(230,0,NULL,'abr','abron','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(231,0,NULL,'abs','ambonese malay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(232,0,NULL,'abt','ambulas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(233,0,NULL,'abu','abure','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(234,0,NULL,'abv','baharna arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(235,0,NULL,'abw','pal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(236,0,NULL,'abx','inabaknon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(237,0,NULL,'aby','aneme wake','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(238,0,NULL,'abz','abui','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(239,0,NULL,'aca','achagua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(240,0,NULL,'acb','Áncá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(241,0,NULL,'acd','gikyode','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(242,0,NULL,'ace','achinese','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(243,0,NULL,'acf','saint lucian creole french','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(244,0,NULL,'ach','acoli','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(245,0,NULL,'aci','aka-cari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(246,0,NULL,'ack','aka-kora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(247,0,NULL,'acl','akar-bale','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(248,0,NULL,'acm','mesopotamian arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(249,0,NULL,'acn','achang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(250,0,NULL,'acp','eastern acipa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(251,0,NULL,'acq','ta''izzi-adeni arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(252,0,NULL,'acr','achi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(253,0,NULL,'acs','acroá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(254,0,NULL,'act','achterhoeks','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(255,0,NULL,'acu','achuar-shiwiar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(256,0,NULL,'acv','achumawi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(257,0,NULL,'acw','hijazi arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(258,0,NULL,'acx','omani arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(259,0,NULL,'acy','cypriot arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(260,0,NULL,'acz','acheron','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(261,0,NULL,'ada','adangme','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(262,0,NULL,'adb','adabe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(263,0,NULL,'add','dzodinka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(264,0,NULL,'ade','adele','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(265,0,NULL,'adf','dhofari arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(266,0,NULL,'adg','andegerebinha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(267,0,NULL,'adh','adhola','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(268,0,NULL,'adi','adi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(269,0,NULL,'adj','adioukrou','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(270,0,NULL,'adl','galo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(271,0,NULL,'adn','adang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(272,0,NULL,'ado','abu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(273,0,NULL,'adp','adap','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(274,0,NULL,'adq','adangbe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(275,0,NULL,'adr','adonara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(276,0,NULL,'ads','adamorobe sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(277,0,NULL,'adt','adnyamathanha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(278,0,NULL,'adu','aduge','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(279,0,NULL,'adw','amundava','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(280,0,NULL,'adx','amdo tibetan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(281,0,NULL,'ady','adygei','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(281,0,NULL,'ady','adyghe','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(282,0,NULL,'adz','adzera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(283,0,NULL,'aea','areba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(284,0,NULL,'aeb','tunisian arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(285,0,NULL,'aec','saidi arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(286,0,NULL,'aed','argentine sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(287,0,NULL,'aee','northeast pashayi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(288,0,NULL,'aek','haeke','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(289,0,NULL,'ael','ambele','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(290,0,NULL,'aem','arem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(291,0,NULL,'aen','armenian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(292,0,NULL,'aeq','aer','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(293,0,NULL,'aer','eastern arrernte','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(294,0,NULL,'aes','alsea','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(295,0,NULL,'aeu','akeu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(296,0,NULL,'aew','ambakich','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(297,0,NULL,'aey','amele','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(298,0,NULL,'aez','aeka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(299,0,NULL,'afa','afro-asiatic languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(300,0,NULL,'afb','gulf arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(301,0,NULL,'afd','andai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(302,0,NULL,'afe','putukwam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(303,0,NULL,'afg','afghan sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(304,0,NULL,'afh','afrihili','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(305,0,NULL,'afi','akrukay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(306,0,NULL,'afk','nanubae','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(307,0,NULL,'afn','defaka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(308,0,NULL,'afo','eloyi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(309,0,NULL,'afp','tapei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(310,0,NULL,'afs','afro-seminole creole','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(311,0,NULL,'aft','afitti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(312,0,NULL,'afu','awutu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(313,0,NULL,'afz','obokuitai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(314,0,NULL,'aga','aguano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(315,0,NULL,'agb','legbo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(316,0,NULL,'agc','agatu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(317,0,NULL,'agd','agarabi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(318,0,NULL,'age','angal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(319,0,NULL,'agf','arguni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(320,0,NULL,'agg','angor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(321,0,NULL,'agh','ngelima','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(322,0,NULL,'agi','agariya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(323,0,NULL,'agj','argobba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(324,0,NULL,'agk','isarog agta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(325,0,NULL,'agl','fembe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(326,0,NULL,'agm','angaataha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(327,0,NULL,'agn','agutaynen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(328,0,NULL,'ago','tainae','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(329,0,NULL,'agp','paranan','1248825600',1268265600,NULL,NULL,NULL,NULL,NULL,'see apf, prf'); +INSERT INTO "iana_records" VALUES(330,0,NULL,'agq','aghem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(331,0,NULL,'agr','aguaruna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(332,0,NULL,'ags','esimbi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(333,0,NULL,'agt','central cagayan agta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(334,0,NULL,'agu','aguacateco','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(335,0,NULL,'agv','remontado dumagat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(336,0,NULL,'agw','kahua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(337,0,NULL,'agx','aghul','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(338,0,NULL,'agy','southern alta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(339,0,NULL,'agz','mt. iriga agta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(340,0,NULL,'aha','ahanta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(341,0,NULL,'ahb','axamb','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(342,0,NULL,'ahg','qimant','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(343,0,NULL,'ahh','aghu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(344,0,NULL,'ahi','tiagbamrin aizi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(345,0,NULL,'ahk','akha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(346,0,NULL,'ahl','igo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(347,0,NULL,'ahm','mobumrin aizi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(348,0,NULL,'ahn','Àhàn','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(349,0,NULL,'aho','ahom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(350,0,NULL,'ahp','aproumu aizi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(351,0,NULL,'ahr','ahirani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(352,0,NULL,'ahs','ashe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(353,0,NULL,'aht','ahtena','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(354,0,NULL,'aia','arosi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(355,0,NULL,'aib','ainu (china)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(356,0,NULL,'aic','ainbai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(357,0,NULL,'aid','alngith','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(358,0,NULL,'aie','amara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(359,0,NULL,'aif','agi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(360,0,NULL,'aig','antigua and barbuda creole english','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(361,0,NULL,'aih','ai-cham','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(362,0,NULL,'aii','assyrian neo-aramaic','1248825600',NULL,NULL,NULL,NULL,'syr',NULL,NULL); +INSERT INTO "iana_records" VALUES(363,0,NULL,'aij','lishanid noshan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(364,0,NULL,'aik','ake','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(365,0,NULL,'ail','aimele','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(366,0,NULL,'aim','aimol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(367,0,NULL,'ain','ainu (japan)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(368,0,NULL,'aio','aiton','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(369,0,NULL,'aip','burumakok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(370,0,NULL,'aiq','aimaq','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(371,0,NULL,'air','airoran','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(372,0,NULL,'ais','nataoran amis','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(373,0,NULL,'ait','arikem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(374,0,NULL,'aiw','aari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(375,0,NULL,'aix','aighon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(376,0,NULL,'aiy','ali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(377,0,NULL,'aja','aja (sudan)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(378,0,NULL,'ajg','aja (benin)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(379,0,NULL,'aji','ajië','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(380,0,NULL,'ajp','south levantine arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(381,0,NULL,'ajt','judeo-tunisian arabic','1248825600',NULL,NULL,NULL,NULL,'jrb',NULL,NULL); +INSERT INTO "iana_records" VALUES(382,0,NULL,'aju','judeo-moroccan arabic','1248825600',NULL,NULL,NULL,NULL,'jrb',NULL,NULL); +INSERT INTO "iana_records" VALUES(383,0,NULL,'ajw','ajawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(384,0,NULL,'ajz','amri karbi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(385,0,NULL,'akb','batak angkola','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(386,0,NULL,'akc','mpur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(387,0,NULL,'akd','ukpet-ehom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(388,0,NULL,'ake','akawaio','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(389,0,NULL,'akf','akpa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(390,0,NULL,'akg','anakalangu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(391,0,NULL,'akh','angal heneng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(392,0,NULL,'aki','aiome','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(393,0,NULL,'akj','aka-jeru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(394,0,NULL,'akk','akkadian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(395,0,NULL,'akl','aklanon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(396,0,NULL,'akm','aka-bo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(397,0,NULL,'ako','akurio','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(398,0,NULL,'akp','siwu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(399,0,NULL,'akq','ak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(400,0,NULL,'akr','araki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(401,0,NULL,'aks','akaselem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(402,0,NULL,'akt','akolet','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(403,0,NULL,'aku','akum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(404,0,NULL,'akv','akhvakh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(405,0,NULL,'akw','akwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(406,0,NULL,'akx','aka-kede','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(407,0,NULL,'aky','aka-kol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(408,0,NULL,'akz','alabama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(409,0,NULL,'ala','alago','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(410,0,NULL,'alc','qawasqar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(411,0,NULL,'ald','alladian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(412,0,NULL,'ale','aleut','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(413,0,NULL,'alf','alege','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(414,0,NULL,'alg','algonquian languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(415,0,NULL,'alh','alawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(416,0,NULL,'ali','amaimon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(417,0,NULL,'alj','alangan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(418,0,NULL,'alk','alak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(419,0,NULL,'all','allar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(420,0,NULL,'alm','amblong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(421,0,NULL,'aln','gheg albanian','1248825600',NULL,NULL,NULL,NULL,'sq',NULL,NULL); +INSERT INTO "iana_records" VALUES(422,0,NULL,'alo','larike-wakasihu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(423,0,NULL,'alp','alune','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(424,0,NULL,'alq','algonquin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(425,0,NULL,'alr','alutor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(426,0,NULL,'als','tosk albanian','1248825600',NULL,NULL,NULL,NULL,'sq',NULL,NULL); +INSERT INTO "iana_records" VALUES(427,0,NULL,'alt','southern altai','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(428,0,NULL,'alu','''are''are','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(429,0,NULL,'alv','atlantic-congo languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(430,0,NULL,'alw','alaba-k’abeena','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(430,0,NULL,'alw','wanbasana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(431,0,NULL,'alx','amol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(432,0,NULL,'aly','alyawarr','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(433,0,NULL,'alz','alur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(434,0,NULL,'ama','amanayé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(435,0,NULL,'amb','ambo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(436,0,NULL,'amc','amahuaca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(437,0,NULL,'ame','yanesha''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(438,0,NULL,'amf','hamer-banna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(439,0,NULL,'amg','amarag','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(440,0,NULL,'ami','amis','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(441,0,NULL,'amj','amdang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(442,0,NULL,'amk','ambai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(443,0,NULL,'aml','war-jaintia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(444,0,NULL,'amm','ama (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(445,0,NULL,'amn','amanab','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(446,0,NULL,'amo','amo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(447,0,NULL,'amp','alamblak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(448,0,NULL,'amq','amahai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(449,0,NULL,'amr','amarakaeri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(450,0,NULL,'ams','southern amami-oshima','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(451,0,NULL,'amt','amto','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(452,0,NULL,'amu','guerrero amuzgo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(453,0,NULL,'amv','ambelau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(454,0,NULL,'amw','western neo-aramaic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(455,0,NULL,'amx','anmatyerre','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(456,0,NULL,'amy','ami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(457,0,NULL,'amz','atampaya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(458,0,NULL,'ana','andaqui','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(459,0,NULL,'anb','andoa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(460,0,NULL,'anc','ngas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(461,0,NULL,'and','ansus','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(462,0,NULL,'ane','xârâcùù','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(463,0,NULL,'anf','animere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(464,0,NULL,'ang','old english (ca. 450-1100)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(465,0,NULL,'anh','nend','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(466,0,NULL,'ani','andi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(467,0,NULL,'anj','anor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(468,0,NULL,'ank','goemai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(469,0,NULL,'anl','anu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(470,0,NULL,'anm','anal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(471,0,NULL,'ann','obolo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(472,0,NULL,'ano','andoque','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(473,0,NULL,'anp','angika','1141776000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(474,0,NULL,'anq','jarawa (india)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(475,0,NULL,'anr','andh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(476,0,NULL,'ans','anserma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(477,0,NULL,'ant','antakarinya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(478,0,NULL,'anu','anuak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(479,0,NULL,'anv','denya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(480,0,NULL,'anw','anaang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(481,0,NULL,'anx','andra-hus','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(482,0,NULL,'any','anyin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(483,0,NULL,'anz','anem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(484,0,NULL,'aoa','angolar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(485,0,NULL,'aob','abom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(486,0,NULL,'aoc','pemon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(487,0,NULL,'aod','andarum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(488,0,NULL,'aoe','angal enen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(489,0,NULL,'aof','bragat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(490,0,NULL,'aog','angoram','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(491,0,NULL,'aoh','arma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(492,0,NULL,'aoi','anindilyakwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(493,0,NULL,'aoj','mufian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(494,0,NULL,'aok','arhö','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(495,0,NULL,'aol','alor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(496,0,NULL,'aom','Ömie','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(497,0,NULL,'aon','bumbita arapesh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(498,0,NULL,'aor','aore','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(499,0,NULL,'aos','taikat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(500,0,NULL,'aot','a''tong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(501,0,NULL,'aox','atorada','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(502,0,NULL,'aoz','uab meto','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(503,0,NULL,'apa','apache languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(504,0,NULL,'apb','sa''a','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(505,0,NULL,'apc','north levantine arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(506,0,NULL,'apd','sudanese arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(507,0,NULL,'ape','bukiyip','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(508,0,NULL,'apf','pahanan agta','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(509,0,NULL,'apg','ampanang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(510,0,NULL,'aph','athpariya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(511,0,NULL,'api','apiaká','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(512,0,NULL,'apj','jicarilla apache','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(513,0,NULL,'apk','kiowa apache','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(514,0,NULL,'apl','lipan apache','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(515,0,NULL,'apm','mescalero-chiricahua apache','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(516,0,NULL,'apn','apinayé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(517,0,NULL,'apo','apalik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(518,0,NULL,'app','apma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(519,0,NULL,'apq','a-pucikwar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(520,0,NULL,'apr','arop-lokep','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(521,0,NULL,'aps','arop-sissano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(522,0,NULL,'apt','apatani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(523,0,NULL,'apu','apurinã','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(524,0,NULL,'apv','alapmunte','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(525,0,NULL,'apw','western apache','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(526,0,NULL,'apx','aputai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(527,0,NULL,'apy','apalaí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(528,0,NULL,'apz','safeyoka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(529,0,NULL,'aqa','alacalufan languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(530,0,NULL,'aqc','archi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(531,0,NULL,'aqg','arigidi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(532,0,NULL,'aql','algic languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(533,0,NULL,'aqm','atohwaim','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(534,0,NULL,'aqn','northern alta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(535,0,NULL,'aqp','atakapa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(536,0,NULL,'aqr','arhâ','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(537,0,NULL,'aqz','akuntsu','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(538,0,NULL,'arb','standard arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(539,0,NULL,'arc','imperial aramaic (700-300 bce)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(539,0,NULL,'arc','official aramaic (700-300 bce)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(540,0,NULL,'ard','arabana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(541,0,NULL,'are','western arrarnta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(542,0,NULL,'arh','arhuaco','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(543,0,NULL,'ari','arikara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(544,0,NULL,'arj','arapaso','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(545,0,NULL,'ark','arikapú','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(546,0,NULL,'arl','arabela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(547,0,NULL,'arn','mapuche','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(547,0,NULL,'arn','mapudungun','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(548,0,NULL,'aro','araona','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(549,0,NULL,'arp','arapaho','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(550,0,NULL,'arq','algerian arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(551,0,NULL,'arr','karo (brazil)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(552,0,NULL,'ars','najdi arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(553,0,NULL,'art','artificial languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(554,0,NULL,'aru','arawá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(554,0,NULL,'aru','aruá (amazonas state)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(555,0,NULL,'arv','arbore','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(556,0,NULL,'arw','arawak','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(557,0,NULL,'arx','aruá (rodonia state)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(558,0,NULL,'ary','moroccan arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(559,0,NULL,'arz','egyptian arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(560,0,NULL,'asa','asu (tanzania)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(561,0,NULL,'asb','assiniboine','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(562,0,NULL,'asc','casuarina coast asmat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(563,0,NULL,'asd','asas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(564,0,NULL,'ase','american sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(565,0,NULL,'asf','australian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(566,0,NULL,'asg','cishingini','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(567,0,NULL,'ash','abishira','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(568,0,NULL,'asi','buruwai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(569,0,NULL,'asj','nsari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(570,0,NULL,'ask','ashkun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(571,0,NULL,'asl','asilulu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(572,0,NULL,'asn','xingú asuriní','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(573,0,NULL,'aso','dano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(574,0,NULL,'asp','algerian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(575,0,NULL,'asq','austrian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(576,0,NULL,'asr','asuri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(577,0,NULL,'ass','ipulo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(578,0,NULL,'ast','asturian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(578,0,NULL,'ast','asturleonese','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(578,0,NULL,'ast','bable','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(578,0,NULL,'ast','leonese','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(579,0,NULL,'asu','tocantins asurini','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(580,0,NULL,'asv','asoa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(581,0,NULL,'asw','australian aborigines sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(582,0,NULL,'asx','muratayak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(583,0,NULL,'asy','yaosakor asmat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(584,0,NULL,'asz','as','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(585,0,NULL,'ata','pele-ata','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(586,0,NULL,'atb','zaiwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(587,0,NULL,'atc','atsahuaca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(588,0,NULL,'atd','ata manobo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(589,0,NULL,'ate','atemble','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(590,0,NULL,'atg','ivbie north-okpela-arhe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(591,0,NULL,'ath','athapascan languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(592,0,NULL,'ati','attié','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(593,0,NULL,'atj','atikamekw','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(594,0,NULL,'atk','ati','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(595,0,NULL,'atl','mt. iraya agta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(596,0,NULL,'atm','ata','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(597,0,NULL,'atn','ashtiani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(598,0,NULL,'ato','atong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(599,0,NULL,'atp','pudtol atta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(600,0,NULL,'atq','aralle-tabulahan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(601,0,NULL,'atr','waimiri-atroari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(602,0,NULL,'ats','gros ventre','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(603,0,NULL,'att','pamplona atta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(604,0,NULL,'atu','reel','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(605,0,NULL,'atv','northern altai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(606,0,NULL,'atw','atsugewi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(607,0,NULL,'atx','arutani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(608,0,NULL,'aty','aneityum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(609,0,NULL,'atz','arta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(610,0,NULL,'aua','asumboa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(611,0,NULL,'aub','alugu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(612,0,NULL,'auc','waorani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(613,0,NULL,'aud','anuta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(614,0,NULL,'aue','=/kx''au//''ein','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(615,0,NULL,'auf','arauan languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(616,0,NULL,'aug','aguna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(617,0,NULL,'auh','aushi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(618,0,NULL,'aui','anuki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(619,0,NULL,'auj','awjilah','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(620,0,NULL,'auk','heyo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(621,0,NULL,'aul','aulua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(622,0,NULL,'aum','asu (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(623,0,NULL,'aun','molmo one','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(624,0,NULL,'auo','auyokawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(625,0,NULL,'aup','makayam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(626,0,NULL,'auq','anus','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(626,0,NULL,'auq','korur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(627,0,NULL,'aur','aruek','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(628,0,NULL,'aus','australian languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(629,0,NULL,'aut','austral','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(630,0,NULL,'auu','auye','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(631,0,NULL,'auw','awyi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(632,0,NULL,'aux','aurá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(633,0,NULL,'auy','awiyaana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(634,0,NULL,'auz','uzbeki arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(635,0,NULL,'avb','avau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(636,0,NULL,'avd','alviri-vidari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(637,0,NULL,'avi','avikam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(638,0,NULL,'avk','kotava','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(639,0,NULL,'avl','eastern egyptian bedawi arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(640,0,NULL,'avn','avatime','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(641,0,NULL,'avo','agavotaguerra','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(642,0,NULL,'avs','aushiri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(643,0,NULL,'avt','au','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(644,0,NULL,'avu','avokaya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(645,0,NULL,'avv','avá-canoeiro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(646,0,NULL,'awa','awadhi','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(647,0,NULL,'awb','awa (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(648,0,NULL,'awc','cicipu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(649,0,NULL,'awd','arawakan languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(650,0,NULL,'awe','awetí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(651,0,NULL,'awh','awbono','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(652,0,NULL,'awi','aekyom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(653,0,NULL,'awk','awabakal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(654,0,NULL,'awm','arawum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(655,0,NULL,'awn','awngi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(656,0,NULL,'awo','awak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(657,0,NULL,'awr','awera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(658,0,NULL,'aws','south awyu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(659,0,NULL,'awt','araweté','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(660,0,NULL,'awu','central awyu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(661,0,NULL,'awv','jair awyu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(662,0,NULL,'aww','awun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(663,0,NULL,'awx','awara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(664,0,NULL,'awy','edera awyu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(665,0,NULL,'axb','abipon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(666,0,NULL,'axg','mato grosso arára','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(667,0,NULL,'axk','yaka (central african republic)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(668,0,NULL,'axm','middle armenian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(669,0,NULL,'axx','xaragure','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(670,0,NULL,'aya','awar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(671,0,NULL,'ayb','ayizo gbe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(672,0,NULL,'ayc','southern aymara','1248825600',NULL,NULL,NULL,NULL,'ay',NULL,NULL); +INSERT INTO "iana_records" VALUES(673,0,NULL,'ayd','ayabadhu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(674,0,NULL,'aye','ayere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(675,0,NULL,'ayg','ginyanga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(676,0,NULL,'ayh','hadrami arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(677,0,NULL,'ayi','leyigha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(678,0,NULL,'ayk','akuku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(679,0,NULL,'ayl','libyan arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(680,0,NULL,'ayn','sanaani arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(681,0,NULL,'ayo','ayoreo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(682,0,NULL,'ayp','north mesopotamian arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(683,0,NULL,'ayq','ayi (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(684,0,NULL,'ayr','central aymara','1248825600',NULL,NULL,NULL,NULL,'ay',NULL,NULL); +INSERT INTO "iana_records" VALUES(685,0,NULL,'ays','sorsogon ayta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(686,0,NULL,'ayt','magbukun ayta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(687,0,NULL,'ayu','ayu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(688,0,NULL,'ayx','ayi (china)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(689,0,NULL,'ayy','tayabas ayta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(690,0,NULL,'ayz','mai brat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(691,0,NULL,'aza','azha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(692,0,NULL,'azb','south azerbaijani','1248825600',NULL,NULL,NULL,NULL,'az',NULL,NULL); +INSERT INTO "iana_records" VALUES(693,0,NULL,'azc','uto-aztecan languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(694,0,NULL,'azg','san pedro amuzgos amuzgo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(695,0,NULL,'azj','north azerbaijani','1248825600',NULL,NULL,NULL,NULL,'az',NULL,NULL); +INSERT INTO "iana_records" VALUES(696,0,NULL,'azm','ipalapa amuzgo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(697,0,NULL,'azo','awing','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(698,0,NULL,'azt','faire atta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(699,0,NULL,'azz','highland puebla nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(700,0,NULL,'baa','babatana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(701,0,NULL,'bab','bainouk-gunyuño','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(702,0,NULL,'bac','badui','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(703,0,NULL,'bad','banda languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(704,0,NULL,'bae','baré','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(705,0,NULL,'baf','nubaca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(706,0,NULL,'bag','tuki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(707,0,NULL,'bah','bahamas creole english','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(708,0,NULL,'bai','bamileke languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(709,0,NULL,'baj','barakai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(710,0,NULL,'bal','baluchi','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(711,0,NULL,'ban','balinese','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(712,0,NULL,'bao','waimaha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(713,0,NULL,'bap','bantawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(714,0,NULL,'bar','bavarian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(715,0,NULL,'bas','basa (cameroon)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(716,0,NULL,'bat','baltic languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(717,0,NULL,'bau','bada (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(718,0,NULL,'bav','vengo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(719,0,NULL,'baw','bambili-bambui','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(720,0,NULL,'bax','bamun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(721,0,NULL,'bay','batuley','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(722,0,NULL,'baz','tunen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(723,0,NULL,'bba','baatonum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(724,0,NULL,'bbb','barai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(725,0,NULL,'bbc','batak toba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(726,0,NULL,'bbd','bau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(727,0,NULL,'bbe','bangba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(728,0,NULL,'bbf','baibai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(729,0,NULL,'bbg','barama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(730,0,NULL,'bbh','bugan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(731,0,NULL,'bbi','barombi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(732,0,NULL,'bbj','ghomálá''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(733,0,NULL,'bbk','babanki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(734,0,NULL,'bbl','bats','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(735,0,NULL,'bbm','babango','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(736,0,NULL,'bbn','uneapa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(737,0,NULL,'bbo','konabéré','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(737,0,NULL,'bbo','northern bobo madaré','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(738,0,NULL,'bbp','west central banda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(739,0,NULL,'bbq','bamali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(740,0,NULL,'bbr','girawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(741,0,NULL,'bbs','bakpinka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(742,0,NULL,'bbt','mburku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(743,0,NULL,'bbu','kulung (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(744,0,NULL,'bbv','karnai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(745,0,NULL,'bbw','baba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(746,0,NULL,'bbx','bubia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(747,0,NULL,'bby','befang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(748,0,NULL,'bbz','babalia creole arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(749,0,NULL,'bca','central bai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(750,0,NULL,'bcb','bainouk-samik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(751,0,NULL,'bcc','southern balochi','1248825600',NULL,NULL,NULL,NULL,'bal',NULL,NULL); +INSERT INTO "iana_records" VALUES(752,0,NULL,'bcd','north babar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(753,0,NULL,'bce','bamenyam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(754,0,NULL,'bcf','bamu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(755,0,NULL,'bcg','baga binari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(756,0,NULL,'bch','bariai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(757,0,NULL,'bci','baoulé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(758,0,NULL,'bcj','bardi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(759,0,NULL,'bck','bunaba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(760,0,NULL,'bcl','central bicolano','1248825600',NULL,NULL,NULL,NULL,'bik',NULL,NULL); +INSERT INTO "iana_records" VALUES(761,0,NULL,'bcm','bannoni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(762,0,NULL,'bcn','bali (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(763,0,NULL,'bco','kaluli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(764,0,NULL,'bcp','bali (democratic republic of congo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(765,0,NULL,'bcq','bench','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(766,0,NULL,'bcr','babine','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(767,0,NULL,'bcs','kohumono','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(768,0,NULL,'bct','bendi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(769,0,NULL,'bcu','awad bing','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(770,0,NULL,'bcv','shoo-minda-nye','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(771,0,NULL,'bcw','bana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(772,0,NULL,'bcy','bacama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(773,0,NULL,'bcz','bainouk-gunyaamolo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(774,0,NULL,'bda','bayot','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(775,0,NULL,'bdb','basap','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(776,0,NULL,'bdc','emberá-baudó','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(777,0,NULL,'bdd','bunama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(778,0,NULL,'bde','bade','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(779,0,NULL,'bdf','biage','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(780,0,NULL,'bdg','bonggi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(781,0,NULL,'bdh','baka (sudan)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(782,0,NULL,'bdi','burun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(783,0,NULL,'bdj','bai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(784,0,NULL,'bdk','budukh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(785,0,NULL,'bdl','indonesian bajau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(786,0,NULL,'bdm','buduma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(787,0,NULL,'bdn','baldemu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(788,0,NULL,'bdo','morom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(789,0,NULL,'bdp','bende','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(790,0,NULL,'bdq','bahnar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(791,0,NULL,'bdr','west coast bajau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(792,0,NULL,'bds','burunge','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(793,0,NULL,'bdt','bokoto','1248825600',NULL,NULL,NULL,NULL,'gba',NULL,NULL); +INSERT INTO "iana_records" VALUES(794,0,NULL,'bdu','oroko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(795,0,NULL,'bdv','bodo parja','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(796,0,NULL,'bdw','baham','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(797,0,NULL,'bdx','budong-budong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(798,0,NULL,'bdy','bandjalang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(799,0,NULL,'bdz','badeshi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(800,0,NULL,'bea','beaver','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(801,0,NULL,'beb','bebele','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(802,0,NULL,'bec','iceve-maci','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(803,0,NULL,'bed','bedoanas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(804,0,NULL,'bee','byangsi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(805,0,NULL,'bef','benabena','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(806,0,NULL,'beg','belait','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(807,0,NULL,'beh','biali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(808,0,NULL,'bei','bekati''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(809,0,NULL,'bej','bedawiyet','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(809,0,NULL,'bej','beja','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(810,0,NULL,'bek','bebeli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(811,0,NULL,'bem','bemba (zambia)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(812,0,NULL,'beo','beami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(813,0,NULL,'bep','besoa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(814,0,NULL,'beq','beembe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(815,0,NULL,'ber','berber languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(816,0,NULL,'bes','besme','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(817,0,NULL,'bet','guiberoua béte','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(818,0,NULL,'beu','blagar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(819,0,NULL,'bev','daloa bété','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(820,0,NULL,'bew','betawi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(821,0,NULL,'bex','jur modo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(822,0,NULL,'bey','beli (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(823,0,NULL,'bez','bena (tanzania)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(824,0,NULL,'bfa','bari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(825,0,NULL,'bfb','pauri bareli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(826,0,NULL,'bfc','northern bai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(827,0,NULL,'bfd','bafut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(828,0,NULL,'bfe','betaf','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(828,0,NULL,'bfe','tena','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(829,0,NULL,'bff','bofi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(830,0,NULL,'bfg','busang kayan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(831,0,NULL,'bfh','blafe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(832,0,NULL,'bfi','british sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(833,0,NULL,'bfj','bafanji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(834,0,NULL,'bfk','ban khor sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(835,0,NULL,'bfl','banda-ndélé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(836,0,NULL,'bfm','mmen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(837,0,NULL,'bfn','bunak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(838,0,NULL,'bfo','malba birifor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(839,0,NULL,'bfp','beba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(840,0,NULL,'bfq','badaga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(841,0,NULL,'bfr','bazigar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(842,0,NULL,'bfs','southern bai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(843,0,NULL,'bft','balti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(844,0,NULL,'bfu','gahri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(845,0,NULL,'bfw','bondo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(846,0,NULL,'bfx','bantayanon','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(847,0,NULL,'bfy','bagheli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(848,0,NULL,'bfz','mahasu pahari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(849,0,NULL,'bga','gwamhi-wuri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(850,0,NULL,'bgb','bobongko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(851,0,NULL,'bgc','haryanvi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(852,0,NULL,'bgd','rathwi bareli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(853,0,NULL,'bge','bauria','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(854,0,NULL,'bgf','bangandu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(855,0,NULL,'bgg','bugun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(856,0,NULL,'bgi','giangan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(857,0,NULL,'bgj','bangolan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(858,0,NULL,'bgk','bit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(858,0,NULL,'bgk','buxinhua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(859,0,NULL,'bgl','bo (laos)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(860,0,NULL,'bgm','baga mboteni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(861,0,NULL,'bgn','western balochi','1248825600',NULL,NULL,NULL,NULL,'bal',NULL,NULL); +INSERT INTO "iana_records" VALUES(862,0,NULL,'bgo','baga koga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(863,0,NULL,'bgp','eastern balochi','1248825600',NULL,NULL,NULL,NULL,'bal',NULL,NULL); +INSERT INTO "iana_records" VALUES(864,0,NULL,'bgq','bagri','1248825600',NULL,NULL,NULL,NULL,'raj',NULL,NULL); +INSERT INTO "iana_records" VALUES(865,0,NULL,'bgr','bawm chin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(866,0,NULL,'bgs','tagabawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(867,0,NULL,'bgt','bughotu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(868,0,NULL,'bgu','mbongno','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(869,0,NULL,'bgv','warkay-bipim','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(870,0,NULL,'bgw','bhatri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(871,0,NULL,'bgx','balkan gagauz turkish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(872,0,NULL,'bgy','benggoi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(873,0,NULL,'bgz','banggai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(874,0,NULL,'bha','bharia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(875,0,NULL,'bhb','bhili','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(876,0,NULL,'bhc','biga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(877,0,NULL,'bhd','bhadrawahi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(878,0,NULL,'bhe','bhaya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(879,0,NULL,'bhf','odiai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(880,0,NULL,'bhg','binandere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(881,0,NULL,'bhh','bukharic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(882,0,NULL,'bhi','bhilali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(883,0,NULL,'bhj','bahing','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(884,0,NULL,'bhk','albay bicolano','1248825600',1268265600,NULL,NULL,NULL,'bik',NULL,'see fbl, lbl, rbl, ubl'); +INSERT INTO "iana_records" VALUES(885,0,NULL,'bhl','bimin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(886,0,NULL,'bhm','bathari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(887,0,NULL,'bhn','bohtan neo-aramaic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(888,0,NULL,'bho','bhojpuri','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(889,0,NULL,'bhp','bima','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(890,0,NULL,'bhq','tukang besi south','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(891,0,NULL,'bhr','bara malagasy','1248825600',NULL,NULL,NULL,NULL,'mg',NULL,NULL); +INSERT INTO "iana_records" VALUES(892,0,NULL,'bhs','buwal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(893,0,NULL,'bht','bhattiyali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(894,0,NULL,'bhu','bhunjia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(895,0,NULL,'bhv','bahau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(896,0,NULL,'bhw','biak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(897,0,NULL,'bhx','bhalay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(898,0,NULL,'bhy','bhele','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(899,0,NULL,'bhz','bada (indonesia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(900,0,NULL,'bia','badimaya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(901,0,NULL,'bib','bissa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(902,0,NULL,'bic','bikaru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(903,0,NULL,'bid','bidiyo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(904,0,NULL,'bie','bepour','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(905,0,NULL,'bif','biafada','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(906,0,NULL,'big','biangai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(907,0,NULL,'bij','vaghat-ya-bijim-legeri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(908,0,NULL,'bik','bikol','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(909,0,NULL,'bil','bile','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(910,0,NULL,'bim','bimoba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(911,0,NULL,'bin','bini','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(911,0,NULL,'bin','edo','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(912,0,NULL,'bio','nai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(913,0,NULL,'bip','bila','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(914,0,NULL,'biq','bipi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(915,0,NULL,'bir','bisorio','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(916,0,NULL,'bit','berinomo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(917,0,NULL,'biu','biete','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(918,0,NULL,'biv','southern birifor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(919,0,NULL,'biw','kol (cameroon)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(920,0,NULL,'bix','bijori','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(921,0,NULL,'biy','birhor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(922,0,NULL,'biz','baloi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(923,0,NULL,'bja','budza','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(924,0,NULL,'bjb','banggarla','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(925,0,NULL,'bjc','bariji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(926,0,NULL,'bjd','bandjigali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(927,0,NULL,'bje','biao-jiao mien','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(928,0,NULL,'bjf','barzani jewish neo-aramaic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(929,0,NULL,'bjg','bidyogo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(930,0,NULL,'bjh','bahinemo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(931,0,NULL,'bji','burji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(932,0,NULL,'bjj','kanauji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(933,0,NULL,'bjk','barok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(934,0,NULL,'bjl','bulu (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(935,0,NULL,'bjm','bajelani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(936,0,NULL,'bjn','banjar','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(937,0,NULL,'bjo','mid-southern banda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(938,0,NULL,'bjq','southern betsimisaraka malagasy','1248825600',NULL,NULL,NULL,NULL,'mg',NULL,NULL); +INSERT INTO "iana_records" VALUES(939,0,NULL,'bjr','binumarien','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(940,0,NULL,'bjs','bajan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(941,0,NULL,'bjt','balanta-ganja','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(942,0,NULL,'bju','busuu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(943,0,NULL,'bjv','bedjond','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(944,0,NULL,'bjw','bakwé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(945,0,NULL,'bjx','banao itneg','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(946,0,NULL,'bjy','bayali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(947,0,NULL,'bjz','baruga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(948,0,NULL,'bka','kyak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(949,0,NULL,'bkb','finallig','1248825600',1268265600,NULL,NULL,NULL,NULL,NULL,'see ebk, obk'); +INSERT INTO "iana_records" VALUES(950,0,NULL,'bkc','baka (cameroon)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(951,0,NULL,'bkd','binukid','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(951,0,NULL,'bkd','talaandig','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(952,0,NULL,'bkf','beeke','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(953,0,NULL,'bkg','buraka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(954,0,NULL,'bkh','bakoko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(955,0,NULL,'bki','baki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(956,0,NULL,'bkj','pande','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(957,0,NULL,'bkk','brokskat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(958,0,NULL,'bkl','berik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(959,0,NULL,'bkm','kom (cameroon)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(960,0,NULL,'bkn','bukitan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(961,0,NULL,'bko','kwa''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(962,0,NULL,'bkp','boko (democratic republic of congo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(963,0,NULL,'bkq','bakairí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(964,0,NULL,'bkr','bakumpai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(965,0,NULL,'bks','northern sorsoganon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(966,0,NULL,'bkt','boloki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(967,0,NULL,'bku','buhid','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(968,0,NULL,'bkv','bekwarra','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(969,0,NULL,'bkw','bekwil','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(970,0,NULL,'bkx','baikeno','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(971,0,NULL,'bky','bokyi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(972,0,NULL,'bkz','bungku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(973,0,NULL,'bla','siksika','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(974,0,NULL,'blb','bilua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(975,0,NULL,'blc','bella coola','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(976,0,NULL,'bld','bolango','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(977,0,NULL,'ble','balanta-kentohe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(978,0,NULL,'blf','buol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(979,0,NULL,'blg','balau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(980,0,NULL,'blh','kuwaa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(981,0,NULL,'bli','bolia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(982,0,NULL,'blj','bolongan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(983,0,NULL,'blk','pa''o karen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(984,0,NULL,'bll','biloxi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(985,0,NULL,'blm','beli (sudan)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(986,0,NULL,'bln','southern catanduanes bicolano','1248825600',NULL,NULL,NULL,NULL,'bik',NULL,NULL); +INSERT INTO "iana_records" VALUES(987,0,NULL,'blo','anii','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(988,0,NULL,'blp','blablanga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(989,0,NULL,'blq','baluan-pam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(990,0,NULL,'blr','blang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(991,0,NULL,'bls','balaesang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(992,0,NULL,'blt','tai dam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(993,0,NULL,'blv','bolo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(994,0,NULL,'blw','balangao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(995,0,NULL,'blx','mag-indi ayta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(996,0,NULL,'bly','notre','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(997,0,NULL,'blz','balantak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(998,0,NULL,'bma','lame','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(999,0,NULL,'bmb','bembe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1000,0,NULL,'bmc','biem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1001,0,NULL,'bmd','baga manduri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1002,0,NULL,'bme','limassa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1003,0,NULL,'bmf','bom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1004,0,NULL,'bmg','bamwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1005,0,NULL,'bmh','kein','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1006,0,NULL,'bmi','bagirmi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1007,0,NULL,'bmj','bote-majhi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1008,0,NULL,'bmk','ghayavi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1009,0,NULL,'bml','bomboli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1010,0,NULL,'bmm','northern betsimisaraka malagasy','1248825600',NULL,NULL,NULL,NULL,'mg',NULL,NULL); +INSERT INTO "iana_records" VALUES(1011,0,NULL,'bmn','bina (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1012,0,NULL,'bmo','bambalang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1013,0,NULL,'bmp','bulgebi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1014,0,NULL,'bmq','bomu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1015,0,NULL,'bmr','muinane','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1016,0,NULL,'bms','bilma kanuri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1017,0,NULL,'bmt','biao mon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1018,0,NULL,'bmu','burum-mindik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1019,0,NULL,'bmv','bum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1020,0,NULL,'bmw','bomwali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1021,0,NULL,'bmx','baimak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1022,0,NULL,'bmy','bemba (democratic republic of congo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1023,0,NULL,'bmz','baramu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1024,0,NULL,'bna','bonerate','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1025,0,NULL,'bnb','bookan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1026,0,NULL,'bnc','bontok','1248825600',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(1027,0,NULL,'bnd','banda (indonesia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1028,0,NULL,'bne','bintauna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1029,0,NULL,'bnf','masiwang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1030,0,NULL,'bng','benga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1031,0,NULL,'bni','bangi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1032,0,NULL,'bnj','eastern tawbuid','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1033,0,NULL,'bnk','bierebo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1034,0,NULL,'bnl','boon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1035,0,NULL,'bnm','batanga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1036,0,NULL,'bnn','bunun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1037,0,NULL,'bno','bantoanon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1038,0,NULL,'bnp','bola','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1039,0,NULL,'bnq','bantik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1040,0,NULL,'bnr','butmas-tur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1041,0,NULL,'bns','bundeli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1042,0,NULL,'bnt','bantu languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1043,0,NULL,'bnu','bentong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1044,0,NULL,'bnv','beneraf','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1044,0,NULL,'bnv','bonerif','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1044,0,NULL,'bnv','edwas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1045,0,NULL,'bnw','bisis','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1046,0,NULL,'bnx','bangubangu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1047,0,NULL,'bny','bintulu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1048,0,NULL,'bnz','beezen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1049,0,NULL,'boa','bora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1050,0,NULL,'bob','aweer','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1051,0,NULL,'boe','mundabli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1052,0,NULL,'bof','bolon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1053,0,NULL,'bog','bamako sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1054,0,NULL,'boh','boma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1055,0,NULL,'boi','barbareño','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1056,0,NULL,'boj','anjam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1057,0,NULL,'bok','bonjo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1058,0,NULL,'bol','bole','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1059,0,NULL,'bom','berom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1060,0,NULL,'bon','bine','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1061,0,NULL,'boo','tiemacèwè bozo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1062,0,NULL,'bop','bonkiman','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1063,0,NULL,'boq','bogaya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1064,0,NULL,'bor','borôro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1065,0,NULL,'bot','bongo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1066,0,NULL,'bou','bondei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1067,0,NULL,'bov','tuwuli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1068,0,NULL,'bow','rema','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1069,0,NULL,'box','buamu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1070,0,NULL,'boy','bodo (central african republic)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1071,0,NULL,'boz','tiéyaxo bozo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1072,0,NULL,'bpa','dakaka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1073,0,NULL,'bpb','barbacoas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1074,0,NULL,'bpd','banda-banda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1075,0,NULL,'bpg','bonggo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1076,0,NULL,'bph','botlikh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1077,0,NULL,'bpi','bagupi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1078,0,NULL,'bpj','binji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1079,0,NULL,'bpk','orowe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1080,0,NULL,'bpl','broome pearling lugger pidgin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1081,0,NULL,'bpm','biyom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1082,0,NULL,'bpn','dzao min','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1083,0,NULL,'bpo','anasi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1084,0,NULL,'bpp','kaure','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1085,0,NULL,'bpq','banda malay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1086,0,NULL,'bpr','koronadal blaan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1087,0,NULL,'bps','sarangani blaan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1088,0,NULL,'bpt','barrow point','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1089,0,NULL,'bpu','bongu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1090,0,NULL,'bpv','bian marind','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1091,0,NULL,'bpw','bo (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1092,0,NULL,'bpx','palya bareli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1093,0,NULL,'bpy','bishnupriya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1094,0,NULL,'bpz','bilba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1095,0,NULL,'bqa','tchumbuli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1096,0,NULL,'bqb','bagusa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1097,0,NULL,'bqc','boko (benin)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1098,0,NULL,'bqd','bung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1099,0,NULL,'bqf','baga kaloum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1100,0,NULL,'bqg','bago-kusuntu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1101,0,NULL,'bqh','baima','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1102,0,NULL,'bqi','bakhtiari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1103,0,NULL,'bqj','bandial','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1104,0,NULL,'bqk','banda-mbrès','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1105,0,NULL,'bql','bilakura','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1106,0,NULL,'bqm','wumboko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1107,0,NULL,'bqn','bulgarian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1108,0,NULL,'bqo','balo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1109,0,NULL,'bqp','busa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1110,0,NULL,'bqq','biritai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1111,0,NULL,'bqr','burusu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1112,0,NULL,'bqs','bosngun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1113,0,NULL,'bqt','bamukumbit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1114,0,NULL,'bqu','boguru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1115,0,NULL,'bqv','begbere-ejar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1116,0,NULL,'bqw','buru (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1117,0,NULL,'bqx','baangi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1118,0,NULL,'bqy','bengkala sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1119,0,NULL,'bqz','bakaka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1120,0,NULL,'bra','braj','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1121,0,NULL,'brb','lave','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1122,0,NULL,'brc','berbice creole dutch','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1123,0,NULL,'brd','baraamu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1124,0,NULL,'brf','bera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1125,0,NULL,'brg','baure','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1126,0,NULL,'brh','brahui','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1127,0,NULL,'bri','mokpwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1128,0,NULL,'brj','bieria','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1129,0,NULL,'brk','birked','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1130,0,NULL,'brl','birwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1131,0,NULL,'brm','barambu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1132,0,NULL,'brn','boruca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1133,0,NULL,'bro','brokkat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1134,0,NULL,'brp','barapasi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1135,0,NULL,'brq','breri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1136,0,NULL,'brr','birao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1137,0,NULL,'brs','baras','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1138,0,NULL,'brt','bitare','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1139,0,NULL,'bru','eastern bru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1140,0,NULL,'brv','western bru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1141,0,NULL,'brw','bellari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1142,0,NULL,'brx','bodo (india)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1143,0,NULL,'bry','burui','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1144,0,NULL,'brz','bilbil','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1145,0,NULL,'bsa','abinomn','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1146,0,NULL,'bsb','brunei bisaya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1147,0,NULL,'bsc','bassari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1147,0,NULL,'bsc','oniyan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1148,0,NULL,'bse','wushi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1149,0,NULL,'bsf','bauchi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1150,0,NULL,'bsg','bashkardi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1151,0,NULL,'bsh','kati','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1152,0,NULL,'bsi','bassossi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1153,0,NULL,'bsj','bangwinji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1154,0,NULL,'bsk','burushaski','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1155,0,NULL,'bsl','basa-gumna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1156,0,NULL,'bsm','busami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1157,0,NULL,'bsn','barasana-eduria','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1158,0,NULL,'bso','buso','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1159,0,NULL,'bsp','baga sitemu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1160,0,NULL,'bsq','bassa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1161,0,NULL,'bsr','bassa-kontagora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1162,0,NULL,'bss','akoose','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1163,0,NULL,'bst','basketo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1164,0,NULL,'bsu','bahonsuai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1165,0,NULL,'bsv','baga sobané','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1166,0,NULL,'bsw','baiso','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1167,0,NULL,'bsx','yangkam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1168,0,NULL,'bsy','sabah bisaya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1169,0,NULL,'bta','bata','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1170,0,NULL,'btb','beti (cameroon)','1248825600',1268265600,NULL,NULL,NULL,NULL,NULL,'see beb, bum, bxp, eto, ewo, fan, mct'); +INSERT INTO "iana_records" VALUES(1171,0,NULL,'btc','bati (cameroon)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1172,0,NULL,'btd','batak dairi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1173,0,NULL,'bte','gamo-ningi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1174,0,NULL,'btf','birgit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1175,0,NULL,'btg','gagnoa bété','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1176,0,NULL,'bth','biatah bidayuh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1177,0,NULL,'bti','burate','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1178,0,NULL,'btj','bacanese malay','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(1179,0,NULL,'btk','batak languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1180,0,NULL,'btl','bhatola','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1181,0,NULL,'btm','batak mandailing','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1182,0,NULL,'btn','ratagnon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1183,0,NULL,'bto','rinconada bikol','1248825600',NULL,NULL,NULL,NULL,'bik',NULL,NULL); +INSERT INTO "iana_records" VALUES(1184,0,NULL,'btp','budibud','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1185,0,NULL,'btq','batek','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1186,0,NULL,'btr','baetora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1187,0,NULL,'bts','batak simalungun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1188,0,NULL,'btt','bete-bendi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1189,0,NULL,'btu','batu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1190,0,NULL,'btv','bateri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1191,0,NULL,'btw','butuanon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1192,0,NULL,'btx','batak karo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1193,0,NULL,'bty','bobot','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1194,0,NULL,'btz','batak alas-kluet','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1195,0,NULL,'bua','buriat','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(1196,0,NULL,'bub','bua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1197,0,NULL,'buc','bushi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1198,0,NULL,'bud','ntcham','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1199,0,NULL,'bue','beothuk','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1200,0,NULL,'buf','bushoong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1201,0,NULL,'bug','buginese','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1202,0,NULL,'buh','younuo bunu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1203,0,NULL,'bui','bongili','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1204,0,NULL,'buj','basa-gurmana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1205,0,NULL,'buk','bugawac','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1206,0,NULL,'bum','bulu (cameroon)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1207,0,NULL,'bun','sherbro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1208,0,NULL,'buo','terei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1209,0,NULL,'bup','busoa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1210,0,NULL,'buq','brem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1211,0,NULL,'bus','bokobaru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1212,0,NULL,'but','bungain','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1213,0,NULL,'buu','budu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1214,0,NULL,'buv','bun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1215,0,NULL,'buw','bubi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1216,0,NULL,'bux','boghom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1217,0,NULL,'buy','bullom so','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1218,0,NULL,'buz','bukwen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1219,0,NULL,'bva','barein','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1220,0,NULL,'bvb','bube','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1221,0,NULL,'bvc','baelelea','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1222,0,NULL,'bvd','baeggu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1223,0,NULL,'bve','berau malay','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(1224,0,NULL,'bvf','boor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1225,0,NULL,'bvg','bonkeng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1226,0,NULL,'bvh','bure','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1227,0,NULL,'bvi','belanda viri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1228,0,NULL,'bvj','baan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1229,0,NULL,'bvk','bukat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1230,0,NULL,'bvl','bolivian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1231,0,NULL,'bvm','bamunka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1232,0,NULL,'bvn','buna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1233,0,NULL,'bvo','bolgo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1234,0,NULL,'bvq','birri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1235,0,NULL,'bvr','burarra','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1236,0,NULL,'bvt','bati (indonesia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1237,0,NULL,'bvu','bukit malay','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(1238,0,NULL,'bvv','baniva','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1239,0,NULL,'bvw','boga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1240,0,NULL,'bvx','dibole','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1241,0,NULL,'bvy','baybayanon','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1242,0,NULL,'bvz','bauzi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1243,0,NULL,'bwa','bwatoo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1244,0,NULL,'bwb','namosi-naitasiri-serua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1245,0,NULL,'bwc','bwile','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1246,0,NULL,'bwd','bwaidoka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1247,0,NULL,'bwe','bwe karen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1248,0,NULL,'bwf','boselewa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1249,0,NULL,'bwg','barwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1250,0,NULL,'bwh','bishuo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1251,0,NULL,'bwi','baniwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1252,0,NULL,'bwj','láá láá bwamu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1253,0,NULL,'bwk','bauwaki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1254,0,NULL,'bwl','bwela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1255,0,NULL,'bwm','biwat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1256,0,NULL,'bwn','wunai bunu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1257,0,NULL,'bwo','borna (ethiopia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1257,0,NULL,'bwo','boro (ethiopia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1258,0,NULL,'bwp','mandobo bawah','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1259,0,NULL,'bwq','southern bobo madaré','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1260,0,NULL,'bwr','bura-pabir','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1261,0,NULL,'bws','bomboma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1262,0,NULL,'bwt','bafaw-balong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1263,0,NULL,'bwu','buli (ghana)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1264,0,NULL,'bww','bwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1265,0,NULL,'bwx','bu-nao bunu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1266,0,NULL,'bwy','cwi bwamu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1267,0,NULL,'bwz','bwisi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1268,0,NULL,'bxa','bauro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1269,0,NULL,'bxb','belanda bor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1270,0,NULL,'bxc','molengue','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1271,0,NULL,'bxd','pela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1272,0,NULL,'bxe','birale','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1273,0,NULL,'bxf','bilur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1274,0,NULL,'bxg','bangala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1275,0,NULL,'bxh','buhutu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1276,0,NULL,'bxi','pirlatapa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1277,0,NULL,'bxj','bayungu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1278,0,NULL,'bxk','bukusu','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(1278,0,NULL,'bxk','lubukusu','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(1279,0,NULL,'bxl','jalkunan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1280,0,NULL,'bxm','mongolia buriat','1248825600',NULL,NULL,NULL,NULL,'bua',NULL,NULL); +INSERT INTO "iana_records" VALUES(1281,0,NULL,'bxn','burduna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1282,0,NULL,'bxo','barikanchi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1283,0,NULL,'bxp','bebil','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1284,0,NULL,'bxq','beele','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1285,0,NULL,'bxr','russia buriat','1248825600',NULL,NULL,NULL,NULL,'bua',NULL,NULL); +INSERT INTO "iana_records" VALUES(1286,0,NULL,'bxs','busam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1287,0,NULL,'bxu','china buriat','1248825600',NULL,NULL,NULL,NULL,'bua',NULL,NULL); +INSERT INTO "iana_records" VALUES(1288,0,NULL,'bxv','berakou','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1289,0,NULL,'bxw','bankagooma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1290,0,NULL,'bxx','borna (democratic republic of congo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1291,0,NULL,'bxz','binahari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1292,0,NULL,'bya','batak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1293,0,NULL,'byb','bikya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1294,0,NULL,'byc','ubaghara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1295,0,NULL,'byd','benyadu''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1296,0,NULL,'bye','pouye','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1297,0,NULL,'byf','bete','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1298,0,NULL,'byg','baygo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1299,0,NULL,'byh','bhujel','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1300,0,NULL,'byi','buyu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1301,0,NULL,'byj','bina (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1302,0,NULL,'byk','biao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1303,0,NULL,'byl','bayono','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1304,0,NULL,'bym','bidyara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1305,0,NULL,'byn','bilin','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1305,0,NULL,'byn','blin','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1306,0,NULL,'byo','biyo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1307,0,NULL,'byp','bumaji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1308,0,NULL,'byq','basay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1309,0,NULL,'byr','baruya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1310,0,NULL,'bys','burak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1311,0,NULL,'byt','berti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1312,0,NULL,'byv','medumba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1313,0,NULL,'byw','belhariya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1314,0,NULL,'byx','qaqet','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1315,0,NULL,'byy','buya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1316,0,NULL,'byz','banaro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1317,0,NULL,'bza','bandi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1318,0,NULL,'bzb','andio','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1319,0,NULL,'bzd','bribri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1320,0,NULL,'bze','jenaama bozo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1321,0,NULL,'bzf','boikin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1322,0,NULL,'bzg','babuza','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1323,0,NULL,'bzh','mapos buang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1324,0,NULL,'bzi','bisu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1325,0,NULL,'bzj','belize kriol english','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1326,0,NULL,'bzk','nicaragua creole english','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1327,0,NULL,'bzl','boano (sulawesi)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1328,0,NULL,'bzm','bolondo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1329,0,NULL,'bzn','boano (maluku)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1330,0,NULL,'bzo','bozaba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1331,0,NULL,'bzp','kemberano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1332,0,NULL,'bzq','buli (indonesia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1333,0,NULL,'bzr','biri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1334,0,NULL,'bzs','brazilian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1335,0,NULL,'bzt','brithenig','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1336,0,NULL,'bzu','burmeso','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1337,0,NULL,'bzv','bebe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1338,0,NULL,'bzw','basa (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1339,0,NULL,'bzx','hainyaxo bozo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1340,0,NULL,'bzy','obanliku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1341,0,NULL,'bzz','evant','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1342,0,NULL,'caa','chortí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1343,0,NULL,'cab','garifuna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1344,0,NULL,'cac','chuj','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1345,0,NULL,'cad','caddo','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1346,0,NULL,'cae','laalaa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1346,0,NULL,'cae','lehar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1347,0,NULL,'caf','southern carrier','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1348,0,NULL,'cag','nivaclé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1349,0,NULL,'cah','cahuarano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1350,0,NULL,'cai','central american indian languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1351,0,NULL,'caj','chané','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1352,0,NULL,'cak','cakchiquel','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1352,0,NULL,'cak','kaqchikel','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1353,0,NULL,'cal','carolinian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1354,0,NULL,'cam','cemuhî','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1355,0,NULL,'can','chambri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1356,0,NULL,'cao','chácobo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1357,0,NULL,'cap','chipaya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1358,0,NULL,'caq','car nicobarese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1359,0,NULL,'car','galibi carib','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1360,0,NULL,'cas','tsimané','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1361,0,NULL,'cau','caucasian languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1362,0,NULL,'cav','cavineña','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1363,0,NULL,'caw','callawalla','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1364,0,NULL,'cax','chiquitano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1365,0,NULL,'cay','cayuga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1366,0,NULL,'caz','canichana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1367,0,NULL,'cba','chibchan languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1368,0,NULL,'cbb','cabiyarí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1369,0,NULL,'cbc','carapana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1370,0,NULL,'cbd','carijona','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1371,0,NULL,'cbe','chipiajes','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1372,0,NULL,'cbg','chimila','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1373,0,NULL,'cbh','cagua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1374,0,NULL,'cbi','chachi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1375,0,NULL,'cbj','ede cabe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1376,0,NULL,'cbk','chavacano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1377,0,NULL,'cbl','bualkhaw chin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1378,0,NULL,'cbn','nyahkur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1379,0,NULL,'cbo','izora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1380,0,NULL,'cbr','cashibo-cacataibo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1381,0,NULL,'cbs','cashinahua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1382,0,NULL,'cbt','chayahuita','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1383,0,NULL,'cbu','candoshi-shapra','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1384,0,NULL,'cbv','cacua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1385,0,NULL,'cbw','kinabalian','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1386,0,NULL,'cby','carabayo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1387,0,NULL,'cca','cauca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1388,0,NULL,'ccc','chamicuro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1389,0,NULL,'ccd','cafundo creole','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1390,0,NULL,'cce','chopi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1391,0,NULL,'ccg','samba daka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1392,0,NULL,'cch','atsam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1393,0,NULL,'ccj','kasanga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1394,0,NULL,'ccl','cutchi-swahili','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1395,0,NULL,'ccm','malaccan creole malay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1396,0,NULL,'ccn','north caucasian languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1397,0,NULL,'cco','comaltepec chinantec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1398,0,NULL,'ccp','chakma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1399,0,NULL,'ccq','chaungtha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1400,0,NULL,'ccr','cacaopera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1401,0,NULL,'ccs','south caucasian languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1402,0,NULL,'cda','choni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1403,0,NULL,'cdc','chadic languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1404,0,NULL,'cdd','caddoan languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1405,0,NULL,'cde','chenchu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1406,0,NULL,'cdf','chiru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1407,0,NULL,'cdg','chamari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1408,0,NULL,'cdh','chambeali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1409,0,NULL,'cdi','chodri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1410,0,NULL,'cdj','churahi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1411,0,NULL,'cdm','chepang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1412,0,NULL,'cdn','chaudangsi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1413,0,NULL,'cdo','min dong chinese','1248825600',NULL,NULL,NULL,NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(1414,0,NULL,'cdr','cinda-regi-tiyal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1415,0,NULL,'cds','chadian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1416,0,NULL,'cdy','chadong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1417,0,NULL,'cdz','koda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1418,0,NULL,'cea','lower chehalis','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1419,0,NULL,'ceb','cebuano','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1420,0,NULL,'ceg','chamacoco','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1421,0,NULL,'cel','celtic languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1422,0,NULL,'cen','cen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1423,0,NULL,'cet','centúúm','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1424,0,NULL,'cfa','dijim-bwilim','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1425,0,NULL,'cfd','cara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1426,0,NULL,'cfg','como karim','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1427,0,NULL,'cfm','falam chin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1428,0,NULL,'cga','changriwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1429,0,NULL,'cgc','kagayanen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1430,0,NULL,'cgg','chiga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1431,0,NULL,'cgk','chocangacakha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1432,0,NULL,'chb','chibcha','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1433,0,NULL,'chc','catawba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1434,0,NULL,'chd','highland oaxaca chontal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1435,0,NULL,'chf','tabasco chontal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1436,0,NULL,'chg','chagatai','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1437,0,NULL,'chh','chinook','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1438,0,NULL,'chj','ojitlán chinantec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1439,0,NULL,'chk','chuukese','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1440,0,NULL,'chl','cahuilla','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1441,0,NULL,'chm','mari (russia)','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(1442,0,NULL,'chn','chinook jargon','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1443,0,NULL,'cho','choctaw','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1444,0,NULL,'chp','chipewyan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1444,0,NULL,'chp','dene suline','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1445,0,NULL,'chq','quiotepec chinantec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1446,0,NULL,'chr','cherokee','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1447,0,NULL,'cht','cholón','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1448,0,NULL,'chw','chuwabu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1449,0,NULL,'chx','chantyal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1450,0,NULL,'chy','cheyenne','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1451,0,NULL,'chz','ozumacín chinantec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1452,0,NULL,'cia','cia-cia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1453,0,NULL,'cib','ci gbe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1454,0,NULL,'cic','chickasaw','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1455,0,NULL,'cid','chimariko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1456,0,NULL,'cie','cineni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1457,0,NULL,'cih','chinali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1458,0,NULL,'cik','chitkuli kinnauri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1459,0,NULL,'cim','cimbrian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1460,0,NULL,'cin','cinta larga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1461,0,NULL,'cip','chiapanec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1462,0,NULL,'cir','tiri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1463,0,NULL,'ciw','chippewa','1248825600',NULL,NULL,NULL,NULL,'oj',NULL,NULL); +INSERT INTO "iana_records" VALUES(1464,0,NULL,'ciy','chaima','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1465,0,NULL,'cja','western cham','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1466,0,NULL,'cje','chru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1467,0,NULL,'cjh','upper chehalis','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1468,0,NULL,'cji','chamalal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1469,0,NULL,'cjk','chokwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1470,0,NULL,'cjm','eastern cham','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1471,0,NULL,'cjn','chenapian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1472,0,NULL,'cjo','ashéninka pajonal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1473,0,NULL,'cjp','cabécar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1474,0,NULL,'cjr','chorotega','1248825600',1268265600,'mom',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1475,0,NULL,'cjs','shor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1476,0,NULL,'cjv','chuave','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1477,0,NULL,'cjy','jinyu chinese','1248825600',NULL,NULL,NULL,NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(1478,0,NULL,'cka','khumi awa chin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1479,0,NULL,'ckb','central kurdish','1248825600',NULL,NULL,NULL,NULL,'ku',NULL,NULL); +INSERT INTO "iana_records" VALUES(1480,0,NULL,'ckh','chak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1481,0,NULL,'ckl','cibak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1482,0,NULL,'cko','anufo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1483,0,NULL,'ckq','kajakse','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1484,0,NULL,'ckr','kairak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1485,0,NULL,'cks','tayo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1486,0,NULL,'ckt','chukot','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1487,0,NULL,'cku','koasati','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1488,0,NULL,'ckv','kavalan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1489,0,NULL,'ckx','caka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1490,0,NULL,'cky','cakfem-mushere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1491,0,NULL,'ckz','cakchiquel-quiché mixed language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1492,0,NULL,'cla','ron','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1493,0,NULL,'clc','chilcotin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1494,0,NULL,'cld','chaldean neo-aramaic','1248825600',NULL,NULL,NULL,NULL,'syr',NULL,NULL); +INSERT INTO "iana_records" VALUES(1495,0,NULL,'cle','lealao chinantec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1496,0,NULL,'clh','chilisso','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1497,0,NULL,'cli','chakali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1498,0,NULL,'clk','idu-mishmi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1499,0,NULL,'cll','chala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1500,0,NULL,'clm','clallam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1501,0,NULL,'clo','lowland oaxaca chontal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1502,0,NULL,'clu','caluyanun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1503,0,NULL,'clw','chulym','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1504,0,NULL,'cly','eastern highland chatino','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1505,0,NULL,'cma','maa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1506,0,NULL,'cmc','chamic languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1507,0,NULL,'cme','cerma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1508,0,NULL,'cmg','classical mongolian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1509,0,NULL,'cmi','emberá-chamí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1510,0,NULL,'cmk','chimakum','1248825600',1268265600,'xch',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1511,0,NULL,'cml','campalagian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1512,0,NULL,'cmm','michigamea','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1513,0,NULL,'cmn','mandarin chinese','1248825600',NULL,NULL,NULL,NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(1514,0,NULL,'cmo','central mnong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1515,0,NULL,'cmr','mro chin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1516,0,NULL,'cms','messapic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1517,0,NULL,'cmt','camtho','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1518,0,NULL,'cna','changthang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1519,0,NULL,'cnb','chinbon chin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1520,0,NULL,'cnc','côông','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1521,0,NULL,'cng','northern qiang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1522,0,NULL,'cnh','haka chin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1523,0,NULL,'cni','asháninka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1524,0,NULL,'cnk','khumi chin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1525,0,NULL,'cnl','lalana chinantec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1526,0,NULL,'cno','con','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1527,0,NULL,'cns','central asmat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1528,0,NULL,'cnt','tepetotutla chinantec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1529,0,NULL,'cnu','chenoua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1530,0,NULL,'cnw','ngawn chin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1531,0,NULL,'cnx','middle cornish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1532,0,NULL,'coa','cocos islands malay','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(1533,0,NULL,'cob','chicomuceltec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1534,0,NULL,'coc','cocopa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1535,0,NULL,'cod','cocama-cocamilla','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1536,0,NULL,'coe','koreguaje','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1537,0,NULL,'cof','colorado','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1538,0,NULL,'cog','chong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1539,0,NULL,'coh','chichonyi-chidzihana-chikauma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1539,0,NULL,'coh','chonyi-dzihana-kauma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1540,0,NULL,'coj','cochimi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1541,0,NULL,'cok','santa teresa cora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1542,0,NULL,'col','columbia-wenatchi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1543,0,NULL,'com','comanche','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1544,0,NULL,'con','cofán','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1545,0,NULL,'coo','comox','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1546,0,NULL,'cop','coptic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1547,0,NULL,'coq','coquille','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1548,0,NULL,'cot','caquinte','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1549,0,NULL,'cou','wamey','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1550,0,NULL,'cov','cao miao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1551,0,NULL,'cow','cowlitz','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1552,0,NULL,'cox','nanti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1553,0,NULL,'coy','coyaima','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1554,0,NULL,'coz','chochotec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1555,0,NULL,'cpa','palantla chinantec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1556,0,NULL,'cpb','ucayali-yurúa ashéninka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1557,0,NULL,'cpc','ajyíninka apurucayali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1558,0,NULL,'cpe','english-based creoles and pidgins','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1559,0,NULL,'cpf','french-based creoles and pidgins','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1560,0,NULL,'cpg','cappadocian greek','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1561,0,NULL,'cpi','chinese pidgin english','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1562,0,NULL,'cpn','cherepon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1563,0,NULL,'cpp','portuguese-based creoles and pidgins','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1564,0,NULL,'cps','capiznon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1565,0,NULL,'cpu','pichis ashéninka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1566,0,NULL,'cpx','pu-xian chinese','1248825600',NULL,NULL,NULL,NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(1567,0,NULL,'cpy','south ucayali ashéninka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1568,0,NULL,'cqd','chuanqiandian cluster miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(1569,0,NULL,'cqu','chilean quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(1570,0,NULL,'cra','chara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1571,0,NULL,'crb','island carib','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1572,0,NULL,'crc','lonwolwol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1573,0,NULL,'crd','coeur d''alene','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1574,0,NULL,'crf','caramanta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1575,0,NULL,'crg','michif','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1576,0,NULL,'crh','crimean tatar','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1576,0,NULL,'crh','crimean turkish','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1577,0,NULL,'cri','sãotomense','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1578,0,NULL,'crj','southern east cree','1248825600',NULL,NULL,NULL,NULL,'cr',NULL,NULL); +INSERT INTO "iana_records" VALUES(1579,0,NULL,'crk','plains cree','1248825600',NULL,NULL,NULL,NULL,'cr',NULL,NULL); +INSERT INTO "iana_records" VALUES(1580,0,NULL,'crl','northern east cree','1248825600',NULL,NULL,NULL,NULL,'cr',NULL,NULL); +INSERT INTO "iana_records" VALUES(1581,0,NULL,'crm','moose cree','1248825600',NULL,NULL,NULL,NULL,'cr',NULL,NULL); +INSERT INTO "iana_records" VALUES(1582,0,NULL,'crn','el nayar cora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1583,0,NULL,'cro','crow','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1584,0,NULL,'crp','creoles and pidgins','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1585,0,NULL,'crq','iyo''wujwa chorote','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1586,0,NULL,'crr','carolina algonquian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1587,0,NULL,'crs','seselwa creole french','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1588,0,NULL,'crt','iyojwa''ja chorote','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1589,0,NULL,'crv','chaura','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1590,0,NULL,'crw','chrau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1591,0,NULL,'crx','carrier','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1592,0,NULL,'cry','cori','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1593,0,NULL,'crz','cruzeño','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1594,0,NULL,'csa','chiltepec chinantec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1595,0,NULL,'csb','kashubian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1596,0,NULL,'csc','catalan sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1596,0,NULL,'csc','lengua de señas catalana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1596,0,NULL,'csc','llengua de signes catalana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1597,0,NULL,'csd','chiangmai sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1598,0,NULL,'cse','czech sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1599,0,NULL,'csf','cuba sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1600,0,NULL,'csg','chilean sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1601,0,NULL,'csh','asho chin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1602,0,NULL,'csi','coast miwok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1603,0,NULL,'csk','jola-kasa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1604,0,NULL,'csl','chinese sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1605,0,NULL,'csm','central sierra miwok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1606,0,NULL,'csn','colombian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1607,0,NULL,'cso','sochiapam chinantec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1607,0,NULL,'cso','sochiapan chinantec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1608,0,NULL,'csq','croatia sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1609,0,NULL,'csr','costa rican sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1610,0,NULL,'css','southern ohlone','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1611,0,NULL,'cst','northern ohlone','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1612,0,NULL,'csu','central sudanic languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1613,0,NULL,'csw','swampy cree','1248825600',NULL,NULL,NULL,NULL,'cr',NULL,NULL); +INSERT INTO "iana_records" VALUES(1614,0,NULL,'csy','siyin chin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1615,0,NULL,'csz','coos','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1616,0,NULL,'cta','tataltepec chatino','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1617,0,NULL,'ctc','chetco','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1618,0,NULL,'ctd','tedim chin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1619,0,NULL,'cte','tepinapa chinantec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1620,0,NULL,'ctg','chittagonian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1621,0,NULL,'ctl','tlacoatzintepec chinantec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1622,0,NULL,'ctm','chitimacha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1623,0,NULL,'ctn','chhintange','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1624,0,NULL,'cto','emberá-catío','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1625,0,NULL,'ctp','western highland chatino','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1626,0,NULL,'cts','northern catanduanes bicolano','1248825600',NULL,NULL,NULL,NULL,'bik',NULL,NULL); +INSERT INTO "iana_records" VALUES(1627,0,NULL,'ctt','wayanad chetti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1628,0,NULL,'ctu','chol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1629,0,NULL,'ctz','zacatepec chatino','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1630,0,NULL,'cua','cua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1631,0,NULL,'cub','cubeo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1632,0,NULL,'cuc','usila chinantec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1633,0,NULL,'cug','cung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1634,0,NULL,'cuh','chuka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1634,0,NULL,'cuh','gichuka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1635,0,NULL,'cui','cuiba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1636,0,NULL,'cuj','mashco piro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1637,0,NULL,'cuk','san blas kuna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1638,0,NULL,'cul','culina','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1638,0,NULL,'cul','kulina','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1639,0,NULL,'cum','cumeral','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1640,0,NULL,'cuo','cumanagoto','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1641,0,NULL,'cup','cupeño','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1642,0,NULL,'cuq','cun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1643,0,NULL,'cur','chhulung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1644,0,NULL,'cus','cushitic languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1645,0,NULL,'cut','teutila cuicatec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1646,0,NULL,'cuu','tai ya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1647,0,NULL,'cuv','cuvok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1648,0,NULL,'cuw','chukwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1649,0,NULL,'cux','tepeuxila cuicatec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1650,0,NULL,'cvg','chug','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1651,0,NULL,'cvn','valle nacional chinantec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1652,0,NULL,'cwa','kabwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1653,0,NULL,'cwb','maindo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1654,0,NULL,'cwd','woods cree','1248825600',NULL,NULL,NULL,NULL,'cr',NULL,NULL); +INSERT INTO "iana_records" VALUES(1655,0,NULL,'cwe','kwere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1656,0,NULL,'cwg','cheq wong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1656,0,NULL,'cwg','chewong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1657,0,NULL,'cwt','kuwaataay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1658,0,NULL,'cya','nopala chatino','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1659,0,NULL,'cyb','cayubaba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1660,0,NULL,'cyo','cuyonon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1661,0,NULL,'czh','huizhou chinese','1248825600',NULL,NULL,NULL,NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(1662,0,NULL,'czk','knaanic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1663,0,NULL,'czn','zenzontepec chatino','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1664,0,NULL,'czo','min zhong chinese','1248825600',NULL,NULL,NULL,NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(1665,0,NULL,'czt','zotung chin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1666,0,NULL,'daa','dangaléat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1667,0,NULL,'dac','dambi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1668,0,NULL,'dad','marik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1669,0,NULL,'dae','duupa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1670,0,NULL,'daf','dan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1671,0,NULL,'dag','dagbani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1672,0,NULL,'dah','gwahatike','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1673,0,NULL,'dai','day','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1674,0,NULL,'daj','dar fur daju','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1675,0,NULL,'dak','dakota','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1676,0,NULL,'dal','dahalo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1677,0,NULL,'dam','damakawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1678,0,NULL,'dao','daai chin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1679,0,NULL,'dap','nisi (india)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1680,0,NULL,'daq','dandami maria','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1681,0,NULL,'dar','dargwa','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1682,0,NULL,'das','daho-doo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1683,0,NULL,'dau','dar sila daju','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1684,0,NULL,'dav','dawida','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1684,0,NULL,'dav','taita','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1685,0,NULL,'daw','davawenyo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1686,0,NULL,'dax','dayi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1687,0,NULL,'day','land dayak languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1688,0,NULL,'daz','dao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1689,0,NULL,'dba','bangi me','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1690,0,NULL,'dbb','deno','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1691,0,NULL,'dbd','dadiya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1692,0,NULL,'dbe','dabe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1693,0,NULL,'dbf','edopi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1694,0,NULL,'dbg','dogul dom dogon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1695,0,NULL,'dbi','doka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1696,0,NULL,'dbj','ida''an','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1697,0,NULL,'dbl','dyirbal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1698,0,NULL,'dbm','duguri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1699,0,NULL,'dbn','duriankere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1700,0,NULL,'dbo','dulbu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1701,0,NULL,'dbp','duwai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1702,0,NULL,'dbq','daba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1703,0,NULL,'dbr','dabarre','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1704,0,NULL,'dbu','bondum dom dogon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1705,0,NULL,'dbv','dungu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1706,0,NULL,'dby','dibiyaso','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1707,0,NULL,'dcc','deccan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1708,0,NULL,'dcr','negerhollands','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1709,0,NULL,'ddd','dongotono','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1710,0,NULL,'dde','doondo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1711,0,NULL,'ddg','fataluku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1712,0,NULL,'ddi','west goodenough','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1713,0,NULL,'ddj','jaru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1714,0,NULL,'ddn','dendi (benin)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1715,0,NULL,'ddo','dido','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1716,0,NULL,'dds','donno so dogon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1717,0,NULL,'ddw','dawera-daweloor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1718,0,NULL,'dec','dagik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1719,0,NULL,'ded','dedua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1720,0,NULL,'dee','dewoin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1721,0,NULL,'def','dezfuli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1722,0,NULL,'deg','degema','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1723,0,NULL,'deh','dehwari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1724,0,NULL,'dei','demisa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1725,0,NULL,'dek','dek','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1726,0,NULL,'del','delaware','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(1727,0,NULL,'dem','dem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1728,0,NULL,'den','slave (athapascan)','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(1729,0,NULL,'dep','pidgin delaware','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1730,0,NULL,'deq','dendi (central african republic)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1731,0,NULL,'der','deori','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1732,0,NULL,'des','desano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1733,0,NULL,'dev','domung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1734,0,NULL,'dez','dengese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1735,0,NULL,'dga','southern dagaare','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1736,0,NULL,'dgb','bunoge dogon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1737,0,NULL,'dgc','casiguran dumagat agta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1738,0,NULL,'dgd','dagaari dioula','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1739,0,NULL,'dge','degenan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1740,0,NULL,'dgg','doga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1741,0,NULL,'dgh','dghwede','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1742,0,NULL,'dgi','northern dagara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1743,0,NULL,'dgk','dagba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1744,0,NULL,'dgn','dagoman','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1745,0,NULL,'dgo','dogri (individual language)','1248825600',NULL,NULL,NULL,NULL,'doi',NULL,NULL); +INSERT INTO "iana_records" VALUES(1746,0,NULL,'dgr','dogrib','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1747,0,NULL,'dgs','dogoso','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1748,0,NULL,'dgu','degaru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1749,0,NULL,'dgx','doghoro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1750,0,NULL,'dgz','daga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1751,0,NULL,'dha','dhanwar (india)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1752,0,NULL,'dhd','dhundari','1248825600',NULL,NULL,NULL,NULL,'mwr',NULL,NULL); +INSERT INTO "iana_records" VALUES(1753,0,NULL,'dhg','dhangu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1754,0,NULL,'dhi','dhimal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1755,0,NULL,'dhl','dhalandji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1756,0,NULL,'dhm','zemba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1757,0,NULL,'dhn','dhanki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1758,0,NULL,'dho','dhodia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1759,0,NULL,'dhr','dhargari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1760,0,NULL,'dhs','dhaiso','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1761,0,NULL,'dhu','dhurga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1762,0,NULL,'dhv','dehu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1763,0,NULL,'dhw','dhanwar (nepal)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1764,0,NULL,'dia','dia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1765,0,NULL,'dib','south central dinka','1248825600',NULL,NULL,NULL,NULL,'din',NULL,NULL); +INSERT INTO "iana_records" VALUES(1766,0,NULL,'dic','lakota dida','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1767,0,NULL,'did','didinga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1768,0,NULL,'dif','dieri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1769,0,NULL,'dig','chidigo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1769,0,NULL,'dig','digo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1770,0,NULL,'dih','kumiai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1771,0,NULL,'dii','dimbong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1772,0,NULL,'dij','dai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1773,0,NULL,'dik','southwestern dinka','1248825600',NULL,NULL,NULL,NULL,'din',NULL,NULL); +INSERT INTO "iana_records" VALUES(1774,0,NULL,'dil','dilling','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1775,0,NULL,'dim','dime','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1776,0,NULL,'din','dinka','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(1777,0,NULL,'dio','dibo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1778,0,NULL,'dip','northeastern dinka','1248825600',NULL,NULL,NULL,NULL,'din',NULL,NULL); +INSERT INTO "iana_records" VALUES(1779,0,NULL,'diq','dimli (individual language)','1248825600',NULL,NULL,NULL,NULL,'zza',NULL,NULL); +INSERT INTO "iana_records" VALUES(1780,0,NULL,'dir','dirim','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1781,0,NULL,'dis','dimasa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1782,0,NULL,'dit','dirari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1783,0,NULL,'diu','diriku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1784,0,NULL,'diw','northwestern dinka','1248825600',NULL,NULL,NULL,NULL,'din',NULL,NULL); +INSERT INTO "iana_records" VALUES(1785,0,NULL,'dix','dixon reef','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1786,0,NULL,'diy','diuwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1787,0,NULL,'diz','ding','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1788,0,NULL,'djb','djinba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1789,0,NULL,'djc','dar daju daju','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1790,0,NULL,'djd','djamindjung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1791,0,NULL,'dje','zarma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1792,0,NULL,'djf','djangun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1793,0,NULL,'dji','djinang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1794,0,NULL,'djj','djeebbana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1795,0,NULL,'djk','businenge tongo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1795,0,NULL,'djk','eastern maroon creole','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1795,0,NULL,'djk','nenge','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1796,0,NULL,'djl','djiwarli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1797,0,NULL,'djm','jamsay dogon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1798,0,NULL,'djn','djauan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1799,0,NULL,'djo','jangkang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1800,0,NULL,'djr','djambarrpuyngu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1801,0,NULL,'dju','kapriman','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1802,0,NULL,'djw','djawi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1803,0,NULL,'dka','dakpakha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1804,0,NULL,'dkk','dakka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1805,0,NULL,'dkl','kolum so dogon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1806,0,NULL,'dkr','kuijau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1807,0,NULL,'dks','southeastern dinka','1248825600',NULL,NULL,NULL,NULL,'din',NULL,NULL); +INSERT INTO "iana_records" VALUES(1808,0,NULL,'dkx','mazagway','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1809,0,NULL,'dlg','dolgan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1810,0,NULL,'dlm','dalmatian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1811,0,NULL,'dln','darlong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1812,0,NULL,'dma','duma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1813,0,NULL,'dmc','dimir','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1814,0,NULL,'dme','dugwor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1815,0,NULL,'dmg','upper kinabatangan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1816,0,NULL,'dmk','domaaki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1817,0,NULL,'dml','dameli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1818,0,NULL,'dmm','dama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1819,0,NULL,'dmn','mande languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1820,0,NULL,'dmo','kemezung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1821,0,NULL,'dmr','east damar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1822,0,NULL,'dms','dampelas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1823,0,NULL,'dmu','dubu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1823,0,NULL,'dmu','tebi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1824,0,NULL,'dmv','dumpas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1825,0,NULL,'dmx','dema','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1826,0,NULL,'dmy','demta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1826,0,NULL,'dmy','sowari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1827,0,NULL,'dna','upper grand valley dani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1828,0,NULL,'dnd','daonda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1829,0,NULL,'dne','ndendeule','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1830,0,NULL,'dng','dungan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1831,0,NULL,'dni','lower grand valley dani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1832,0,NULL,'dnk','dengka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1833,0,NULL,'dnn','dzùùngoo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1834,0,NULL,'dnr','danaru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1835,0,NULL,'dnt','mid grand valley dani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1836,0,NULL,'dnu','danau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1837,0,NULL,'dnw','western dani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1838,0,NULL,'dny','dení','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1839,0,NULL,'doa','dom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1840,0,NULL,'dob','dobu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1841,0,NULL,'doc','northern dong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1842,0,NULL,'doe','doe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1843,0,NULL,'dof','domu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1844,0,NULL,'doh','dong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1845,0,NULL,'doi','dogri (macrolanguage)','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(1846,0,NULL,'dok','dondo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1847,0,NULL,'dol','doso','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1848,0,NULL,'don','toura (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1849,0,NULL,'doo','dongo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1850,0,NULL,'dop','lukpa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1851,0,NULL,'doq','dominican sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1852,0,NULL,'dor','dori''o','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1853,0,NULL,'dos','dogosé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1854,0,NULL,'dot','dass','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1855,0,NULL,'dov','dombe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1856,0,NULL,'dow','doyayo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1857,0,NULL,'dox','bussa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1858,0,NULL,'doy','dompo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1859,0,NULL,'doz','dorze','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1860,0,NULL,'dpp','papar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1861,0,NULL,'dra','dravidian languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1862,0,NULL,'drb','dair','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1863,0,NULL,'drd','darmiya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1864,0,NULL,'dre','dolpo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1865,0,NULL,'drg','rungus','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1866,0,NULL,'drh','darkhat','1248825600',1268265600,'khk',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1867,0,NULL,'dri','c''lela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1868,0,NULL,'drl','darling','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1869,0,NULL,'drn','west damar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1870,0,NULL,'dro','daro-matu melanau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1871,0,NULL,'drq','dura','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1872,0,NULL,'drr','dororo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1873,0,NULL,'drs','gedeo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1874,0,NULL,'drt','drents','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1875,0,NULL,'dru','rukai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1876,0,NULL,'drw','darwazi','1248825600',1268265600,'prs',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1877,0,NULL,'dry','darai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1878,0,NULL,'dsb','lower sorbian','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1879,0,NULL,'dse','dutch sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1880,0,NULL,'dsh','daasanach','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1881,0,NULL,'dsi','disa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1882,0,NULL,'dsl','danish sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1883,0,NULL,'dsn','dusner','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1884,0,NULL,'dso','desiya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1885,0,NULL,'dsq','tadaksahak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1886,0,NULL,'dta','daur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1887,0,NULL,'dtb','labuk-kinabatangan kadazan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1888,0,NULL,'dti','ana tinga dogon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1889,0,NULL,'dtk','tene kan dogon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1890,0,NULL,'dtm','tomo kan dogon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1891,0,NULL,'dtp','central dusun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1892,0,NULL,'dtr','lotud','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1893,0,NULL,'dts','toro so dogon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1894,0,NULL,'dtt','toro tegu dogon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1895,0,NULL,'dtu','tebul ure dogon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1896,0,NULL,'dua','duala','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1897,0,NULL,'dub','dubli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1898,0,NULL,'duc','duna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1899,0,NULL,'dud','hun-saare','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1900,0,NULL,'due','umiray dumaget agta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1901,0,NULL,'duf','dumbea','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1902,0,NULL,'dug','chiduruma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1902,0,NULL,'dug','duruma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1903,0,NULL,'duh','dungra bhil','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1904,0,NULL,'dui','dumun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1905,0,NULL,'duj','dhuwal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1906,0,NULL,'duk','duduela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1907,0,NULL,'dul','alabat island agta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1908,0,NULL,'dum','middle dutch (ca. 1050-1350)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1909,0,NULL,'dun','dusun deyah','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1910,0,NULL,'duo','dupaninan agta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1911,0,NULL,'dup','duano','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(1912,0,NULL,'duq','dusun malang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1913,0,NULL,'dur','dii','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1914,0,NULL,'dus','dumi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1915,0,NULL,'duu','drung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1916,0,NULL,'duv','duvle','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1917,0,NULL,'duw','dusun witu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1918,0,NULL,'dux','duungooma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1919,0,NULL,'duy','dicamay agta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1920,0,NULL,'duz','duli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1921,0,NULL,'dva','duau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1922,0,NULL,'dwa','diri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1923,0,NULL,'dwl','walo kumbe dogon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1924,0,NULL,'dwr','dawro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1925,0,NULL,'dws','dutton world speedwords','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1926,0,NULL,'dww','dawawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1927,0,NULL,'dya','dyan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1928,0,NULL,'dyb','dyaberdyaber','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1929,0,NULL,'dyd','dyugun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1930,0,NULL,'dyg','villa viciosa agta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1931,0,NULL,'dyi','djimini senoufo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1932,0,NULL,'dym','yanda dom dogon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1933,0,NULL,'dyn','dyangadi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1934,0,NULL,'dyo','jola-fonyi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1935,0,NULL,'dyu','dyula','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1936,0,NULL,'dyy','dyaabugay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1937,0,NULL,'dza','tunzu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1938,0,NULL,'dzd','daza','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1939,0,NULL,'dzg','dazaga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1940,0,NULL,'dzl','dzalakha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1941,0,NULL,'dzn','dzando','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1942,0,NULL,'ebg','ebughu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1943,0,NULL,'ebk','eastern bontok','1268265600',NULL,NULL,NULL,NULL,'bnc',NULL,NULL); +INSERT INTO "iana_records" VALUES(1944,0,NULL,'ebo','teke-ebo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1945,0,NULL,'ebr','ebrié','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1946,0,NULL,'ebu','embu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1946,0,NULL,'ebu','kiembu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1947,0,NULL,'ecr','eteocretan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1948,0,NULL,'ecs','ecuadorian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1949,0,NULL,'ecy','eteocypriot','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1950,0,NULL,'eee','e','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1951,0,NULL,'efa','efai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1952,0,NULL,'efe','efe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1953,0,NULL,'efi','efik','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1954,0,NULL,'ega','ega','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1955,0,NULL,'egl','emilian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1956,0,NULL,'ego','eggon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1957,0,NULL,'egx','egyptian languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1958,0,NULL,'egy','egyptian (ancient)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1959,0,NULL,'ehu','ehueun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1960,0,NULL,'eip','eipomek','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1961,0,NULL,'eit','eitiep','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1962,0,NULL,'eiv','askopan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1963,0,NULL,'eja','ejamat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1964,0,NULL,'eka','ekajuk','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1965,0,NULL,'eke','ekit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1966,0,NULL,'ekg','ekari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1967,0,NULL,'eki','eki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1968,0,NULL,'ekk','standard estonian','1248825600',NULL,NULL,NULL,NULL,'et',NULL,NULL); +INSERT INTO "iana_records" VALUES(1969,0,NULL,'ekl','kol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1970,0,NULL,'ekm','elip','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1971,0,NULL,'eko','koti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1972,0,NULL,'ekp','ekpeye','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1973,0,NULL,'ekr','yace','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1974,0,NULL,'eky','eastern kayah','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1975,0,NULL,'ele','elepi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1976,0,NULL,'elh','el hugeirat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1977,0,NULL,'eli','nding','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1978,0,NULL,'elk','elkei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1979,0,NULL,'elm','eleme','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1980,0,NULL,'elo','el molo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1981,0,NULL,'elp','elpaputih','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1982,0,NULL,'elu','elu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1983,0,NULL,'elx','elamite','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1984,0,NULL,'ema','emai-iuleha-ora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1985,0,NULL,'emb','embaloh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1986,0,NULL,'eme','emerillon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1987,0,NULL,'emg','eastern meohang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1988,0,NULL,'emi','mussau-emira','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1989,0,NULL,'emk','eastern maninkakan','1248825600',NULL,NULL,NULL,NULL,'man',NULL,NULL); +INSERT INTO "iana_records" VALUES(1990,0,NULL,'emm','mamulique','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1991,0,NULL,'emn','eman','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1992,0,NULL,'emo','emok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1993,0,NULL,'emp','northern emberá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1994,0,NULL,'ems','pacific gulf yupik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1995,0,NULL,'emu','eastern muria','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1996,0,NULL,'emw','emplawas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1997,0,NULL,'emx','erromintxela','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1998,0,NULL,'emy','epigraphic mayan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1999,0,NULL,'ena','apali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2000,0,NULL,'enb','markweeta','1248825600',NULL,NULL,NULL,NULL,'kln',NULL,NULL); +INSERT INTO "iana_records" VALUES(2001,0,NULL,'enc','en','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2002,0,NULL,'end','ende','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2003,0,NULL,'enf','forest enets','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2004,0,NULL,'enh','tundra enets','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2005,0,NULL,'enm','middle english (1100-1500)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2006,0,NULL,'enn','engenni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2007,0,NULL,'eno','enggano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2008,0,NULL,'enq','enga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2009,0,NULL,'enr','emem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2009,0,NULL,'enr','emumu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2010,0,NULL,'enu','enu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2011,0,NULL,'env','enwan (edu state)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2012,0,NULL,'enw','enwan (akwa ibom state)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2013,0,NULL,'eot','beti (côte d''ivoire)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2014,0,NULL,'epi','epie','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2015,0,NULL,'era','eravallan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2016,0,NULL,'erg','sie','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2017,0,NULL,'erh','eruwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2018,0,NULL,'eri','ogea','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2019,0,NULL,'erk','south efate','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2020,0,NULL,'ero','horpa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2021,0,NULL,'err','erre','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2022,0,NULL,'ers','ersu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2023,0,NULL,'ert','eritai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2024,0,NULL,'erw','erokwanas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2025,0,NULL,'ese','ese ejja','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2026,0,NULL,'esh','eshtehardi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2027,0,NULL,'esi','north alaskan inupiatun','1248825600',NULL,NULL,NULL,NULL,'ik',NULL,NULL); +INSERT INTO "iana_records" VALUES(2028,0,NULL,'esk','northwest alaska inupiatun','1248825600',NULL,NULL,NULL,NULL,'ik',NULL,NULL); +INSERT INTO "iana_records" VALUES(2029,0,NULL,'esl','egypt sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2030,0,NULL,'esm','esuma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2031,0,NULL,'esn','salvadoran sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2032,0,NULL,'eso','estonian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2033,0,NULL,'esq','esselen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2034,0,NULL,'ess','central siberian yupik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2035,0,NULL,'esu','central yupik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2036,0,NULL,'esx','eskimo-aleut languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2037,0,NULL,'etb','etebi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2038,0,NULL,'etc','etchemin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2039,0,NULL,'eth','ethiopian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2040,0,NULL,'etn','eton (vanuatu)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2041,0,NULL,'eto','eton (cameroon)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2042,0,NULL,'etr','edolo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2043,0,NULL,'ets','yekhee','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2044,0,NULL,'ett','etruscan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2045,0,NULL,'etu','ejagham','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2046,0,NULL,'etx','eten','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2047,0,NULL,'etz','semimi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2048,0,NULL,'euq','basque (family)','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2049,0,NULL,'eve','even','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2050,0,NULL,'evh','uvbie','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2051,0,NULL,'evn','evenki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2052,0,NULL,'ewo','ewondo','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2053,0,NULL,'ext','extremaduran','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2054,0,NULL,'eya','eyak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2055,0,NULL,'eyo','keiyo','1248825600',NULL,NULL,NULL,NULL,'kln',NULL,NULL); +INSERT INTO "iana_records" VALUES(2056,0,NULL,'eze','uzekwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2057,0,NULL,'faa','fasu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2058,0,NULL,'fab','fa d''ambu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2059,0,NULL,'fad','wagi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2060,0,NULL,'faf','fagani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2061,0,NULL,'fag','finongan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2062,0,NULL,'fah','baissa fali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2063,0,NULL,'fai','faiwol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2064,0,NULL,'faj','faita','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2065,0,NULL,'fak','fang (cameroon)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2066,0,NULL,'fal','south fali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2067,0,NULL,'fam','fam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2068,0,NULL,'fan','fang (equatorial guinea)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2069,0,NULL,'fap','palor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2070,0,NULL,'far','fataleka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2071,0,NULL,'fat','fanti','1129420800',NULL,NULL,NULL,NULL,'ak',NULL,NULL); +INSERT INTO "iana_records" VALUES(2072,0,NULL,'fau','fayu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2073,0,NULL,'fax','fala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2074,0,NULL,'fay','southwestern fars','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2075,0,NULL,'faz','northwestern fars','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2076,0,NULL,'fbl','west albay bikol','1268265600',NULL,NULL,NULL,NULL,'bik',NULL,NULL); +INSERT INTO "iana_records" VALUES(2077,0,NULL,'fcs','quebec sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2078,0,NULL,'fer','feroge','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2079,0,NULL,'ffi','foia foia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2080,0,NULL,'ffm','maasina fulfulde','1248825600',NULL,NULL,NULL,NULL,'ff',NULL,NULL); +INSERT INTO "iana_records" VALUES(2081,0,NULL,'fgr','fongoro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2082,0,NULL,'fia','nobiin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2083,0,NULL,'fie','fyer','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2084,0,NULL,'fil','filipino','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2084,0,NULL,'fil','pilipino','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2085,0,NULL,'fip','fipa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2086,0,NULL,'fir','firan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2087,0,NULL,'fit','tornedalen finnish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2088,0,NULL,'fiu','finno-ugrian languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2089,0,NULL,'fiw','fiwaga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2090,0,NULL,'fkv','kven finnish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2091,0,NULL,'fla','kalispel-pend d''oreille','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2092,0,NULL,'flh','foau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2093,0,NULL,'fli','fali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2094,0,NULL,'fll','north fali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2095,0,NULL,'fln','flinders island','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2096,0,NULL,'flr','fuliiru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2097,0,NULL,'fly','tsotsitaal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2098,0,NULL,'fmp','fe''fe''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2099,0,NULL,'fmu','far western muria','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2100,0,NULL,'fng','fanagalo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2101,0,NULL,'fni','fania','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2102,0,NULL,'fod','foodo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2103,0,NULL,'foi','foi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2104,0,NULL,'fom','foma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2105,0,NULL,'fon','fon','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2106,0,NULL,'for','fore','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2107,0,NULL,'fos','siraya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2108,0,NULL,'fox','formosan languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2109,0,NULL,'fpe','fernando po creole english','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2110,0,NULL,'fqs','fas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2111,0,NULL,'frc','cajun french','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2112,0,NULL,'frd','fordata','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2113,0,NULL,'frk','frankish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2114,0,NULL,'frm','middle french (ca. 1400-1600)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2115,0,NULL,'fro','old french (842-ca. 1400)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2116,0,NULL,'frp','arpitan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2116,0,NULL,'frp','francoprovençal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2117,0,NULL,'frq','forak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2118,0,NULL,'frr','northern frisian','1141776000',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2119,0,NULL,'frs','eastern frisian','1141776000',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2120,0,NULL,'frt','fortsenal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2121,0,NULL,'fse','finnish sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2122,0,NULL,'fsl','french sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2123,0,NULL,'fss','finland-swedish sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2123,0,NULL,'fss','finlandssvenskt teckensprÃ¥k','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2123,0,NULL,'fss','suomenruotsalainen viittomakieli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2124,0,NULL,'fub','adamawa fulfulde','1248825600',NULL,NULL,NULL,NULL,'ff',NULL,NULL); +INSERT INTO "iana_records" VALUES(2125,0,NULL,'fuc','pulaar','1248825600',NULL,NULL,NULL,NULL,'ff',NULL,NULL); +INSERT INTO "iana_records" VALUES(2126,0,NULL,'fud','east futuna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2127,0,NULL,'fue','borgu fulfulde','1248825600',NULL,NULL,NULL,NULL,'ff',NULL,NULL); +INSERT INTO "iana_records" VALUES(2128,0,NULL,'fuf','pular','1248825600',NULL,NULL,NULL,NULL,'ff',NULL,NULL); +INSERT INTO "iana_records" VALUES(2129,0,NULL,'fuh','western niger fulfulde','1248825600',NULL,NULL,NULL,NULL,'ff',NULL,NULL); +INSERT INTO "iana_records" VALUES(2130,0,NULL,'fui','bagirmi fulfulde','1248825600',NULL,NULL,NULL,NULL,'ff',NULL,NULL); +INSERT INTO "iana_records" VALUES(2131,0,NULL,'fuj','ko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2132,0,NULL,'fum','fum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2133,0,NULL,'fun','fulniô','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2134,0,NULL,'fuq','central-eastern niger fulfulde','1248825600',NULL,NULL,NULL,NULL,'ff',NULL,NULL); +INSERT INTO "iana_records" VALUES(2135,0,NULL,'fur','friulian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2136,0,NULL,'fut','futuna-aniwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2137,0,NULL,'fuu','furu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2138,0,NULL,'fuv','nigerian fulfulde','1248825600',NULL,NULL,NULL,NULL,'ff',NULL,NULL); +INSERT INTO "iana_records" VALUES(2139,0,NULL,'fuy','fuyug','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2140,0,NULL,'fvr','fur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2141,0,NULL,'fwa','fwâi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2142,0,NULL,'fwe','fwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2143,0,NULL,'gaa','ga','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2144,0,NULL,'gab','gabri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2145,0,NULL,'gac','mixed great andamanese','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2146,0,NULL,'gad','gaddang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2147,0,NULL,'gae','guarequena','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2148,0,NULL,'gaf','gende','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2149,0,NULL,'gag','gagauz','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2150,0,NULL,'gah','alekano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2151,0,NULL,'gai','borei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2152,0,NULL,'gaj','gadsup','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2153,0,NULL,'gak','gamkonora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2154,0,NULL,'gal','galoli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2155,0,NULL,'gam','kandawo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2156,0,NULL,'gan','gan chinese','1248825600',NULL,NULL,NULL,NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(2157,0,NULL,'gao','gants','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2158,0,NULL,'gap','gal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2159,0,NULL,'gaq','gata''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2160,0,NULL,'gar','galeya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2161,0,NULL,'gas','adiwasi garasia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2162,0,NULL,'gat','kenati','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2163,0,NULL,'gau','mudhili gadaba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2164,0,NULL,'gav','gabutamon','1248825600',1268265600,'dev',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2165,0,NULL,'gaw','nobonob','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2166,0,NULL,'gax','borana-arsi-guji oromo','1248825600',NULL,NULL,NULL,NULL,'om',NULL,NULL); +INSERT INTO "iana_records" VALUES(2167,0,NULL,'gay','gayo','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2168,0,NULL,'gaz','west central oromo','1248825600',NULL,NULL,NULL,NULL,'om',NULL,NULL); +INSERT INTO "iana_records" VALUES(2169,0,NULL,'gba','gbaya (central african republic)','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(2170,0,NULL,'gbb','kaytetye','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2171,0,NULL,'gbc','garawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2172,0,NULL,'gbd','karadjeri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2173,0,NULL,'gbe','niksek','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2174,0,NULL,'gbf','gaikundi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2175,0,NULL,'gbg','gbanziri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2176,0,NULL,'gbh','defi gbe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2177,0,NULL,'gbi','galela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2178,0,NULL,'gbj','bodo gadaba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2179,0,NULL,'gbk','gaddi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2180,0,NULL,'gbl','gamit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2181,0,NULL,'gbm','garhwali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2182,0,NULL,'gbn','mo''da','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2183,0,NULL,'gbo','northern grebo','1248825600',NULL,NULL,NULL,NULL,'grb',NULL,NULL); +INSERT INTO "iana_records" VALUES(2184,0,NULL,'gbp','gbaya-bossangoa','1248825600',NULL,NULL,NULL,NULL,'gba',NULL,NULL); +INSERT INTO "iana_records" VALUES(2185,0,NULL,'gbq','gbaya-bozoum','1248825600',NULL,NULL,NULL,NULL,'gba',NULL,NULL); +INSERT INTO "iana_records" VALUES(2186,0,NULL,'gbr','gbagyi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2187,0,NULL,'gbs','gbesi gbe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2188,0,NULL,'gbu','gagadu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2189,0,NULL,'gbv','gbanu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2190,0,NULL,'gbx','eastern xwla gbe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2191,0,NULL,'gby','gbari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2192,0,NULL,'gbz','zoroastrian dari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2193,0,NULL,'gcc','mali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2194,0,NULL,'gcd','ganggalida','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2195,0,NULL,'gce','galice','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2196,0,NULL,'gcf','guadeloupean creole french','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2197,0,NULL,'gcl','grenadian creole english','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2198,0,NULL,'gcn','gaina','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2199,0,NULL,'gcr','guianese creole french','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2200,0,NULL,'gct','colonia tovar german','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2201,0,NULL,'gda','gade lohar','1248825600',NULL,NULL,NULL,NULL,'raj',NULL,NULL); +INSERT INTO "iana_records" VALUES(2202,0,NULL,'gdb','pottangi ollar gadaba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2203,0,NULL,'gdc','gugu badhun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2204,0,NULL,'gdd','gedaged','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2205,0,NULL,'gde','gude','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2206,0,NULL,'gdf','guduf-gava','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2207,0,NULL,'gdg','ga''dang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2208,0,NULL,'gdh','gadjerawang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2209,0,NULL,'gdi','gundi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2210,0,NULL,'gdj','gurdjar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2211,0,NULL,'gdk','gadang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2212,0,NULL,'gdl','dirasha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2213,0,NULL,'gdm','laal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2214,0,NULL,'gdn','umanakaina','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2215,0,NULL,'gdo','ghodoberi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2216,0,NULL,'gdq','mehri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2217,0,NULL,'gdr','wipi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2218,0,NULL,'gdu','gudu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2219,0,NULL,'gdx','godwari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2220,0,NULL,'gea','geruma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2221,0,NULL,'geb','kire','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2222,0,NULL,'gec','gboloo grebo','1248825600',NULL,NULL,NULL,NULL,'grb',NULL,NULL); +INSERT INTO "iana_records" VALUES(2223,0,NULL,'ged','gade','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2224,0,NULL,'geg','gengle','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2225,0,NULL,'geh','hutterisch','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2225,0,NULL,'geh','hutterite german','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2226,0,NULL,'gei','gebe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2227,0,NULL,'gej','gen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2228,0,NULL,'gek','yiwom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2229,0,NULL,'gel','kag-fer-jiir-koor-ror-us-zuksun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2230,0,NULL,'gem','germanic languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2231,0,NULL,'geq','geme','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2232,0,NULL,'ges','geser-gorom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2233,0,NULL,'gew','gera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2234,0,NULL,'gex','garre','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2235,0,NULL,'gey','enya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2236,0,NULL,'gez','geez','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2237,0,NULL,'gfk','patpatar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2238,0,NULL,'gft','gafat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2239,0,NULL,'gga','gao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2240,0,NULL,'ggb','gbii','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2241,0,NULL,'ggd','gugadj','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2242,0,NULL,'gge','guragone','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2243,0,NULL,'ggg','gurgula','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2244,0,NULL,'ggk','kungarakany','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2245,0,NULL,'ggl','ganglau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2246,0,NULL,'ggn','eastern gurung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2247,0,NULL,'ggo','southern gondi','1248825600',NULL,NULL,NULL,NULL,'gon',NULL,NULL); +INSERT INTO "iana_records" VALUES(2248,0,NULL,'ggr','aghu tharnggalu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2249,0,NULL,'ggt','gitua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2250,0,NULL,'ggu','gagu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2251,0,NULL,'ggw','gogodala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2252,0,NULL,'gha','ghadamès','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2253,0,NULL,'ghc','hiberno-scottish gaelic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2254,0,NULL,'ghe','southern ghale','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2255,0,NULL,'ghh','northern ghale','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2256,0,NULL,'ghk','geko karen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2257,0,NULL,'ghl','ghulfan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2258,0,NULL,'ghn','ghanongga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2259,0,NULL,'gho','ghomara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2260,0,NULL,'ghr','ghera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2261,0,NULL,'ghs','guhu-samane','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2262,0,NULL,'ght','kutang ghale','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2263,0,NULL,'gia','kitja','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2264,0,NULL,'gib','gibanawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2265,0,NULL,'gic','gail','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2266,0,NULL,'gid','gidar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2267,0,NULL,'gig','goaria','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2268,0,NULL,'gil','gilbertese','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2269,0,NULL,'gim','gimi (eastern highlands)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2270,0,NULL,'gin','hinukh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2271,0,NULL,'gio','gelao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2272,0,NULL,'gip','gimi (west new britain)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2273,0,NULL,'giq','green gelao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2274,0,NULL,'gir','red gelao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2275,0,NULL,'gis','north giziga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2276,0,NULL,'git','gitxsan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2277,0,NULL,'giw','white gelao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2278,0,NULL,'gix','gilima','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2279,0,NULL,'giy','giyug','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2280,0,NULL,'giz','south giziga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2281,0,NULL,'gji','geji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2282,0,NULL,'gjk','kachi koli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2283,0,NULL,'gjn','gonja','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2284,0,NULL,'gju','gujari','1248825600',NULL,NULL,NULL,NULL,'raj',NULL,NULL); +INSERT INTO "iana_records" VALUES(2285,0,NULL,'gka','guya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2286,0,NULL,'gke','ndai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2287,0,NULL,'gkn','gokana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2288,0,NULL,'gkp','guinea kpelle','1248825600',NULL,NULL,NULL,NULL,'kpe',NULL,NULL); +INSERT INTO "iana_records" VALUES(2289,0,NULL,'glc','bon gula','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2290,0,NULL,'gld','nanai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2291,0,NULL,'glh','northwest pashayi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2292,0,NULL,'gli','guliguli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2293,0,NULL,'glj','gula iro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2294,0,NULL,'glk','gilaki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2295,0,NULL,'glo','galambu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2296,0,NULL,'glr','glaro-twabo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2297,0,NULL,'glu','gula (chad)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2298,0,NULL,'glw','glavda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2299,0,NULL,'gly','gule','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2300,0,NULL,'gma','gambera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2301,0,NULL,'gmb','gula''alaa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2302,0,NULL,'gmd','mághdì','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2303,0,NULL,'gme','east germanic languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2304,0,NULL,'gmh','middle high german (ca. 1050-1500)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2305,0,NULL,'gml','middle low german','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2306,0,NULL,'gmm','gbaya-mbodomo','1248825600',NULL,NULL,NULL,NULL,'gba',NULL,NULL); +INSERT INTO "iana_records" VALUES(2307,0,NULL,'gmn','gimnime','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2308,0,NULL,'gmq','north germanic languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2309,0,NULL,'gmu','gumalu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2310,0,NULL,'gmv','gamo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2311,0,NULL,'gmw','west germanic languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2312,0,NULL,'gmx','magoma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2313,0,NULL,'gmy','mycenaean greek','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2314,0,NULL,'gna','kaansa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2315,0,NULL,'gnb','gangte','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2316,0,NULL,'gnc','guanche','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2317,0,NULL,'gnd','zulgo-gemzek','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2318,0,NULL,'gne','ganang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2319,0,NULL,'gng','ngangam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2320,0,NULL,'gnh','lere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2321,0,NULL,'gni','gooniyandi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2322,0,NULL,'gnk','//gana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2323,0,NULL,'gnl','gangulu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2324,0,NULL,'gnm','ginuman','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2325,0,NULL,'gnn','gumatj','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2326,0,NULL,'gno','northern gondi','1248825600',NULL,NULL,NULL,NULL,'gon',NULL,NULL); +INSERT INTO "iana_records" VALUES(2327,0,NULL,'gnq','gana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2328,0,NULL,'gnr','gureng gureng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2329,0,NULL,'gnt','guntai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2330,0,NULL,'gnu','gnau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2331,0,NULL,'gnw','western bolivian guaraní','1248825600',NULL,NULL,NULL,NULL,'gn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2332,0,NULL,'gnz','ganzi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2333,0,NULL,'goa','guro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2334,0,NULL,'gob','playero','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2335,0,NULL,'goc','gorakor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2336,0,NULL,'god','godié','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2337,0,NULL,'goe','gongduk','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2338,0,NULL,'gof','gofa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2339,0,NULL,'gog','gogo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2340,0,NULL,'goh','old high german (ca. 750-1050)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2341,0,NULL,'goi','gobasi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2342,0,NULL,'goj','gowlan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2343,0,NULL,'gok','gowli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2344,0,NULL,'gol','gola','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2345,0,NULL,'gom','goan konkani','1248825600',NULL,NULL,NULL,NULL,'kok',NULL,NULL); +INSERT INTO "iana_records" VALUES(2346,0,NULL,'gon','gondi','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(2347,0,NULL,'goo','gone dau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2348,0,NULL,'gop','yeretuar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2349,0,NULL,'goq','gorap','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2350,0,NULL,'gor','gorontalo','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2351,0,NULL,'gos','gronings','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2352,0,NULL,'got','gothic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2353,0,NULL,'gou','gavar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2354,0,NULL,'gow','gorowa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2355,0,NULL,'gox','gobu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2356,0,NULL,'goy','goundo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2357,0,NULL,'goz','gozarkhani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2358,0,NULL,'gpa','gupa-abawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2359,0,NULL,'gpn','taiap','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2360,0,NULL,'gqa','ga''anda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2361,0,NULL,'gqi','guiqiong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2362,0,NULL,'gqn','guana (brazil)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2363,0,NULL,'gqr','gor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2364,0,NULL,'gra','rajput garasia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2365,0,NULL,'grb','grebo','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(2366,0,NULL,'grc','ancient greek (to 1453)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2367,0,NULL,'grd','guruntum-mbaaru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2368,0,NULL,'grg','madi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2369,0,NULL,'grh','gbiri-niragu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2370,0,NULL,'gri','ghari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2371,0,NULL,'grj','southern grebo','1248825600',NULL,NULL,NULL,NULL,'grb',NULL,NULL); +INSERT INTO "iana_records" VALUES(2372,0,NULL,'grk','greek languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2373,0,NULL,'grm','kota marudu talantang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2374,0,NULL,'gro','groma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2375,0,NULL,'grq','gorovu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2376,0,NULL,'grr','taznatit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2377,0,NULL,'grs','gresi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2378,0,NULL,'grt','garo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2379,0,NULL,'gru','kistane','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2380,0,NULL,'grv','central grebo','1248825600',NULL,NULL,NULL,NULL,'grb',NULL,NULL); +INSERT INTO "iana_records" VALUES(2381,0,NULL,'grw','gweda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2382,0,NULL,'grx','guriaso','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2383,0,NULL,'gry','barclayville grebo','1248825600',NULL,NULL,NULL,NULL,'grb',NULL,NULL); +INSERT INTO "iana_records" VALUES(2384,0,NULL,'grz','guramalum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2385,0,NULL,'gse','ghanaian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2386,0,NULL,'gsg','german sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2387,0,NULL,'gsl','gusilay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2388,0,NULL,'gsm','guatemalan sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2389,0,NULL,'gsn','gusan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2390,0,NULL,'gso','southwest gbaya','1248825600',NULL,NULL,NULL,NULL,'gba',NULL,NULL); +INSERT INTO "iana_records" VALUES(2391,0,NULL,'gsp','wasembo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2392,0,NULL,'gss','greek sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2393,0,NULL,'gsw','alemannic','1141776000',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2393,0,NULL,'gsw','alsatian','1141776000',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2393,0,NULL,'gsw','swiss german','1141776000',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2394,0,NULL,'gta','guató','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2395,0,NULL,'gti','gbati-ri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2396,0,NULL,'gua','shiki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2397,0,NULL,'gub','guajajára','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2398,0,NULL,'guc','wayuu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2399,0,NULL,'gud','yocoboué dida','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2400,0,NULL,'gue','gurinji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2401,0,NULL,'guf','gupapuyngu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2402,0,NULL,'gug','paraguayan guaraní','1248825600',NULL,NULL,NULL,NULL,'gn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2403,0,NULL,'guh','guahibo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2404,0,NULL,'gui','eastern bolivian guaraní','1248825600',NULL,NULL,NULL,NULL,'gn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2405,0,NULL,'guk','gumuz','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2406,0,NULL,'gul','sea island creole english','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2407,0,NULL,'gum','guambiano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2408,0,NULL,'gun','mbyá guaraní','1248825600',NULL,NULL,NULL,NULL,'gn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2409,0,NULL,'guo','guayabero','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2410,0,NULL,'gup','gunwinggu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2411,0,NULL,'guq','aché','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2412,0,NULL,'gur','farefare','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2413,0,NULL,'gus','guinean sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2414,0,NULL,'gut','maléku jaíka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2415,0,NULL,'guu','yanomamö','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2416,0,NULL,'guv','gey','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2417,0,NULL,'guw','gun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2418,0,NULL,'gux','gourmanchéma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2419,0,NULL,'guz','ekegusii','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2419,0,NULL,'guz','gusii','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2420,0,NULL,'gva','guana (paraguay)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2421,0,NULL,'gvc','guanano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2422,0,NULL,'gve','duwet','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2423,0,NULL,'gvf','golin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2424,0,NULL,'gvj','guajá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2425,0,NULL,'gvl','gulay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2426,0,NULL,'gvm','gurmana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2427,0,NULL,'gvn','kuku-yalanji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2428,0,NULL,'gvo','gavião do jiparaná','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2429,0,NULL,'gvp','pará gavião','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2430,0,NULL,'gvr','western gurung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2431,0,NULL,'gvs','gumawana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2432,0,NULL,'gvy','guyani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2433,0,NULL,'gwa','mbato','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2434,0,NULL,'gwb','gwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2435,0,NULL,'gwc','kalami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2436,0,NULL,'gwd','gawwada','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2437,0,NULL,'gwe','gweno','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2438,0,NULL,'gwf','gowro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2439,0,NULL,'gwg','moo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2440,0,NULL,'gwi','gwichʼin','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2441,0,NULL,'gwj','/gwi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2442,0,NULL,'gwn','gwandara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2443,0,NULL,'gwr','gwere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2444,0,NULL,'gwt','gawar-bati','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2445,0,NULL,'gwu','guwamu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2446,0,NULL,'gww','kwini','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2447,0,NULL,'gwx','gua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2448,0,NULL,'gxx','wè southern','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2449,0,NULL,'gya','northwest gbaya','1248825600',NULL,NULL,NULL,NULL,'gba',NULL,NULL); +INSERT INTO "iana_records" VALUES(2450,0,NULL,'gyb','garus','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2451,0,NULL,'gyd','kayardild','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2452,0,NULL,'gye','gyem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2453,0,NULL,'gyf','gungabula','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2454,0,NULL,'gyg','gbayi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2455,0,NULL,'gyi','gyele','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2456,0,NULL,'gyl','gayil','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2457,0,NULL,'gym','ngäbere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2458,0,NULL,'gyn','guyanese creole english','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2459,0,NULL,'gyr','guarayu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2460,0,NULL,'gyy','gunya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2461,0,NULL,'gza','ganza','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2462,0,NULL,'gzi','gazi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2463,0,NULL,'gzn','gane','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2464,0,NULL,'haa','han','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2465,0,NULL,'hab','hanoi sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2466,0,NULL,'hac','gurani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2467,0,NULL,'had','hatam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2468,0,NULL,'hae','eastern oromo','1248825600',NULL,NULL,NULL,NULL,'om',NULL,NULL); +INSERT INTO "iana_records" VALUES(2469,0,NULL,'haf','haiphong sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2470,0,NULL,'hag','hanga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2471,0,NULL,'hah','hahon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2472,0,NULL,'hai','haida','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(2473,0,NULL,'haj','hajong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2474,0,NULL,'hak','hakka chinese','1248825600',NULL,NULL,NULL,NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(2475,0,NULL,'hal','halang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2476,0,NULL,'ham','hewa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2477,0,NULL,'han','hangaza','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2478,0,NULL,'hao','hakö','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2479,0,NULL,'hap','hupla','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2480,0,NULL,'haq','ha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2481,0,NULL,'har','harari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2482,0,NULL,'has','haisla','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2483,0,NULL,'hav','havu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2484,0,NULL,'haw','hawaiian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2485,0,NULL,'hax','southern haida','1248825600',NULL,NULL,NULL,NULL,'hai',NULL,NULL); +INSERT INTO "iana_records" VALUES(2486,0,NULL,'hay','haya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2487,0,NULL,'haz','hazaragi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2488,0,NULL,'hba','hamba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2489,0,NULL,'hbb','huba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2490,0,NULL,'hbn','heiban','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2491,0,NULL,'hbo','ancient hebrew','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2492,0,NULL,'hbu','habu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2493,0,NULL,'hca','andaman creole hindi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2494,0,NULL,'hch','huichol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2495,0,NULL,'hdn','northern haida','1248825600',NULL,NULL,NULL,NULL,'hai',NULL,NULL); +INSERT INTO "iana_records" VALUES(2496,0,NULL,'hds','honduras sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2497,0,NULL,'hdy','hadiyya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2498,0,NULL,'hea','northern qiandong miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2499,0,NULL,'hed','herdé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2500,0,NULL,'heg','helong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2501,0,NULL,'heh','hehe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2502,0,NULL,'hei','heiltsuk','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2503,0,NULL,'hem','hemba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2504,0,NULL,'hgm','hai//om','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2505,0,NULL,'hgw','haigwai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2506,0,NULL,'hhi','hoia hoia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2507,0,NULL,'hhr','kerak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2508,0,NULL,'hhy','hoyahoya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2509,0,NULL,'hia','lamang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2510,0,NULL,'hib','hibito','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2511,0,NULL,'hid','hidatsa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2512,0,NULL,'hif','fiji hindi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2513,0,NULL,'hig','kamwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2514,0,NULL,'hih','pamosu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2515,0,NULL,'hii','hinduri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2516,0,NULL,'hij','hijuk','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2517,0,NULL,'hik','seit-kaitetu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2518,0,NULL,'hil','hiligaynon','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2519,0,NULL,'him','himachali languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2519,0,NULL,'him','western pahari languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2520,0,NULL,'hio','tsoa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2521,0,NULL,'hir','himarimã','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2522,0,NULL,'hit','hittite','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2523,0,NULL,'hiw','hiw','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2524,0,NULL,'hix','hixkaryána','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2525,0,NULL,'hji','haji','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(2526,0,NULL,'hka','kahe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2527,0,NULL,'hke','hunde','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2528,0,NULL,'hkk','hunjara-kaina ke','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2529,0,NULL,'hks','heung kong sau yue','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2529,0,NULL,'hks','hong kong sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2530,0,NULL,'hla','halia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2531,0,NULL,'hlb','halbi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2532,0,NULL,'hld','halang doan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2533,0,NULL,'hle','hlersu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2534,0,NULL,'hlt','nga la','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2535,0,NULL,'hlu','hieroglyphic luwian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2536,0,NULL,'hma','southern mashan hmong','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2536,0,NULL,'hma','southern mashan miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2537,0,NULL,'hmb','humburi senni songhay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2538,0,NULL,'hmc','central huishui hmong','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2538,0,NULL,'hmc','central huishui miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2539,0,NULL,'hmd','a-hmaos','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2539,0,NULL,'hmd','da-hua miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2539,0,NULL,'hmd','large flowery miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2540,0,NULL,'hme','eastern huishui hmong','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2540,0,NULL,'hme','eastern huishui miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2541,0,NULL,'hmf','hmong don','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2542,0,NULL,'hmg','southwestern guiyang hmong','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2543,0,NULL,'hmh','southwestern huishui hmong','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2543,0,NULL,'hmh','southwestern huishui miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2544,0,NULL,'hmi','northern huishui hmong','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2544,0,NULL,'hmi','northern huishui miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2545,0,NULL,'hmj','ge','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2545,0,NULL,'hmj','gejia','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2546,0,NULL,'hmk','maek','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2547,0,NULL,'hml','luopohe hmong','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2547,0,NULL,'hml','luopohe miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2548,0,NULL,'hmm','central mashan hmong','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2548,0,NULL,'hmm','central mashan miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2549,0,NULL,'hmn','hmong','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(2549,0,NULL,'hmn','mong','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(2550,0,NULL,'hmp','northern mashan hmong','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2550,0,NULL,'hmp','northern mashan miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2551,0,NULL,'hmq','eastern qiandong miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2552,0,NULL,'hmr','hmar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2553,0,NULL,'hms','southern qiandong miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2554,0,NULL,'hmt','hamtai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2555,0,NULL,'hmu','hamap','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2556,0,NULL,'hmv','hmong dô','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2557,0,NULL,'hmw','western mashan hmong','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2557,0,NULL,'hmw','western mashan miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2558,0,NULL,'hmx','hmong-mien languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2559,0,NULL,'hmy','southern guiyang hmong','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2559,0,NULL,'hmy','southern guiyang miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2560,0,NULL,'hmz','hmong shua','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2560,0,NULL,'hmz','sinicized miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2561,0,NULL,'hna','mina (cameroon)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2562,0,NULL,'hnd','southern hindko','1248825600',NULL,NULL,NULL,NULL,'lah',NULL,NULL); +INSERT INTO "iana_records" VALUES(2563,0,NULL,'hne','chhattisgarhi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2564,0,NULL,'hnh','//ani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2565,0,NULL,'hni','hani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2566,0,NULL,'hnj','hmong njua','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2566,0,NULL,'hnj','mong leng','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2566,0,NULL,'hnj','mong njua','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2567,0,NULL,'hnn','hanunoo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2568,0,NULL,'hno','northern hindko','1248825600',NULL,NULL,NULL,NULL,'lah',NULL,NULL); +INSERT INTO "iana_records" VALUES(2569,0,NULL,'hns','caribbean hindustani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2570,0,NULL,'hnu','hung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2571,0,NULL,'hoa','hoava','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2572,0,NULL,'hob','mari (madang province)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2573,0,NULL,'hoc','ho','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2574,0,NULL,'hod','holma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2575,0,NULL,'hoe','horom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2576,0,NULL,'hoh','hobyót','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2577,0,NULL,'hoi','holikachuk','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2578,0,NULL,'hoj','hadothi','1248825600',NULL,NULL,NULL,NULL,'raj',NULL,NULL); +INSERT INTO "iana_records" VALUES(2579,0,NULL,'hok','hokan languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2580,0,NULL,'hol','holu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2581,0,NULL,'hom','homa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2582,0,NULL,'hoo','holoholo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2583,0,NULL,'hop','hopi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2584,0,NULL,'hor','horo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2585,0,NULL,'hos','ho chi minh city sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2586,0,NULL,'hot','hote','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2586,0,NULL,'hot','malê','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2587,0,NULL,'hov','hovongan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2588,0,NULL,'how','honi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2589,0,NULL,'hoy','holiya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2590,0,NULL,'hoz','hozo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2591,0,NULL,'hpo','hpon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2592,0,NULL,'hps','hawai''i pidgin sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2593,0,NULL,'hra','hrangkhol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2594,0,NULL,'hre','hre','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2595,0,NULL,'hrk','haruku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2596,0,NULL,'hrm','horned miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2597,0,NULL,'hro','haroi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2598,0,NULL,'hrr','horuru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2599,0,NULL,'hrt','hértevin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2600,0,NULL,'hru','hruso','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2601,0,NULL,'hrx','hunsrik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2602,0,NULL,'hrz','harzani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2603,0,NULL,'hsb','upper sorbian','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2604,0,NULL,'hsh','hungarian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2605,0,NULL,'hsl','hausa sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2606,0,NULL,'hsn','xiang chinese','1248825600',NULL,NULL,NULL,NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(2607,0,NULL,'hss','harsusi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2608,0,NULL,'hti','hoti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2609,0,NULL,'hto','minica huitoto','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2610,0,NULL,'hts','hadza','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2611,0,NULL,'htu','hitu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2612,0,NULL,'htx','middle hittite','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2613,0,NULL,'hub','huambisa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2614,0,NULL,'huc','=/hua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2615,0,NULL,'hud','huaulu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2616,0,NULL,'hue','san francisco del mar huave','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2617,0,NULL,'huf','humene','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2618,0,NULL,'hug','huachipaeri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2619,0,NULL,'huh','huilliche','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2620,0,NULL,'hui','huli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2621,0,NULL,'huj','northern guiyang hmong','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2621,0,NULL,'huj','northern guiyang miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2622,0,NULL,'huk','hulung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2623,0,NULL,'hul','hula','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2624,0,NULL,'hum','hungana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2625,0,NULL,'huo','hu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2626,0,NULL,'hup','hupa','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2627,0,NULL,'huq','tsat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2628,0,NULL,'hur','halkomelem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2629,0,NULL,'hus','huastec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2630,0,NULL,'hut','humla','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2631,0,NULL,'huu','murui huitoto','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2632,0,NULL,'huv','san mateo del mar huave','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2633,0,NULL,'huw','hukumina','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2634,0,NULL,'hux','nüpode huitoto','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2635,0,NULL,'huy','hulaulá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2636,0,NULL,'huz','hunzib','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2637,0,NULL,'hvc','haitian vodoun culture language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2638,0,NULL,'hve','san dionisio del mar huave','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2639,0,NULL,'hvk','haveke','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2640,0,NULL,'hvn','sabu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2641,0,NULL,'hvv','santa maría del mar huave','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2642,0,NULL,'hwa','wané','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2643,0,NULL,'hwc','hawai''i creole english','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2644,0,NULL,'hwo','hwana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2645,0,NULL,'hya','hya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2646,0,NULL,'hyx','armenian (family)','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2647,0,NULL,'iai','iaai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2648,0,NULL,'ian','iatmul','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2649,0,NULL,'iap','iapama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2650,0,NULL,'iar','purari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2651,0,NULL,'iba','iban','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2652,0,NULL,'ibb','ibibio','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2653,0,NULL,'ibd','iwaidja','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2654,0,NULL,'ibe','akpes','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2655,0,NULL,'ibg','ibanag','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2656,0,NULL,'ibi','ibilo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2657,0,NULL,'ibl','ibaloi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2658,0,NULL,'ibm','agoi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2659,0,NULL,'ibn','ibino','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2660,0,NULL,'ibr','ibuoro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2661,0,NULL,'ibu','ibu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2662,0,NULL,'iby','ibani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2663,0,NULL,'ica','ede ica','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2664,0,NULL,'ich','etkywan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2665,0,NULL,'icl','icelandic sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2666,0,NULL,'icr','islander creole english','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2667,0,NULL,'ida','idakho-isukha-tiriki','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(2667,0,NULL,'ida','luidakho-luisukha-lutirichi','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(2668,0,NULL,'idb','indo-portuguese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2669,0,NULL,'idc','idon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2670,0,NULL,'idd','ede idaca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2671,0,NULL,'ide','idere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2672,0,NULL,'idi','idi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2673,0,NULL,'idr','indri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2674,0,NULL,'ids','idesa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2675,0,NULL,'idt','idaté','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2676,0,NULL,'idu','idoma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2677,0,NULL,'ifa','amganad ifugao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2678,0,NULL,'ifb','ayangan ifugao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2678,0,NULL,'ifb','batad ifugao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2679,0,NULL,'ife','ifè','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2680,0,NULL,'iff','ifo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2681,0,NULL,'ifk','tuwali ifugao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2682,0,NULL,'ifm','teke-fuumu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2683,0,NULL,'ifu','mayoyao ifugao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2684,0,NULL,'ify','keley-i kallahan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2685,0,NULL,'igb','ebira','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2686,0,NULL,'ige','igede','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2687,0,NULL,'igg','igana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2688,0,NULL,'igl','igala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2689,0,NULL,'igm','kanggape','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2690,0,NULL,'ign','ignaciano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2691,0,NULL,'igo','isebe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2692,0,NULL,'igs','interglossa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2693,0,NULL,'igw','igwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2694,0,NULL,'ihb','iha based pidgin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2695,0,NULL,'ihi','ihievbe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2696,0,NULL,'ihp','iha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2697,0,NULL,'iir','indo-iranian languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2698,0,NULL,'ijc','izon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2699,0,NULL,'ije','biseni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2700,0,NULL,'ijj','ede ije','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2701,0,NULL,'ijn','kalabari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2702,0,NULL,'ijo','ijo languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2703,0,NULL,'ijs','southeast ijo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2704,0,NULL,'ike','eastern canadian inuktitut','1248825600',NULL,NULL,NULL,NULL,'iu',NULL,NULL); +INSERT INTO "iana_records" VALUES(2705,0,NULL,'iki','iko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2706,0,NULL,'ikk','ika','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2707,0,NULL,'ikl','ikulu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2708,0,NULL,'iko','olulumo-ikom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2709,0,NULL,'ikp','ikpeshi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2710,0,NULL,'ikt','western canadian inuktitut','1248825600',NULL,NULL,NULL,NULL,'iu',NULL,NULL); +INSERT INTO "iana_records" VALUES(2711,0,NULL,'ikv','iku-gora-ankwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2712,0,NULL,'ikw','ikwere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2713,0,NULL,'ikx','ik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2714,0,NULL,'ikz','ikizu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2715,0,NULL,'ila','ile ape','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2716,0,NULL,'ilb','ila','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2717,0,NULL,'ilg','garig-ilgar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2718,0,NULL,'ili','ili turki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2719,0,NULL,'ilk','ilongot','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2720,0,NULL,'ill','iranun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2721,0,NULL,'ilo','iloko','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2722,0,NULL,'ils','international sign','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2723,0,NULL,'ilu','ili''uun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2724,0,NULL,'ilv','ilue','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2725,0,NULL,'ilw','talur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2726,0,NULL,'ima','mala malasar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2727,0,NULL,'ime','imeraguen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2728,0,NULL,'imi','anamgura','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2729,0,NULL,'iml','miluk','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2730,0,NULL,'imn','imonda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2731,0,NULL,'imo','imbongu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2732,0,NULL,'imr','imroing','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2733,0,NULL,'ims','marsian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2734,0,NULL,'imy','milyan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2735,0,NULL,'inb','inga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2736,0,NULL,'inc','indic languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2737,0,NULL,'ine','indo-european languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2738,0,NULL,'ing','degexit''an','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2739,0,NULL,'inh','ingush','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2740,0,NULL,'inj','jungle inga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2741,0,NULL,'inl','indonesian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2742,0,NULL,'inm','minaean','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2743,0,NULL,'inn','isinai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2744,0,NULL,'ino','inoke-yate','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2745,0,NULL,'inp','iñapari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2746,0,NULL,'ins','indian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2747,0,NULL,'int','intha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2748,0,NULL,'inz','ineseño','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2749,0,NULL,'ior','inor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2750,0,NULL,'iou','tuma-irumu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2751,0,NULL,'iow','iowa-oto','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2752,0,NULL,'ipi','ipili','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2753,0,NULL,'ipo','ipiko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2754,0,NULL,'iqu','iquito','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2755,0,NULL,'ira','iranian languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2756,0,NULL,'ire','iresim','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2757,0,NULL,'irh','irarutu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2758,0,NULL,'iri','irigwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2759,0,NULL,'irk','iraqw','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2760,0,NULL,'irn','irántxe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2761,0,NULL,'iro','iroquoian languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2762,0,NULL,'irr','ir','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2763,0,NULL,'iru','irula','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2764,0,NULL,'irx','kamberau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2765,0,NULL,'iry','iraya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2766,0,NULL,'isa','isabi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2767,0,NULL,'isc','isconahua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2768,0,NULL,'isd','isnag','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2769,0,NULL,'ise','italian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2770,0,NULL,'isg','irish sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2771,0,NULL,'ish','esan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2772,0,NULL,'isi','nkem-nkum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2773,0,NULL,'isk','ishkashimi','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2774,0,NULL,'ism','masimasi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2775,0,NULL,'isn','isanzu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2776,0,NULL,'iso','isoko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2777,0,NULL,'isr','israeli sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2778,0,NULL,'ist','istriot','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2779,0,NULL,'isu','isu (menchum division)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2780,0,NULL,'itb','binongan itneg','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2781,0,NULL,'itc','italic languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2782,0,NULL,'ite','itene','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2783,0,NULL,'iti','inlaod itneg','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2784,0,NULL,'itk','judeo-italian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2785,0,NULL,'itl','itelmen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2786,0,NULL,'itm','itu mbon uzo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2787,0,NULL,'ito','itonama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2788,0,NULL,'itr','iteri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2789,0,NULL,'its','isekiri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2790,0,NULL,'itt','maeng itneg','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2791,0,NULL,'itv','itawit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2792,0,NULL,'itw','ito','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2793,0,NULL,'itx','itik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2794,0,NULL,'ity','moyadan itneg','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2795,0,NULL,'itz','itzá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2796,0,NULL,'ium','iu mien','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2797,0,NULL,'ivb','ibatan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2798,0,NULL,'ivv','ivatan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2799,0,NULL,'iwk','i-wak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2800,0,NULL,'iwm','iwam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2801,0,NULL,'iwo','iwur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2802,0,NULL,'iws','sepik iwam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2803,0,NULL,'ixc','ixcatec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2804,0,NULL,'ixl','ixil','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2805,0,NULL,'iya','iyayu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2806,0,NULL,'iyo','mesaka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2807,0,NULL,'iyx','yaka (congo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2808,0,NULL,'izh','ingrian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2809,0,NULL,'izi','izi-ezaa-ikwo-mgbo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2810,0,NULL,'izr','izere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2811,0,NULL,'jaa','jamamadí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2812,0,NULL,'jab','hyam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2813,0,NULL,'jac','jakalteko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2813,0,NULL,'jac','popti''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2814,0,NULL,'jad','jahanka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2815,0,NULL,'jae','yabem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2816,0,NULL,'jaf','jara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2817,0,NULL,'jah','jah hut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2818,0,NULL,'jaj','zazao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2819,0,NULL,'jak','jakun','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(2820,0,NULL,'jal','yalahatan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2821,0,NULL,'jam','jamaican creole english','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2822,0,NULL,'jao','yanyuwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2823,0,NULL,'jaq','yaqay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2824,0,NULL,'jar','jarawa (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2825,0,NULL,'jas','new caledonian javanese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2826,0,NULL,'jat','jakati','1248825600',NULL,NULL,NULL,NULL,'lah',NULL,NULL); +INSERT INTO "iana_records" VALUES(2827,0,NULL,'jau','yaur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2828,0,NULL,'jax','jambi malay','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(2829,0,NULL,'jay','yan-nhangu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2830,0,NULL,'jaz','jawe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2831,0,NULL,'jbe','judeo-berber','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2832,0,NULL,'jbj','arandai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2833,0,NULL,'jbn','nafusi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2834,0,NULL,'jbo','lojban','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2835,0,NULL,'jbr','jofotek-bromnya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2836,0,NULL,'jbt','jabutí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2837,0,NULL,'jbu','jukun takum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2838,0,NULL,'jcs','jamaican country sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2839,0,NULL,'jct','krymchak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2840,0,NULL,'jda','jad','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2841,0,NULL,'jdg','jadgali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2842,0,NULL,'jdt','judeo-tat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2843,0,NULL,'jeb','jebero','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2844,0,NULL,'jee','jerung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2845,0,NULL,'jeg','jeng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2846,0,NULL,'jeh','jeh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2847,0,NULL,'jei','yei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2848,0,NULL,'jek','jeri kuo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2849,0,NULL,'jel','yelmek','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2850,0,NULL,'jen','dza','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2851,0,NULL,'jer','jere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2852,0,NULL,'jet','manem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2853,0,NULL,'jeu','jonkor bourmataguil','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2854,0,NULL,'jgb','ngbee','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2855,0,NULL,'jge','judeo-georgian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2856,0,NULL,'jgo','ngomba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2857,0,NULL,'jhi','jehai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2858,0,NULL,'jhs','jhankot sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2859,0,NULL,'jia','jina','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2860,0,NULL,'jib','jibu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2861,0,NULL,'jic','tol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2862,0,NULL,'jid','bu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2863,0,NULL,'jie','jilbe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2864,0,NULL,'jig','djingili','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2865,0,NULL,'jih','shangzhai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2866,0,NULL,'jii','jiiddu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2867,0,NULL,'jil','jilim','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2868,0,NULL,'jim','jimi (cameroon)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2869,0,NULL,'jio','jiamao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2870,0,NULL,'jiq','guanyinqiao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2871,0,NULL,'jit','jita','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2872,0,NULL,'jiu','youle jinuo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2873,0,NULL,'jiv','shuar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2874,0,NULL,'jiy','buyuan jinuo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2875,0,NULL,'jko','kubo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2876,0,NULL,'jku','labir','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2877,0,NULL,'jle','ngile','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2878,0,NULL,'jls','jamaican sign language','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2879,0,NULL,'jma','dima','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2880,0,NULL,'jmb','zumbun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2881,0,NULL,'jmc','machame','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2882,0,NULL,'jmd','yamdena','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2883,0,NULL,'jmi','jimi (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2884,0,NULL,'jml','jumli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2885,0,NULL,'jmn','makuri naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2886,0,NULL,'jmr','kamara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2887,0,NULL,'jms','mashi (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2888,0,NULL,'jmx','western juxtlahuaca mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2889,0,NULL,'jna','jangshung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2890,0,NULL,'jnd','jandavra','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2891,0,NULL,'jng','yangman','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2892,0,NULL,'jni','janji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2893,0,NULL,'jnj','yemsa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2894,0,NULL,'jnl','rawat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2895,0,NULL,'jns','jaunsari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2896,0,NULL,'job','joba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2897,0,NULL,'jod','wojenaka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2898,0,NULL,'jor','jorá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2899,0,NULL,'jos','jordanian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2900,0,NULL,'jow','jowulu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2901,0,NULL,'jpa','jewish palestinian aramaic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2902,0,NULL,'jpr','judeo-persian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2903,0,NULL,'jpx','japanese (family)','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2904,0,NULL,'jqr','jaqaru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2905,0,NULL,'jra','jarai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2906,0,NULL,'jrb','judeo-arabic','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(2907,0,NULL,'jrr','jiru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2908,0,NULL,'jrt','jorto','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2909,0,NULL,'jru','japrería','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2910,0,NULL,'jsl','japanese sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2911,0,NULL,'jua','júma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2912,0,NULL,'jub','wannu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2913,0,NULL,'juc','jurchen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2914,0,NULL,'jud','worodougou','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2915,0,NULL,'juh','hõne','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2916,0,NULL,'juk','wapan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2917,0,NULL,'jul','jirel','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2918,0,NULL,'jum','jumjum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2919,0,NULL,'jun','juang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2920,0,NULL,'juo','jiba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2921,0,NULL,'jup','hupdë','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2922,0,NULL,'jur','jurúna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2923,0,NULL,'jus','jumla sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2924,0,NULL,'jut','jutish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2925,0,NULL,'juu','ju','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2926,0,NULL,'juw','wãpha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2927,0,NULL,'juy','juray','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2928,0,NULL,'jvd','javindo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2929,0,NULL,'jvn','caribbean javanese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2930,0,NULL,'jwi','jwira-pepesa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2931,0,NULL,'jya','jiarong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2932,0,NULL,'jye','judeo-yemeni arabic','1248825600',NULL,NULL,NULL,NULL,'jrb',NULL,NULL); +INSERT INTO "iana_records" VALUES(2933,0,NULL,'jyy','jaya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2934,0,NULL,'kaa','kara-kalpak','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2935,0,NULL,'kab','kabyle','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2936,0,NULL,'kac','jingpho','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2936,0,NULL,'kac','kachin','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2937,0,NULL,'kad','kadara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2938,0,NULL,'kae','ketangalan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2939,0,NULL,'kaf','katso','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2940,0,NULL,'kag','kajaman','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2941,0,NULL,'kah','kara (central african republic)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2942,0,NULL,'kai','karekare','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2943,0,NULL,'kaj','jju','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2944,0,NULL,'kak','kayapa kallahan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2945,0,NULL,'kam','kamba (kenya)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2946,0,NULL,'kao','xaasongaxango','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2947,0,NULL,'kap','bezhta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2948,0,NULL,'kaq','capanahua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2949,0,NULL,'kar','karen languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2950,0,NULL,'kav','katukína','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2951,0,NULL,'kaw','kawi','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2952,0,NULL,'kax','kao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2953,0,NULL,'kay','kamayurá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2954,0,NULL,'kba','kalarko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2955,0,NULL,'kbb','kaxuiâna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2956,0,NULL,'kbc','kadiwéu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2957,0,NULL,'kbd','kabardian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2958,0,NULL,'kbe','kanju','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2959,0,NULL,'kbf','kakauhua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2960,0,NULL,'kbg','khamba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2961,0,NULL,'kbh','camsá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2962,0,NULL,'kbi','kaptiau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2963,0,NULL,'kbj','kari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2964,0,NULL,'kbk','grass koiari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2965,0,NULL,'kbl','kanembu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2966,0,NULL,'kbm','iwal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2967,0,NULL,'kbn','kare (central african republic)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2968,0,NULL,'kbo','keliko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2969,0,NULL,'kbp','kabiyè','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2970,0,NULL,'kbq','kamano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2971,0,NULL,'kbr','kafa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2972,0,NULL,'kbs','kande','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2973,0,NULL,'kbt','abadi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2974,0,NULL,'kbu','kabutra','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2975,0,NULL,'kbv','dera (indonesia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2976,0,NULL,'kbw','kaiep','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2977,0,NULL,'kbx','ap ma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2978,0,NULL,'kby','manga kanuri','1248825600',NULL,NULL,NULL,NULL,'kr',NULL,NULL); +INSERT INTO "iana_records" VALUES(2979,0,NULL,'kbz','duhwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2980,0,NULL,'kca','khanty','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2981,0,NULL,'kcb','kawacha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2982,0,NULL,'kcc','lubila','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2983,0,NULL,'kcd','ngkâlmpw kanum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2984,0,NULL,'kce','kaivi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2985,0,NULL,'kcf','ukaan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2986,0,NULL,'kcg','tyap','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2987,0,NULL,'kch','vono','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2988,0,NULL,'kci','kamantan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2989,0,NULL,'kcj','kobiana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2990,0,NULL,'kck','kalanga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2991,0,NULL,'kcl','kela (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2992,0,NULL,'kcm','gula (central african republic)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2993,0,NULL,'kcn','nubi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2994,0,NULL,'kco','kinalakna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2995,0,NULL,'kcp','kanga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2996,0,NULL,'kcq','kamo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2997,0,NULL,'kcr','katla','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2998,0,NULL,'kcs','koenoem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2999,0,NULL,'kct','kaian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3000,0,NULL,'kcu','kami (tanzania)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3001,0,NULL,'kcv','kete','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3002,0,NULL,'kcw','kabwari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3003,0,NULL,'kcx','kachama-ganjule','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3004,0,NULL,'kcy','korandje','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3005,0,NULL,'kcz','konongo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3006,0,NULL,'kda','worimi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3007,0,NULL,'kdc','kutu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3008,0,NULL,'kdd','yankunytjatjara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3009,0,NULL,'kde','makonde','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3010,0,NULL,'kdf','mamusi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3011,0,NULL,'kdg','seba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3012,0,NULL,'kdh','tem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3013,0,NULL,'kdi','kumam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3014,0,NULL,'kdj','karamojong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3015,0,NULL,'kdk','numee','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3016,0,NULL,'kdl','tsikimba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3017,0,NULL,'kdm','kagoma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3018,0,NULL,'kdn','kunda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3019,0,NULL,'kdo','kordofanian languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(3020,0,NULL,'kdp','kaningdon-nindem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3021,0,NULL,'kdq','koch','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3022,0,NULL,'kdr','karaim','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3023,0,NULL,'kdt','kuy','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3024,0,NULL,'kdu','kadaru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3025,0,NULL,'kdv','kado','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3026,0,NULL,'kdw','koneraw','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3027,0,NULL,'kdx','kam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3028,0,NULL,'kdy','keder','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3028,0,NULL,'kdy','keijar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3029,0,NULL,'kdz','kwaja','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3030,0,NULL,'kea','kabuverdianu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3031,0,NULL,'keb','kélé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3032,0,NULL,'kec','keiga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3033,0,NULL,'ked','kerewe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3034,0,NULL,'kee','eastern keres','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3035,0,NULL,'kef','kpessi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3036,0,NULL,'keg','tese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3037,0,NULL,'keh','keak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3038,0,NULL,'kei','kei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3039,0,NULL,'kej','kadar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3040,0,NULL,'kek','kekchí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3041,0,NULL,'kel','kela (democratic republic of congo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3042,0,NULL,'kem','kemak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3043,0,NULL,'ken','kenyang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3044,0,NULL,'keo','kakwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3045,0,NULL,'kep','kaikadi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3046,0,NULL,'keq','kamar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3047,0,NULL,'ker','kera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3048,0,NULL,'kes','kugbo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3049,0,NULL,'ket','ket','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3050,0,NULL,'keu','akebu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3051,0,NULL,'kev','kanikkaran','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3052,0,NULL,'kew','west kewa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3053,0,NULL,'kex','kukna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3054,0,NULL,'key','kupia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3055,0,NULL,'kez','kukele','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3056,0,NULL,'kfa','kodava','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3057,0,NULL,'kfb','northwestern kolami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3058,0,NULL,'kfc','konda-dora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3059,0,NULL,'kfd','korra koraga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3060,0,NULL,'kfe','kota (india)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3061,0,NULL,'kff','koya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3062,0,NULL,'kfg','kudiya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3063,0,NULL,'kfh','kurichiya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3064,0,NULL,'kfi','kannada kurumba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3065,0,NULL,'kfj','kemiehua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3066,0,NULL,'kfk','kinnauri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3067,0,NULL,'kfl','kung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3068,0,NULL,'kfm','khunsari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3069,0,NULL,'kfn','kuk','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3070,0,NULL,'kfo','koro (côte d''ivoire)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3071,0,NULL,'kfp','korwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3072,0,NULL,'kfq','korku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3073,0,NULL,'kfr','kachchi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3074,0,NULL,'kfs','bilaspuri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3075,0,NULL,'kft','kanjari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3076,0,NULL,'kfu','katkari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3077,0,NULL,'kfv','kurmukar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3078,0,NULL,'kfw','kharam naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3079,0,NULL,'kfx','kullu pahari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3080,0,NULL,'kfy','kumaoni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3081,0,NULL,'kfz','koromfé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3082,0,NULL,'kga','koyaga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3083,0,NULL,'kgb','kawe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3084,0,NULL,'kgc','kasseng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3085,0,NULL,'kgd','kataang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3086,0,NULL,'kge','komering','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3087,0,NULL,'kgf','kube','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3088,0,NULL,'kgg','kusunda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3089,0,NULL,'kgh','upper tanudan kalinga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3090,0,NULL,'kgi','selangor sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3091,0,NULL,'kgj','gamale kham','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3092,0,NULL,'kgk','kaiwá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3093,0,NULL,'kgl','kunggari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3094,0,NULL,'kgm','karipúna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3095,0,NULL,'kgn','karingani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3096,0,NULL,'kgo','krongo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3097,0,NULL,'kgp','kaingang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3098,0,NULL,'kgq','kamoro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3099,0,NULL,'kgr','abun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3100,0,NULL,'kgs','kumbainggar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3101,0,NULL,'kgt','somyev','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3102,0,NULL,'kgu','kobol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3103,0,NULL,'kgv','karas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3104,0,NULL,'kgw','karon dori','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3105,0,NULL,'kgx','kamaru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3106,0,NULL,'kgy','kyerung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3107,0,NULL,'kha','khasi','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,'as of 2008-04-21 this subtag does not include lyngngam; see lyg'); +INSERT INTO "iana_records" VALUES(3108,0,NULL,'khb','lü','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3109,0,NULL,'khc','tukang besi north','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3110,0,NULL,'khd','bädi kanum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3111,0,NULL,'khe','korowai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3112,0,NULL,'khf','khuen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3113,0,NULL,'khg','khams tibetan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3114,0,NULL,'khh','kehu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3115,0,NULL,'khi','khoisan languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(3116,0,NULL,'khj','kuturmi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3117,0,NULL,'khk','halh mongolian','1248825600',NULL,NULL,NULL,NULL,'mn',NULL,NULL); +INSERT INTO "iana_records" VALUES(3118,0,NULL,'khl','lusi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3119,0,NULL,'khn','khandesi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3120,0,NULL,'kho','khotanese','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3120,0,NULL,'kho','sakan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3121,0,NULL,'khp','kapauri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3121,0,NULL,'khp','kapori','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3122,0,NULL,'khq','koyra chiini songhay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3123,0,NULL,'khr','kharia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3124,0,NULL,'khs','kasua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3125,0,NULL,'kht','khamti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3126,0,NULL,'khu','nkhumbi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3127,0,NULL,'khv','khvarshi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3128,0,NULL,'khw','khowar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3129,0,NULL,'khx','kanu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3130,0,NULL,'khy','kele (democratic republic of congo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3131,0,NULL,'khz','keapara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3132,0,NULL,'kia','kim','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3133,0,NULL,'kib','koalib','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3134,0,NULL,'kic','kickapoo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3135,0,NULL,'kid','koshin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3136,0,NULL,'kie','kibet','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3137,0,NULL,'kif','eastern parbate kham','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3138,0,NULL,'kig','kimaama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3138,0,NULL,'kig','kimaghima','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3139,0,NULL,'kih','kilmeri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3140,0,NULL,'kii','kitsai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3141,0,NULL,'kij','kilivila','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3142,0,NULL,'kil','kariya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3143,0,NULL,'kim','karagas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3144,0,NULL,'kio','kiowa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3145,0,NULL,'kip','sheshi kham','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3146,0,NULL,'kiq','kosadle','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3146,0,NULL,'kiq','kosare','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3147,0,NULL,'kis','kis','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3148,0,NULL,'kit','agob','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3149,0,NULL,'kiu','kirmanjki (individual language)','1248825600',NULL,NULL,NULL,NULL,'zza',NULL,NULL); +INSERT INTO "iana_records" VALUES(3150,0,NULL,'kiv','kimbu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3151,0,NULL,'kiw','northeast kiwai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3152,0,NULL,'kix','khiamniungan naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3153,0,NULL,'kiy','kirikiri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3154,0,NULL,'kiz','kisi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3155,0,NULL,'kja','mlap','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3156,0,NULL,'kjb','kanjobal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3156,0,NULL,'kjb','q''anjob''al','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3157,0,NULL,'kjc','coastal konjo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3158,0,NULL,'kjd','southern kiwai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3159,0,NULL,'kje','kisar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3160,0,NULL,'kjf','khalaj','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3161,0,NULL,'kjg','khmu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3162,0,NULL,'kjh','khakas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3163,0,NULL,'kji','zabana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3164,0,NULL,'kjj','khinalugh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3165,0,NULL,'kjk','highland konjo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3166,0,NULL,'kjl','western parbate kham','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3167,0,NULL,'kjm','kháng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3168,0,NULL,'kjn','kunjen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3169,0,NULL,'kjo','harijan kinnauri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3170,0,NULL,'kjp','pwo eastern karen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3171,0,NULL,'kjq','western keres','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3172,0,NULL,'kjr','kurudu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3173,0,NULL,'kjs','east kewa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3174,0,NULL,'kjt','phrae pwo karen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3175,0,NULL,'kju','kashaya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3176,0,NULL,'kjx','ramopa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3177,0,NULL,'kjy','erave','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3178,0,NULL,'kjz','bumthangkha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3179,0,NULL,'kka','kakanda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3180,0,NULL,'kkb','kwerisa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3181,0,NULL,'kkc','odoodee','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3182,0,NULL,'kkd','kinuku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3183,0,NULL,'kke','kakabe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3184,0,NULL,'kkf','kalaktang monpa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3185,0,NULL,'kkg','mabaka valley kalinga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3186,0,NULL,'kkh','khün','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3187,0,NULL,'kki','kagulu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3188,0,NULL,'kkj','kako','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3189,0,NULL,'kkk','kokota','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3190,0,NULL,'kkl','kosarek yale','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3191,0,NULL,'kkm','kiong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3192,0,NULL,'kkn','kon keu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3193,0,NULL,'kko','karko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3194,0,NULL,'kkp','gugubera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3195,0,NULL,'kkq','kaiku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3196,0,NULL,'kkr','kir-balar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3197,0,NULL,'kks','giiwo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3198,0,NULL,'kkt','koi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3199,0,NULL,'kku','tumi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3200,0,NULL,'kkv','kangean','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3201,0,NULL,'kkw','teke-kukuya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3202,0,NULL,'kkx','kohin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3203,0,NULL,'kky','guguyimidjir','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3204,0,NULL,'kkz','kaska','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3205,0,NULL,'kla','klamath-modoc','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3206,0,NULL,'klb','kiliwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3207,0,NULL,'klc','kolbila','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3208,0,NULL,'kld','gamilaraay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3209,0,NULL,'kle','kulung (nepal)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3210,0,NULL,'klf','kendeje','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3211,0,NULL,'klg','tagakaulo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3212,0,NULL,'klh','weliki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3213,0,NULL,'kli','kalumpang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3214,0,NULL,'klj','turkic khalaj','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3215,0,NULL,'klk','kono (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3216,0,NULL,'kll','kagan kalagan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3217,0,NULL,'klm','migum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3218,0,NULL,'kln','kalenjin','1248825600',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(3219,0,NULL,'klo','kapya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3220,0,NULL,'klp','kamasa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3221,0,NULL,'klq','rumu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3222,0,NULL,'klr','khaling','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3223,0,NULL,'kls','kalasha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3224,0,NULL,'klt','nukna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3225,0,NULL,'klu','klao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3226,0,NULL,'klv','maskelynes','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3227,0,NULL,'klw','lindu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3228,0,NULL,'klx','koluwawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3229,0,NULL,'kly','kalao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3230,0,NULL,'klz','kabola','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3231,0,NULL,'kma','konni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3232,0,NULL,'kmb','kimbundu','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3233,0,NULL,'kmc','southern dong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3234,0,NULL,'kmd','majukayang kalinga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3235,0,NULL,'kme','bakole','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3236,0,NULL,'kmf','kare (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3237,0,NULL,'kmg','kâte','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3238,0,NULL,'kmh','kalam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3239,0,NULL,'kmi','kami (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3240,0,NULL,'kmj','kumarbhag paharia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3241,0,NULL,'kmk','limos kalinga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3242,0,NULL,'kml','lower tanudan kalinga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3243,0,NULL,'kmm','kom (india)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3244,0,NULL,'kmn','awtuw','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3245,0,NULL,'kmo','kwoma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3246,0,NULL,'kmp','gimme','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3247,0,NULL,'kmq','kwama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3248,0,NULL,'kmr','northern kurdish','1248825600',NULL,NULL,NULL,NULL,'ku',NULL,NULL); +INSERT INTO "iana_records" VALUES(3249,0,NULL,'kms','kamasau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3250,0,NULL,'kmt','kemtuik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3251,0,NULL,'kmu','kanite','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3252,0,NULL,'kmv','karipúna creole french','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3253,0,NULL,'kmw','komo (democratic republic of congo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3254,0,NULL,'kmx','waboda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3255,0,NULL,'kmy','koma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3256,0,NULL,'kmz','khorasani turkish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3257,0,NULL,'kna','dera (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3258,0,NULL,'knb','lubuagan kalinga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3259,0,NULL,'knc','central kanuri','1248825600',NULL,NULL,NULL,NULL,'kr',NULL,NULL); +INSERT INTO "iana_records" VALUES(3260,0,NULL,'knd','konda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3261,0,NULL,'kne','kankanaey','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3262,0,NULL,'knf','mankanya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3263,0,NULL,'kng','koongo','1248825600',NULL,NULL,NULL,NULL,'kg',NULL,NULL); +INSERT INTO "iana_records" VALUES(3264,0,NULL,'kni','kanufi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3265,0,NULL,'knj','western kanjobal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3266,0,NULL,'knk','kuranko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3267,0,NULL,'knl','keninjal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3268,0,NULL,'knm','kanamarí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3269,0,NULL,'knn','konkani (individual language)','1248825600',NULL,NULL,NULL,NULL,'kok',NULL,NULL); +INSERT INTO "iana_records" VALUES(3270,0,NULL,'kno','kono (sierra leone)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3271,0,NULL,'knp','kwanja','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3272,0,NULL,'knq','kintaq','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3273,0,NULL,'knr','kaningra','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3274,0,NULL,'kns','kensiu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3275,0,NULL,'knt','panoan katukína','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3276,0,NULL,'knu','kono (guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3277,0,NULL,'knv','tabo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3278,0,NULL,'knw','kung-ekoka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3279,0,NULL,'knx','kendayan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3279,0,NULL,'knx','salako','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3280,0,NULL,'kny','kanyok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3281,0,NULL,'knz','kalamsé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3282,0,NULL,'koa','konomala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3283,0,NULL,'koc','kpati','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3284,0,NULL,'kod','kodi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3285,0,NULL,'koe','kacipo-balesi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3286,0,NULL,'kof','kubi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3287,0,NULL,'kog','cogui','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3287,0,NULL,'kog','kogi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3288,0,NULL,'koh','koyo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3289,0,NULL,'koi','komi-permyak','1248825600',NULL,NULL,NULL,NULL,'kv',NULL,NULL); +INSERT INTO "iana_records" VALUES(3290,0,NULL,'koj','sara dunjo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3291,0,NULL,'kok','konkani (macrolanguage)','1129420800',NULL,NULL,NULL,'deva',NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(3292,0,NULL,'kol','kol (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3293,0,NULL,'koo','konzo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3294,0,NULL,'kop','kwato','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3295,0,NULL,'koq','kota (gabon)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3296,0,NULL,'kos','kosraean','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3297,0,NULL,'kot','lagwan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3298,0,NULL,'kou','koke','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3299,0,NULL,'kov','kudu-camo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3300,0,NULL,'kow','kugama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3301,0,NULL,'kox','coxima','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3302,0,NULL,'koy','koyukon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3303,0,NULL,'koz','korak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3304,0,NULL,'kpa','kutto','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3305,0,NULL,'kpb','mullu kurumba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3306,0,NULL,'kpc','curripaco','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3307,0,NULL,'kpd','koba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3308,0,NULL,'kpe','kpelle','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(3309,0,NULL,'kpf','komba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3310,0,NULL,'kpg','kapingamarangi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3311,0,NULL,'kph','kplang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3312,0,NULL,'kpi','kofei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3313,0,NULL,'kpj','karajá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3314,0,NULL,'kpk','kpan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3315,0,NULL,'kpl','kpala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3316,0,NULL,'kpm','koho','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3317,0,NULL,'kpn','kepkiriwát','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3318,0,NULL,'kpo','ikposo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3319,0,NULL,'kpp','paku karen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3320,0,NULL,'kpq','korupun-sela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3321,0,NULL,'kpr','korafe-yegha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3322,0,NULL,'kps','tehit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3323,0,NULL,'kpt','karata','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3324,0,NULL,'kpu','kafoa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3325,0,NULL,'kpv','komi-zyrian','1248825600',NULL,NULL,NULL,NULL,'kv',NULL,NULL); +INSERT INTO "iana_records" VALUES(3326,0,NULL,'kpw','kobon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3327,0,NULL,'kpx','mountain koiali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3328,0,NULL,'kpy','koryak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3329,0,NULL,'kpz','kupsabiny','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3330,0,NULL,'kqa','mum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3331,0,NULL,'kqb','kovai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3332,0,NULL,'kqc','doromu-koki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3333,0,NULL,'kqd','koy sanjaq surat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3334,0,NULL,'kqe','kalagan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3335,0,NULL,'kqf','kakabai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3336,0,NULL,'kqg','khe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3337,0,NULL,'kqh','kisankasa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3338,0,NULL,'kqi','koitabu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3339,0,NULL,'kqj','koromira','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3340,0,NULL,'kqk','kotafon gbe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3341,0,NULL,'kql','kyenele','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3342,0,NULL,'kqm','khisa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3343,0,NULL,'kqn','kaonde','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3344,0,NULL,'kqo','eastern krahn','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3345,0,NULL,'kqp','kimré','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3346,0,NULL,'kqq','krenak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3347,0,NULL,'kqr','kimaragang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3348,0,NULL,'kqs','northern kissi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3349,0,NULL,'kqt','klias river kadazan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3350,0,NULL,'kqu','seroa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3351,0,NULL,'kqv','okolod','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3352,0,NULL,'kqw','kandas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3353,0,NULL,'kqx','mser','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3354,0,NULL,'kqy','koorete','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3355,0,NULL,'kqz','korana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3356,0,NULL,'kra','kumhali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3357,0,NULL,'krb','karkin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3358,0,NULL,'krc','karachay-balkar','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3359,0,NULL,'krd','kairui-midiki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3360,0,NULL,'kre','panará','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3361,0,NULL,'krf','koro (vanuatu)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3362,0,NULL,'krh','kurama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3363,0,NULL,'kri','krio','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3364,0,NULL,'krj','kinaray-a','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3365,0,NULL,'krk','kerek','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3366,0,NULL,'krl','karelian','1141776000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3367,0,NULL,'krm','krim','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3368,0,NULL,'krn','sapo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3369,0,NULL,'kro','kru languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(3370,0,NULL,'krp','korop','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3371,0,NULL,'krr','kru''ng 2','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3372,0,NULL,'krs','gbaya (sudan)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3373,0,NULL,'krt','tumari kanuri','1248825600',NULL,NULL,NULL,NULL,'kr',NULL,NULL); +INSERT INTO "iana_records" VALUES(3374,0,NULL,'kru','kurukh','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3375,0,NULL,'krv','kavet','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3376,0,NULL,'krw','western krahn','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3377,0,NULL,'krx','karon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3378,0,NULL,'kry','kryts','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3379,0,NULL,'krz','sota kanum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3380,0,NULL,'ksa','shuwa-zamani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3381,0,NULL,'ksb','shambala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3382,0,NULL,'ksc','southern kalinga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3383,0,NULL,'ksd','kuanua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3384,0,NULL,'kse','kuni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3385,0,NULL,'ksf','bafia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3386,0,NULL,'ksg','kusaghe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3387,0,NULL,'ksh','kölsch','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3388,0,NULL,'ksi','i''saka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3388,0,NULL,'ksi','krisa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3389,0,NULL,'ksj','uare','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3390,0,NULL,'ksk','kansa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3391,0,NULL,'ksl','kumalu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3392,0,NULL,'ksm','kumba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3393,0,NULL,'ksn','kasiguranin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3394,0,NULL,'kso','kofa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3395,0,NULL,'ksp','kaba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3396,0,NULL,'ksq','kwaami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3397,0,NULL,'ksr','borong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3398,0,NULL,'kss','southern kisi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3399,0,NULL,'kst','winyé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3400,0,NULL,'ksu','khamyang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3401,0,NULL,'ksv','kusu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3402,0,NULL,'ksw','s''gaw karen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3403,0,NULL,'ksx','kedang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3404,0,NULL,'ksy','kharia thar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3405,0,NULL,'ksz','kodaku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3406,0,NULL,'kta','katua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3407,0,NULL,'ktb','kambaata','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3408,0,NULL,'ktc','kholok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3409,0,NULL,'ktd','kokata','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3410,0,NULL,'kte','nubri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3411,0,NULL,'ktf','kwami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3412,0,NULL,'ktg','kalkutung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3413,0,NULL,'kth','karanga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3414,0,NULL,'kti','north muyu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3415,0,NULL,'ktj','plapo krumen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3416,0,NULL,'ktk','kaniet','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3417,0,NULL,'ktl','koroshi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3418,0,NULL,'ktm','kurti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3419,0,NULL,'ktn','karitiâna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3420,0,NULL,'kto','kuot','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3421,0,NULL,'ktp','kaduo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3422,0,NULL,'ktq','katabaga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3423,0,NULL,'ktr','kota marudu tinagas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3424,0,NULL,'kts','south muyu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3425,0,NULL,'ktt','ketum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3426,0,NULL,'ktu','kituba (democratic republic of congo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3427,0,NULL,'ktv','eastern katu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3428,0,NULL,'ktw','kato','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3429,0,NULL,'ktx','kaxararí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3430,0,NULL,'kty','kango (bas-uélé district)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3431,0,NULL,'ktz','ju/''hoan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3432,0,NULL,'kub','kutep','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3433,0,NULL,'kuc','kwinsu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3434,0,NULL,'kud','''auhelawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3435,0,NULL,'kue','kuman','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3436,0,NULL,'kuf','western katu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3437,0,NULL,'kug','kupa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3438,0,NULL,'kuh','kushi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3439,0,NULL,'kui','kuikúro-kalapálo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3440,0,NULL,'kuj','kuria','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3441,0,NULL,'kuk','kepo''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3442,0,NULL,'kul','kulere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3443,0,NULL,'kum','kumyk','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3444,0,NULL,'kun','kunama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3445,0,NULL,'kuo','kumukio','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3446,0,NULL,'kup','kunimaipa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3447,0,NULL,'kuq','karipuna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3448,0,NULL,'kus','kusaal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3449,0,NULL,'kut','kutenai','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3450,0,NULL,'kuu','upper kuskokwim','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3451,0,NULL,'kuv','kur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3452,0,NULL,'kuw','kpagua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3453,0,NULL,'kux','kukatja','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3454,0,NULL,'kuy','kuuku-ya''u','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3455,0,NULL,'kuz','kunza','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3456,0,NULL,'kva','bagvalal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3457,0,NULL,'kvb','kubu','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(3458,0,NULL,'kvc','kove','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3459,0,NULL,'kvd','kui (indonesia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3460,0,NULL,'kve','kalabakan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3461,0,NULL,'kvf','kabalai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3462,0,NULL,'kvg','kuni-boazi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3463,0,NULL,'kvh','komodo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3464,0,NULL,'kvi','kwang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3465,0,NULL,'kvj','psikye','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3466,0,NULL,'kvk','korean sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3467,0,NULL,'kvl','brek karen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3468,0,NULL,'kvm','kendem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3469,0,NULL,'kvn','border kuna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3470,0,NULL,'kvo','dobel','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3471,0,NULL,'kvp','kompane','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3472,0,NULL,'kvq','geba karen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3473,0,NULL,'kvr','kerinci','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(3474,0,NULL,'kvs','kunggara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3475,0,NULL,'kvt','lahta karen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3476,0,NULL,'kvu','yinbaw karen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3477,0,NULL,'kvv','kola','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3478,0,NULL,'kvw','wersing','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3479,0,NULL,'kvx','parkari koli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3480,0,NULL,'kvy','yintale karen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3481,0,NULL,'kvz','tsakwambo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3481,0,NULL,'kvz','tsaukambo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3482,0,NULL,'kwa','dâw','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3483,0,NULL,'kwb','kwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3484,0,NULL,'kwc','likwala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3485,0,NULL,'kwd','kwaio','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3486,0,NULL,'kwe','kwerba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3487,0,NULL,'kwf','kwara''ae','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3488,0,NULL,'kwg','sara kaba deme','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3489,0,NULL,'kwh','kowiai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3490,0,NULL,'kwi','awa-cuaiquer','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3491,0,NULL,'kwj','kwanga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3492,0,NULL,'kwk','kwakiutl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3493,0,NULL,'kwl','kofyar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3494,0,NULL,'kwm','kwambi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3495,0,NULL,'kwn','kwangali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3496,0,NULL,'kwo','kwomtari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3497,0,NULL,'kwp','kodia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3498,0,NULL,'kwq','kwak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3499,0,NULL,'kwr','kwer','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3500,0,NULL,'kws','kwese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3501,0,NULL,'kwt','kwesten','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3502,0,NULL,'kwu','kwakum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3503,0,NULL,'kwv','sara kaba náà','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3504,0,NULL,'kww','kwinti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3505,0,NULL,'kwx','khirwar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3506,0,NULL,'kwy','san salvador kongo','1248825600',NULL,NULL,NULL,NULL,'kg',NULL,NULL); +INSERT INTO "iana_records" VALUES(3507,0,NULL,'kwz','kwadi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3508,0,NULL,'kxa','kairiru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3509,0,NULL,'kxb','krobu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3510,0,NULL,'kxc','khonso','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3510,0,NULL,'kxc','konso','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3511,0,NULL,'kxd','brunei','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(3512,0,NULL,'kxe','kakihum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3513,0,NULL,'kxf','manumanaw karen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3514,0,NULL,'kxh','karo (ethiopia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3515,0,NULL,'kxi','keningau murut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3516,0,NULL,'kxj','kulfa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3517,0,NULL,'kxk','zayein karen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3518,0,NULL,'kxl','nepali kurux','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3519,0,NULL,'kxm','northern khmer','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3520,0,NULL,'kxn','kanowit-tanjong melanau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3521,0,NULL,'kxo','kanoé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3522,0,NULL,'kxp','wadiyara koli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3523,0,NULL,'kxq','smärky kanum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3524,0,NULL,'kxr','koro (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3525,0,NULL,'kxs','kangjia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3526,0,NULL,'kxt','koiwat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3527,0,NULL,'kxu','kui (india)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3528,0,NULL,'kxv','kuvi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3529,0,NULL,'kxw','konai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3530,0,NULL,'kxx','likuba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3531,0,NULL,'kxy','kayong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3532,0,NULL,'kxz','kerewo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3533,0,NULL,'kya','kwaya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3534,0,NULL,'kyb','butbut kalinga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3535,0,NULL,'kyc','kyaka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3536,0,NULL,'kyd','karey','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3537,0,NULL,'kye','krache','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3538,0,NULL,'kyf','kouya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3539,0,NULL,'kyg','keyagana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3540,0,NULL,'kyh','karok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3541,0,NULL,'kyi','kiput','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3542,0,NULL,'kyj','karao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3543,0,NULL,'kyk','kamayo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3544,0,NULL,'kyl','kalapuya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3545,0,NULL,'kym','kpatili','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3546,0,NULL,'kyn','northern binukidnon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3547,0,NULL,'kyo','kelon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3548,0,NULL,'kyp','kang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3549,0,NULL,'kyq','kenga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3550,0,NULL,'kyr','kuruáya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3551,0,NULL,'kys','baram kayan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3552,0,NULL,'kyt','kayagar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3553,0,NULL,'kyu','western kayah','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3554,0,NULL,'kyv','kayort','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3555,0,NULL,'kyw','kudmali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3556,0,NULL,'kyx','rapoisi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3557,0,NULL,'kyy','kambaira','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3558,0,NULL,'kyz','kayabí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3559,0,NULL,'kza','western karaboro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3560,0,NULL,'kzb','kaibobo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3561,0,NULL,'kzc','bondoukou kulango','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3562,0,NULL,'kzd','kadai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3563,0,NULL,'kze','kosena','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3564,0,NULL,'kzf','da''a kaili','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3565,0,NULL,'kzg','kikai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3566,0,NULL,'kzh','kenuzi-dongola','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3567,0,NULL,'kzi','kelabit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3568,0,NULL,'kzj','coastal kadazan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3569,0,NULL,'kzk','kazukuru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3570,0,NULL,'kzl','kayeli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3571,0,NULL,'kzm','kais','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3572,0,NULL,'kzn','kokola','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3573,0,NULL,'kzo','kaningi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3574,0,NULL,'kzp','kaidipang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3575,0,NULL,'kzq','kaike','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3576,0,NULL,'kzr','karang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3577,0,NULL,'kzs','sugut dusun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3578,0,NULL,'kzt','tambunan dusun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3579,0,NULL,'kzu','kayupulau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3580,0,NULL,'kzv','komyandaret','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3581,0,NULL,'kzw','karirí-xocó','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3582,0,NULL,'kzx','kamarian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3583,0,NULL,'kzy','kango (tshopo district)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3584,0,NULL,'kzz','kalabra','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3585,0,NULL,'laa','southern subanen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3586,0,NULL,'lab','linear a','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3587,0,NULL,'lac','lacandon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3588,0,NULL,'lad','ladino','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3589,0,NULL,'lae','pattani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3590,0,NULL,'laf','lafofa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3591,0,NULL,'lag','langi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3592,0,NULL,'lah','lahnda','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(3593,0,NULL,'lai','lambya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3594,0,NULL,'laj','lango (uganda)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3595,0,NULL,'lak','laka (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3596,0,NULL,'lal','lalia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3597,0,NULL,'lam','lamba','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3598,0,NULL,'lan','laru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3599,0,NULL,'lap','laka (chad)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3600,0,NULL,'laq','qabiao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3601,0,NULL,'lar','larteh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3602,0,NULL,'las','lama (togo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3603,0,NULL,'lau','laba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3604,0,NULL,'law','lauje','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3605,0,NULL,'lax','tiwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3606,0,NULL,'lay','lama (myanmar)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3607,0,NULL,'laz','aribwatsa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3608,0,NULL,'lba','lui','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3609,0,NULL,'lbb','label','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3610,0,NULL,'lbc','lakkia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3611,0,NULL,'lbe','lak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3612,0,NULL,'lbf','tinani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3613,0,NULL,'lbg','laopang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3614,0,NULL,'lbi','la''bi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3615,0,NULL,'lbj','ladakhi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3616,0,NULL,'lbk','central bontok','1268265600',NULL,NULL,NULL,NULL,'bnc',NULL,NULL); +INSERT INTO "iana_records" VALUES(3617,0,NULL,'lbl','libon bikol','1268265600',NULL,NULL,NULL,NULL,'bik',NULL,NULL); +INSERT INTO "iana_records" VALUES(3618,0,NULL,'lbm','lodhi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3619,0,NULL,'lbn','lamet','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3620,0,NULL,'lbo','laven','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3621,0,NULL,'lbq','wampar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3622,0,NULL,'lbr','northern lorung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3623,0,NULL,'lbs','libyan sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3624,0,NULL,'lbt','lachi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3625,0,NULL,'lbu','labu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3626,0,NULL,'lbv','lavatbura-lamusong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3627,0,NULL,'lbw','tolaki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3628,0,NULL,'lbx','lawangan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3629,0,NULL,'lby','lamu-lamu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3630,0,NULL,'lbz','lardil','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3631,0,NULL,'lcc','legenyem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3632,0,NULL,'lcd','lola','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3633,0,NULL,'lce','loncong','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(3634,0,NULL,'lcf','lubu','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(3635,0,NULL,'lch','luchazi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3636,0,NULL,'lcl','lisela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3637,0,NULL,'lcm','tungag','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3638,0,NULL,'lcp','western lawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3639,0,NULL,'lcq','luhu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3640,0,NULL,'lcs','lisabata-nuniali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3641,0,NULL,'ldb','idun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3642,0,NULL,'ldd','luri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3643,0,NULL,'ldg','lenyima','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3644,0,NULL,'ldh','lamja-dengsa-tola','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3645,0,NULL,'ldi','laari','1248825600',NULL,NULL,NULL,NULL,'kg',NULL,NULL); +INSERT INTO "iana_records" VALUES(3646,0,NULL,'ldj','lemoro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3647,0,NULL,'ldk','leelau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3648,0,NULL,'ldl','kaan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3649,0,NULL,'ldm','landoma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3650,0,NULL,'ldn','láadan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3651,0,NULL,'ldo','loo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3652,0,NULL,'ldp','tso','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3653,0,NULL,'ldq','lufu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3654,0,NULL,'lea','lega-shabunda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3655,0,NULL,'leb','lala-bisa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3656,0,NULL,'lec','leco','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3657,0,NULL,'led','lendu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3658,0,NULL,'lee','lyélé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3659,0,NULL,'lef','lelemi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3660,0,NULL,'leg','lengua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3661,0,NULL,'leh','lenje','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3662,0,NULL,'lei','lemio','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3663,0,NULL,'lej','lengola','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3664,0,NULL,'lek','leipon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3665,0,NULL,'lel','lele (democratic republic of congo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3666,0,NULL,'lem','nomaande','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3667,0,NULL,'len','lenca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3668,0,NULL,'leo','leti (cameroon)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3669,0,NULL,'lep','lepcha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3670,0,NULL,'leq','lembena','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3671,0,NULL,'ler','lenkau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3672,0,NULL,'les','lese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3673,0,NULL,'let','lesing-gelimi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3674,0,NULL,'leu','kara (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3675,0,NULL,'lev','lamma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3676,0,NULL,'lew','ledo kaili','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3677,0,NULL,'lex','luang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3678,0,NULL,'ley','lemolang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3679,0,NULL,'lez','lezghian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3680,0,NULL,'lfa','lefa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3681,0,NULL,'lfn','lingua franca nova','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3682,0,NULL,'lga','lungga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3683,0,NULL,'lgb','laghu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3684,0,NULL,'lgg','lugbara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3685,0,NULL,'lgh','laghuu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3686,0,NULL,'lgi','lengilu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3687,0,NULL,'lgk','lingarak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3687,0,NULL,'lgk','neverver','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3688,0,NULL,'lgl','wala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3689,0,NULL,'lgm','lega-mwenga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3690,0,NULL,'lgn','opuuo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3691,0,NULL,'lgq','logba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3692,0,NULL,'lgr','lengo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3693,0,NULL,'lgt','pahi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3694,0,NULL,'lgu','longgu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3695,0,NULL,'lgz','ligenza','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3696,0,NULL,'lha','laha (viet nam)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3697,0,NULL,'lhh','laha (indonesia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3698,0,NULL,'lhi','lahu shi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3699,0,NULL,'lhl','lahul lohar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3700,0,NULL,'lhm','lhomi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3701,0,NULL,'lhn','lahanan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3702,0,NULL,'lhp','lhokpu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3703,0,NULL,'lhs','mlahsö','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3704,0,NULL,'lht','lo-toga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3705,0,NULL,'lhu','lahu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3706,0,NULL,'lia','west-central limba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3707,0,NULL,'lib','likum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3708,0,NULL,'lic','hlai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3709,0,NULL,'lid','nyindrou','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3710,0,NULL,'lie','likila','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3711,0,NULL,'lif','limbu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3712,0,NULL,'lig','ligbi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3713,0,NULL,'lih','lihir','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3714,0,NULL,'lii','lingkhim','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3715,0,NULL,'lij','ligurian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3716,0,NULL,'lik','lika','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3717,0,NULL,'lil','lillooet','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3718,0,NULL,'lio','liki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3719,0,NULL,'lip','sekpele','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3720,0,NULL,'liq','libido','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3721,0,NULL,'lir','liberian english','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3722,0,NULL,'lis','lisu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3723,0,NULL,'liu','logorik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3724,0,NULL,'liv','liv','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3725,0,NULL,'liw','col','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(3726,0,NULL,'lix','liabuku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3727,0,NULL,'liy','banda-bambari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3728,0,NULL,'liz','libinza','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3729,0,NULL,'lje','rampi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3730,0,NULL,'lji','laiyolo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3731,0,NULL,'ljl','li''o','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3732,0,NULL,'ljp','lampung api','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3733,0,NULL,'lka','lakalei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3734,0,NULL,'lkb','kabras','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(3734,0,NULL,'lkb','lukabaras','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(3735,0,NULL,'lkc','kucong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3736,0,NULL,'lkd','lakondê','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3737,0,NULL,'lke','kenyi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3738,0,NULL,'lkh','lakha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3739,0,NULL,'lki','laki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3740,0,NULL,'lkj','remun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3741,0,NULL,'lkl','laeko-libuat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3742,0,NULL,'lkn','lakon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3742,0,NULL,'lkn','vure','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3743,0,NULL,'lko','khayo','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(3743,0,NULL,'lko','olukhayo','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(3744,0,NULL,'lkr','päri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3745,0,NULL,'lks','kisa','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(3745,0,NULL,'lks','olushisa','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(3746,0,NULL,'lkt','lakota','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3747,0,NULL,'lky','lokoya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3748,0,NULL,'lla','lala-roba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3749,0,NULL,'llb','lolo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3750,0,NULL,'llc','lele (guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3751,0,NULL,'lld','ladin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3752,0,NULL,'lle','lele (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3753,0,NULL,'llf','hermit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3754,0,NULL,'llg','lole','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3755,0,NULL,'llh','lamu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3756,0,NULL,'lli','teke-laali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3757,0,NULL,'llk','lelak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3758,0,NULL,'lll','lilau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3759,0,NULL,'llm','lasalimu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3760,0,NULL,'lln','lele (chad)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3761,0,NULL,'llo','khlor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3762,0,NULL,'llp','north efate','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3763,0,NULL,'llq','lolak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3764,0,NULL,'lls','lithuanian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3765,0,NULL,'llu','lau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3766,0,NULL,'llx','lauan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3767,0,NULL,'lma','east limba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3768,0,NULL,'lmb','merei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3769,0,NULL,'lmc','limilngan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3770,0,NULL,'lmd','lumun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3771,0,NULL,'lme','pévé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3772,0,NULL,'lmf','south lembata','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3773,0,NULL,'lmg','lamogai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3774,0,NULL,'lmh','lambichhong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3775,0,NULL,'lmi','lombi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3776,0,NULL,'lmj','west lembata','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3777,0,NULL,'lmk','lamkang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3778,0,NULL,'lml','hano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3779,0,NULL,'lmm','lamam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3780,0,NULL,'lmn','lambadi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3781,0,NULL,'lmo','lombard','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3782,0,NULL,'lmp','limbum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3783,0,NULL,'lmq','lamatuka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3784,0,NULL,'lmr','lamalera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3785,0,NULL,'lmu','lamenu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3786,0,NULL,'lmv','lomaiviti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3787,0,NULL,'lmw','lake miwok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3788,0,NULL,'lmx','laimbue','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3789,0,NULL,'lmy','lamboya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3790,0,NULL,'lmz','lumbee','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3791,0,NULL,'lna','langbashe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3792,0,NULL,'lnb','mbalanhu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3793,0,NULL,'lnd','lun bawang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3793,0,NULL,'lnd','lundayeh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3794,0,NULL,'lng','langobardic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3795,0,NULL,'lnh','lanoh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3796,0,NULL,'lni','daantanai''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3797,0,NULL,'lnj','leningitij','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3798,0,NULL,'lnl','south central banda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3799,0,NULL,'lnm','langam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3800,0,NULL,'lnn','lorediakarkar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3801,0,NULL,'lno','lango (sudan)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3802,0,NULL,'lns','lamnso''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3803,0,NULL,'lnu','longuda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3804,0,NULL,'lnz','lonzo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3805,0,NULL,'loa','loloda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3806,0,NULL,'lob','lobi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3807,0,NULL,'loc','inonhan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3808,0,NULL,'loe','saluan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3809,0,NULL,'lof','logol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3810,0,NULL,'log','logo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3811,0,NULL,'loh','narim','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3812,0,NULL,'loi','loma (côte d''ivoire)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3813,0,NULL,'loj','lou','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3814,0,NULL,'lok','loko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3815,0,NULL,'lol','mongo','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3816,0,NULL,'lom','loma (liberia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3817,0,NULL,'lon','malawi lomwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3818,0,NULL,'loo','lombo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3819,0,NULL,'lop','lopa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3820,0,NULL,'loq','lobala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3821,0,NULL,'lor','téén','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3822,0,NULL,'los','loniu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3823,0,NULL,'lot','otuho','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3824,0,NULL,'lou','louisiana creole french','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3825,0,NULL,'lov','lopi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3826,0,NULL,'low','tampias lobu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3827,0,NULL,'lox','loun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3828,0,NULL,'loy','lowa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3829,0,NULL,'loz','lozi','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3830,0,NULL,'lpa','lelepa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3831,0,NULL,'lpe','lepki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3832,0,NULL,'lpn','long phuri naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3833,0,NULL,'lpo','lipo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3834,0,NULL,'lpx','lopit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3835,0,NULL,'lra','rara bakati''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3836,0,NULL,'lrc','northern luri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3837,0,NULL,'lre','laurentian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3838,0,NULL,'lrg','laragia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3839,0,NULL,'lri','marachi','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(3839,0,NULL,'lri','olumarachi','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(3840,0,NULL,'lrk','loarki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3841,0,NULL,'lrl','lari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3842,0,NULL,'lrm','marama','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(3842,0,NULL,'lrm','olumarama','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(3843,0,NULL,'lrn','lorang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3844,0,NULL,'lro','laro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3845,0,NULL,'lrr','southern lorung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3846,0,NULL,'lrt','larantuka malay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3847,0,NULL,'lrv','larevat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3848,0,NULL,'lrz','lemerig','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3849,0,NULL,'lsa','lasgerdi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3850,0,NULL,'lsd','lishana deni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3851,0,NULL,'lse','lusengo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3852,0,NULL,'lsg','lyons sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3853,0,NULL,'lsh','lish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3854,0,NULL,'lsi','lashi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3855,0,NULL,'lsl','latvian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3856,0,NULL,'lsm','olusamia','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(3856,0,NULL,'lsm','saamia','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(3857,0,NULL,'lso','laos sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3858,0,NULL,'lsp','lengua de señas panameñas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3858,0,NULL,'lsp','panamanian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3859,0,NULL,'lsr','aruop','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3860,0,NULL,'lss','lasi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3861,0,NULL,'lst','trinidad and tobago sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3862,0,NULL,'lsy','mauritian sign language','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3863,0,NULL,'ltc','late middle chinese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3864,0,NULL,'ltg','latgalian','1268265600',NULL,NULL,NULL,NULL,'lv',NULL,NULL); +INSERT INTO "iana_records" VALUES(3865,0,NULL,'lti','leti (indonesia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3866,0,NULL,'ltn','latundê','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3867,0,NULL,'lto','olutsotso','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(3867,0,NULL,'lto','tsotso','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(3868,0,NULL,'lts','lutachoni','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(3868,0,NULL,'lts','tachoni','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(3869,0,NULL,'ltu','latu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3870,0,NULL,'lua','luba-lulua','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3871,0,NULL,'luc','aringa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3872,0,NULL,'lud','ludian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3873,0,NULL,'lue','luvale','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3874,0,NULL,'luf','laua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3875,0,NULL,'lui','luiseno','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3876,0,NULL,'luj','luna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3877,0,NULL,'luk','lunanakha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3878,0,NULL,'lul','olu''bo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3879,0,NULL,'lum','luimbi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3880,0,NULL,'lun','lunda','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3881,0,NULL,'luo','dholuo','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3881,0,NULL,'luo','luo (kenya and tanzania)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3882,0,NULL,'lup','lumbu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3883,0,NULL,'luq','lucumi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3884,0,NULL,'lur','laura','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3885,0,NULL,'lus','lushai','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3886,0,NULL,'lut','lushootseed','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3887,0,NULL,'luu','lumba-yakkha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3888,0,NULL,'luv','luwati','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3889,0,NULL,'luw','luo (cameroon)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3890,0,NULL,'luy','luyia','1248825600',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(3890,0,NULL,'luy','oluluyia','1248825600',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(3891,0,NULL,'luz','southern luri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3892,0,NULL,'lva','maku''a','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3893,0,NULL,'lvk','lavukaleve','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3894,0,NULL,'lvs','standard latvian','1268265600',NULL,NULL,NULL,NULL,'lv',NULL,NULL); +INSERT INTO "iana_records" VALUES(3895,0,NULL,'lvu','levuka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3896,0,NULL,'lwa','lwalu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3897,0,NULL,'lwe','lewo eleng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3898,0,NULL,'lwg','oluwanga','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(3898,0,NULL,'lwg','wanga','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(3899,0,NULL,'lwh','white lachi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3900,0,NULL,'lwl','eastern lawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3901,0,NULL,'lwm','laomian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3902,0,NULL,'lwo','luwo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3903,0,NULL,'lwt','lewotobi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3904,0,NULL,'lww','lewo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3905,0,NULL,'lya','layakha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3906,0,NULL,'lyg','lyngngam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3907,0,NULL,'lyn','luyana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3908,0,NULL,'lzh','literary chinese','1248825600',NULL,NULL,NULL,NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(3909,0,NULL,'lzl','litzlitz','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3910,0,NULL,'lzn','leinong naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3911,0,NULL,'lzz','laz','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3912,0,NULL,'maa','san jerónimo tecóatl mazatec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3913,0,NULL,'mab','yutanduchi mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3914,0,NULL,'mad','madurese','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3915,0,NULL,'mae','bo-rukul','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3916,0,NULL,'maf','mafa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3917,0,NULL,'mag','magahi','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3918,0,NULL,'mai','maithili','1129420800',NULL,NULL,NULL,'deva',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3919,0,NULL,'maj','jalapa de díaz mazatec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3920,0,NULL,'mak','makasar','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3921,0,NULL,'mam','mam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3922,0,NULL,'man','mandingo','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(3923,0,NULL,'map','austronesian languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(3924,0,NULL,'maq','chiquihuitlán mazatec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3925,0,NULL,'mas','masai','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3926,0,NULL,'mat','san francisco matlatzinca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3927,0,NULL,'mau','huautla mazatec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3928,0,NULL,'mav','sateré-mawé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3929,0,NULL,'maw','mampruli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3930,0,NULL,'max','north moluccan malay','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(3931,0,NULL,'maz','central mazahua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3932,0,NULL,'mba','higaonon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3933,0,NULL,'mbb','western bukidnon manobo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3934,0,NULL,'mbc','macushi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3935,0,NULL,'mbd','dibabawon manobo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3936,0,NULL,'mbe','molale','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3937,0,NULL,'mbf','baba malay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3938,0,NULL,'mbh','mangseng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3939,0,NULL,'mbi','ilianen manobo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3940,0,NULL,'mbj','nadëb','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3941,0,NULL,'mbk','malol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3942,0,NULL,'mbl','maxakalí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3943,0,NULL,'mbm','ombamba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3944,0,NULL,'mbn','macaguán','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3945,0,NULL,'mbo','mbo (cameroon)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3946,0,NULL,'mbp','malayo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3947,0,NULL,'mbq','maisin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3948,0,NULL,'mbr','nukak makú','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3949,0,NULL,'mbs','sarangani manobo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3950,0,NULL,'mbt','matigsalug manobo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3951,0,NULL,'mbu','mbula-bwazza','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3952,0,NULL,'mbv','mbulungish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3953,0,NULL,'mbw','maring','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3954,0,NULL,'mbx','mari (east sepik province)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3955,0,NULL,'mby','memoni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3956,0,NULL,'mbz','amoltepec mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3957,0,NULL,'mca','maca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3958,0,NULL,'mcb','machiguenga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3959,0,NULL,'mcc','bitur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3960,0,NULL,'mcd','sharanahua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3961,0,NULL,'mce','itundujia mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3962,0,NULL,'mcf','matsés','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3963,0,NULL,'mcg','mapoyo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3964,0,NULL,'mch','maquiritari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3965,0,NULL,'mci','mese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3966,0,NULL,'mcj','mvanip','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3967,0,NULL,'mck','mbunda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3968,0,NULL,'mcl','macaguaje','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3969,0,NULL,'mcm','malaccan creole portuguese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3970,0,NULL,'mcn','masana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3971,0,NULL,'mco','coatlán mixe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3972,0,NULL,'mcp','makaa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3973,0,NULL,'mcq','ese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3974,0,NULL,'mcr','menya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3975,0,NULL,'mcs','mambai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3976,0,NULL,'mct','mengisa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3977,0,NULL,'mcu','cameroon mambila','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3978,0,NULL,'mcv','minanibai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3979,0,NULL,'mcw','mawa (chad)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3980,0,NULL,'mcx','mpiemo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3981,0,NULL,'mcy','south watut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3982,0,NULL,'mcz','mawan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3983,0,NULL,'mda','mada (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3984,0,NULL,'mdb','morigi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3985,0,NULL,'mdc','male (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3986,0,NULL,'mdd','mbum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3987,0,NULL,'mde','maba (chad)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3988,0,NULL,'mdf','moksha','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3989,0,NULL,'mdg','massalat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3990,0,NULL,'mdh','maguindanaon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3991,0,NULL,'mdi','mamvu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3992,0,NULL,'mdj','mangbetu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3993,0,NULL,'mdk','mangbutu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3994,0,NULL,'mdl','maltese sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3995,0,NULL,'mdm','mayogo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3996,0,NULL,'mdn','mbati','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3997,0,NULL,'mdp','mbala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3998,0,NULL,'mdq','mbole','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3999,0,NULL,'mdr','mandar','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4000,0,NULL,'mds','maria (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4001,0,NULL,'mdt','mbere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4002,0,NULL,'mdu','mboko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4003,0,NULL,'mdv','santa lucía monteverde mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4004,0,NULL,'mdw','mbosi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4005,0,NULL,'mdx','dizin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4006,0,NULL,'mdy','male (ethiopia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4007,0,NULL,'mdz','suruí do pará','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4008,0,NULL,'mea','menka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4009,0,NULL,'meb','ikobi-mena','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4010,0,NULL,'mec','mara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4011,0,NULL,'med','melpa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4012,0,NULL,'mee','mengen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4013,0,NULL,'mef','megam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4014,0,NULL,'meg','mea','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4015,0,NULL,'meh','southwestern tlaxiaco mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4016,0,NULL,'mei','midob','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4017,0,NULL,'mej','meyah','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4018,0,NULL,'mek','mekeo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4019,0,NULL,'mel','central melanau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4020,0,NULL,'mem','mangala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4021,0,NULL,'men','mende (sierra leone)','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4022,0,NULL,'meo','kedah malay','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(4023,0,NULL,'mep','miriwung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4024,0,NULL,'meq','merey','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4025,0,NULL,'mer','meru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4026,0,NULL,'mes','masmaje','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4027,0,NULL,'met','mato','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4028,0,NULL,'meu','motu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4029,0,NULL,'mev','mann','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4030,0,NULL,'mew','maaka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4031,0,NULL,'mey','hassaniyya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4032,0,NULL,'mez','menominee','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4033,0,NULL,'mfa','pattani malay','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(4034,0,NULL,'mfb','bangka','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(4035,0,NULL,'mfc','mba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4036,0,NULL,'mfd','mendankwe-nkwen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4037,0,NULL,'mfe','morisyen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4038,0,NULL,'mff','naki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4039,0,NULL,'mfg','mixifore','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4040,0,NULL,'mfh','matal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4041,0,NULL,'mfi','wandala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4042,0,NULL,'mfj','mefele','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4043,0,NULL,'mfk','north mofu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4044,0,NULL,'mfl','putai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4045,0,NULL,'mfm','marghi south','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4046,0,NULL,'mfn','cross river mbembe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4047,0,NULL,'mfo','mbe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4048,0,NULL,'mfp','makassar malay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4049,0,NULL,'mfq','moba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4050,0,NULL,'mfr','marithiel','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4051,0,NULL,'mfs','mexican sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4052,0,NULL,'mft','mokerang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4053,0,NULL,'mfu','mbwela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4054,0,NULL,'mfv','mandjak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4055,0,NULL,'mfw','mulaha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4056,0,NULL,'mfx','melo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4057,0,NULL,'mfy','mayo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4058,0,NULL,'mfz','mabaan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4059,0,NULL,'mga','middle irish (900-1200)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4060,0,NULL,'mgb','mararit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4061,0,NULL,'mgc','morokodo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4062,0,NULL,'mgd','moru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4063,0,NULL,'mge','mango','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4064,0,NULL,'mgf','maklew','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4065,0,NULL,'mgg','mpongmpong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4066,0,NULL,'mgh','makhuwa-meetto','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4067,0,NULL,'mgi','lijili','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4068,0,NULL,'mgj','abureni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4069,0,NULL,'mgk','mawes','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4070,0,NULL,'mgl','maleu-kilenge','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4071,0,NULL,'mgm','mambae','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4072,0,NULL,'mgn','mbangi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4073,0,NULL,'mgo','meta''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4074,0,NULL,'mgp','eastern magar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4075,0,NULL,'mgq','malila','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4076,0,NULL,'mgr','mambwe-lungu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4077,0,NULL,'mgs','manda (tanzania)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4078,0,NULL,'mgt','mongol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4079,0,NULL,'mgu','mailu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4080,0,NULL,'mgv','matengo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4081,0,NULL,'mgw','matumbi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4082,0,NULL,'mgx','omati','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4083,0,NULL,'mgy','mbunga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4084,0,NULL,'mgz','mbugwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4085,0,NULL,'mha','manda (india)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4086,0,NULL,'mhb','mahongwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4087,0,NULL,'mhc','mocho','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4088,0,NULL,'mhd','mbugu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4089,0,NULL,'mhe','besisi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4089,0,NULL,'mhe','mah meri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4090,0,NULL,'mhf','mamaa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4091,0,NULL,'mhg','margu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4092,0,NULL,'mhh','maskoy pidgin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4093,0,NULL,'mhi','ma''di','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4094,0,NULL,'mhj','mogholi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4095,0,NULL,'mhk','mungaka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4096,0,NULL,'mhl','mauwake','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4097,0,NULL,'mhm','makhuwa-moniga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4098,0,NULL,'mhn','mócheno','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4099,0,NULL,'mho','mashi (zambia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4100,0,NULL,'mhp','balinese malay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4101,0,NULL,'mhq','mandan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4102,0,NULL,'mhr','eastern mari','1248825600',NULL,NULL,NULL,NULL,'chm',NULL,NULL); +INSERT INTO "iana_records" VALUES(4103,0,NULL,'mhs','buru (indonesia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4104,0,NULL,'mht','mandahuaca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4105,0,NULL,'mhu','darang deng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4105,0,NULL,'mhu','digaro-mishmi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4106,0,NULL,'mhw','mbukushu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4107,0,NULL,'mhx','lhaovo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4107,0,NULL,'mhx','maru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4108,0,NULL,'mhy','ma''anyan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4109,0,NULL,'mhz','mor (mor islands)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4110,0,NULL,'mia','miami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4111,0,NULL,'mib','atatláhuca mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4112,0,NULL,'mic','mi''kmaq','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4112,0,NULL,'mic','micmac','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4113,0,NULL,'mid','mandaic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4114,0,NULL,'mie','ocotepec mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4115,0,NULL,'mif','mofu-gudur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4116,0,NULL,'mig','san miguel el grande mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4117,0,NULL,'mih','chayuco mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4118,0,NULL,'mii','chigmecatitlán mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4119,0,NULL,'mij','abar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4120,0,NULL,'mik','mikasuki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4121,0,NULL,'mil','peñoles mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4122,0,NULL,'mim','alacatlatzala mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4123,0,NULL,'min','minangkabau','1129420800',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(4124,0,NULL,'mio','pinotepa nacional mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4125,0,NULL,'mip','apasco-apoala mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4126,0,NULL,'miq','mískito','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4127,0,NULL,'mir','isthmus mixe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4128,0,NULL,'mis','uncoded languages','1129420800',NULL,NULL,NULL,NULL,NULL,'special',NULL); +INSERT INTO "iana_records" VALUES(4129,0,NULL,'mit','southern puebla mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4130,0,NULL,'miu','cacaloxtepec mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4131,0,NULL,'miw','akoye','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4132,0,NULL,'mix','mixtepec mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4133,0,NULL,'miy','ayutla mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4134,0,NULL,'miz','coatzospan mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4135,0,NULL,'mja','mahei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4136,0,NULL,'mjc','san juan colorado mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4137,0,NULL,'mjd','northwest maidu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4138,0,NULL,'mje','muskum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4139,0,NULL,'mjg','tu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4140,0,NULL,'mjh','mwera (nyasa)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4141,0,NULL,'mji','kim mun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4142,0,NULL,'mjj','mawak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4143,0,NULL,'mjk','matukar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4144,0,NULL,'mjl','mandeali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4145,0,NULL,'mjm','medebur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4146,0,NULL,'mjn','ma (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4147,0,NULL,'mjo','malankuravan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4148,0,NULL,'mjp','malapandaram','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4149,0,NULL,'mjq','malaryan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4150,0,NULL,'mjr','malavedan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4151,0,NULL,'mjs','miship','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4152,0,NULL,'mjt','sauria paharia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4153,0,NULL,'mju','manna-dora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4154,0,NULL,'mjv','mannan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4155,0,NULL,'mjw','karbi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4156,0,NULL,'mjx','mahali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4157,0,NULL,'mjy','mahican','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4158,0,NULL,'mjz','majhi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4159,0,NULL,'mka','mbre','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4160,0,NULL,'mkb','mal paharia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4161,0,NULL,'mkc','siliput','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4162,0,NULL,'mke','mawchi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4163,0,NULL,'mkf','miya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4164,0,NULL,'mkg','mak (china)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4165,0,NULL,'mkh','mon-khmer languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(4166,0,NULL,'mki','dhatki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4167,0,NULL,'mkj','mokilese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4168,0,NULL,'mkk','byep','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4169,0,NULL,'mkl','mokole','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4170,0,NULL,'mkm','moklen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4171,0,NULL,'mkn','kupang malay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4172,0,NULL,'mko','mingang doso','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4173,0,NULL,'mkp','moikodi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4174,0,NULL,'mkq','bay miwok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4175,0,NULL,'mkr','malas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4176,0,NULL,'mks','silacayoapan mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4177,0,NULL,'mkt','vamale','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4178,0,NULL,'mku','konyanka maninka','1248825600',NULL,NULL,NULL,NULL,'man',NULL,NULL); +INSERT INTO "iana_records" VALUES(4179,0,NULL,'mkv','mafea','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4180,0,NULL,'mkw','kituba (congo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4181,0,NULL,'mkx','kinamiging manobo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4182,0,NULL,'mky','east makian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4183,0,NULL,'mkz','makasae','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4184,0,NULL,'mla','malo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4185,0,NULL,'mlb','mbule','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4186,0,NULL,'mlc','cao lan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4187,0,NULL,'mld','malakhel','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4188,0,NULL,'mle','manambu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4189,0,NULL,'mlf','mal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4190,0,NULL,'mlh','mape','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4191,0,NULL,'mli','malimpung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4192,0,NULL,'mlj','miltu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4193,0,NULL,'mlk','ilwana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4193,0,NULL,'mlk','kiwilwana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4194,0,NULL,'mll','malua bay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4195,0,NULL,'mlm','mulam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4196,0,NULL,'mln','malango','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4197,0,NULL,'mlo','mlomp','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4198,0,NULL,'mlp','bargam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4199,0,NULL,'mlq','western maninkakan','1248825600',NULL,NULL,NULL,NULL,'man',NULL,NULL); +INSERT INTO "iana_records" VALUES(4200,0,NULL,'mlr','vame','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4201,0,NULL,'mls','masalit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4202,0,NULL,'mlu','to''abaita','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4203,0,NULL,'mlv','motlav','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4203,0,NULL,'mlv','mwotlap','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4204,0,NULL,'mlw','moloko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4205,0,NULL,'mlx','malfaxal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4205,0,NULL,'mlx','naha''ai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4206,0,NULL,'mlz','malaynon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4207,0,NULL,'mma','mama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4208,0,NULL,'mmb','momina','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4209,0,NULL,'mmc','michoacán mazahua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4210,0,NULL,'mmd','maonan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4211,0,NULL,'mme','mae','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4212,0,NULL,'mmf','mundat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4213,0,NULL,'mmg','north ambrym','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4214,0,NULL,'mmh','mehináku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4215,0,NULL,'mmi','musar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4216,0,NULL,'mmj','majhwar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4217,0,NULL,'mmk','mukha-dora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4218,0,NULL,'mml','man met','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4219,0,NULL,'mmm','maii','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4220,0,NULL,'mmn','mamanwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4221,0,NULL,'mmo','mangga buang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4222,0,NULL,'mmp','siawi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4223,0,NULL,'mmq','musak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4224,0,NULL,'mmr','western xiangxi miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(4225,0,NULL,'mmt','malalamai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4226,0,NULL,'mmu','mmaala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4227,0,NULL,'mmv','miriti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4228,0,NULL,'mmw','emae','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4229,0,NULL,'mmx','madak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4230,0,NULL,'mmy','migaama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4231,0,NULL,'mmz','mabaale','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4232,0,NULL,'mna','mbula','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4233,0,NULL,'mnb','muna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4234,0,NULL,'mnc','manchu','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4235,0,NULL,'mnd','mondé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4236,0,NULL,'mne','naba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4237,0,NULL,'mnf','mundani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4238,0,NULL,'mng','eastern mnong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4239,0,NULL,'mnh','mono (democratic republic of congo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4240,0,NULL,'mni','manipuri','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4241,0,NULL,'mnj','munji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4242,0,NULL,'mnk','mandinka','1248825600',NULL,NULL,NULL,NULL,'man',NULL,NULL); +INSERT INTO "iana_records" VALUES(4243,0,NULL,'mnl','tiale','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4244,0,NULL,'mnm','mapena','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4245,0,NULL,'mnn','southern mnong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4246,0,NULL,'mno','manobo languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(4247,0,NULL,'mnp','min bei chinese','1248825600',NULL,NULL,NULL,NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(4248,0,NULL,'mnq','minriq','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4249,0,NULL,'mnr','mono (usa)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4250,0,NULL,'mns','mansi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4251,0,NULL,'mnt','maykulan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4252,0,NULL,'mnu','mer','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4253,0,NULL,'mnv','rennell-bellona','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4254,0,NULL,'mnw','mon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4255,0,NULL,'mnx','manikion','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4256,0,NULL,'mny','manyawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4257,0,NULL,'mnz','moni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4258,0,NULL,'moa','mwan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4259,0,NULL,'moc','mocoví','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4260,0,NULL,'mod','mobilian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4261,0,NULL,'moe','montagnais','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4262,0,NULL,'mof','mohegan-montauk-narragansett','1248825600',1268265600,NULL,NULL,NULL,NULL,NULL,'see xnt, xpq'); +INSERT INTO "iana_records" VALUES(4263,0,NULL,'mog','mongondow','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4264,0,NULL,'moh','mohawk','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4265,0,NULL,'moi','mboi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4266,0,NULL,'moj','monzombo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4267,0,NULL,'mok','morori','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4268,0,NULL,'mom','mangue','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4269,0,NULL,'moo','monom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4270,0,NULL,'mop','mopán maya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4271,0,NULL,'moq','mor (bomberai peninsula)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4272,0,NULL,'mor','moro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4273,0,NULL,'mos','mossi','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4274,0,NULL,'mot','barí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4275,0,NULL,'mou','mogum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4276,0,NULL,'mov','mohave','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4277,0,NULL,'mow','moi (congo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4278,0,NULL,'mox','molima','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4279,0,NULL,'moy','shekkacho','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4280,0,NULL,'moz','mukulu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4281,0,NULL,'mpa','mpoto','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4282,0,NULL,'mpb','mullukmulluk','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4283,0,NULL,'mpc','mangarayi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4284,0,NULL,'mpd','machinere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4285,0,NULL,'mpe','majang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4286,0,NULL,'mpg','marba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4287,0,NULL,'mph','maung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4288,0,NULL,'mpi','mpade','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4289,0,NULL,'mpj','martu wangka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4290,0,NULL,'mpk','mbara (chad)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4291,0,NULL,'mpl','middle watut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4292,0,NULL,'mpm','yosondúa mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4293,0,NULL,'mpn','mindiri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4294,0,NULL,'mpo','miu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4295,0,NULL,'mpp','migabac','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4296,0,NULL,'mpq','matís','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4297,0,NULL,'mpr','vangunu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4298,0,NULL,'mps','dadibi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4299,0,NULL,'mpt','mian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4300,0,NULL,'mpu','makuráp','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4301,0,NULL,'mpv','mungkip','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4302,0,NULL,'mpw','mapidian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4303,0,NULL,'mpx','misima-paneati','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4304,0,NULL,'mpy','mapia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4305,0,NULL,'mpz','mpi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4306,0,NULL,'mqa','maba (indonesia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4307,0,NULL,'mqb','mbuko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4308,0,NULL,'mqc','mangole','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4309,0,NULL,'mqe','matepi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4310,0,NULL,'mqf','momuna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4311,0,NULL,'mqg','kota bangun kutai malay','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(4312,0,NULL,'mqh','tlazoyaltepec mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4313,0,NULL,'mqi','mariri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4314,0,NULL,'mqj','mamasa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4315,0,NULL,'mqk','rajah kabunsuwan manobo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4316,0,NULL,'mql','mbelime','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4317,0,NULL,'mqm','south marquesan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4318,0,NULL,'mqn','moronene','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4319,0,NULL,'mqo','modole','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4320,0,NULL,'mqp','manipa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4321,0,NULL,'mqq','minokok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4322,0,NULL,'mqr','mander','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4323,0,NULL,'mqs','west makian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4324,0,NULL,'mqt','mok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4325,0,NULL,'mqu','mandari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4326,0,NULL,'mqv','mosimo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4327,0,NULL,'mqw','murupi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4328,0,NULL,'mqx','mamuju','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4329,0,NULL,'mqy','manggarai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4330,0,NULL,'mqz','malasanga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4331,0,NULL,'mra','mlabri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4332,0,NULL,'mrb','marino','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4333,0,NULL,'mrc','maricopa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4334,0,NULL,'mrd','western magar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4335,0,NULL,'mre','martha''s vineyard sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4336,0,NULL,'mrf','elseng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4337,0,NULL,'mrg','miri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4338,0,NULL,'mrh','mara chin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4339,0,NULL,'mrj','western mari','1248825600',NULL,NULL,NULL,NULL,'chm',NULL,NULL); +INSERT INTO "iana_records" VALUES(4340,0,NULL,'mrk','hmwaveke','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4341,0,NULL,'mrl','mortlockese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4342,0,NULL,'mrm','merlav','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4342,0,NULL,'mrm','mwerlap','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4343,0,NULL,'mrn','cheke holo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4344,0,NULL,'mro','mru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4345,0,NULL,'mrp','morouas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4346,0,NULL,'mrq','north marquesan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4347,0,NULL,'mrr','maria (india)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4348,0,NULL,'mrs','maragus','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4349,0,NULL,'mrt','marghi central','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4350,0,NULL,'mru','mono (cameroon)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4351,0,NULL,'mrv','mangareva','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4352,0,NULL,'mrw','maranao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4353,0,NULL,'mrx','dineor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4353,0,NULL,'mrx','maremgi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4354,0,NULL,'mry','mandaya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4355,0,NULL,'mrz','marind','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4356,0,NULL,'msb','masbatenyo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4357,0,NULL,'msc','sankaran maninka','1248825600',NULL,NULL,NULL,NULL,'man',NULL,NULL); +INSERT INTO "iana_records" VALUES(4358,0,NULL,'msd','yucatec maya sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4359,0,NULL,'mse','musey','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4360,0,NULL,'msf','mekwei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4361,0,NULL,'msg','moraid','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4362,0,NULL,'msh','masikoro malagasy','1248825600',NULL,NULL,NULL,NULL,'mg',NULL,NULL); +INSERT INTO "iana_records" VALUES(4363,0,NULL,'msi','sabah malay','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(4364,0,NULL,'msj','ma (democratic republic of congo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4365,0,NULL,'msk','mansaka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4366,0,NULL,'msl','molof','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4366,0,NULL,'msl','poule','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4367,0,NULL,'msm','agusan manobo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4368,0,NULL,'msn','vurës','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4369,0,NULL,'mso','mombum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4370,0,NULL,'msp','maritsauá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4371,0,NULL,'msq','caac','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4372,0,NULL,'msr','mongolian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4373,0,NULL,'mss','west masela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4374,0,NULL,'mst','cataelano mandaya','1248825600',1268265600,'mry',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4375,0,NULL,'msu','musom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4376,0,NULL,'msv','maslam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4377,0,NULL,'msw','mansoanka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4378,0,NULL,'msx','moresada','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4379,0,NULL,'msy','aruamu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4380,0,NULL,'msz','momare','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4381,0,NULL,'mta','cotabato manobo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4382,0,NULL,'mtb','anyin morofo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4383,0,NULL,'mtc','munit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4384,0,NULL,'mtd','mualang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4385,0,NULL,'mte','mono (solomon islands)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4386,0,NULL,'mtf','murik (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4387,0,NULL,'mtg','una','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4388,0,NULL,'mth','munggui','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4389,0,NULL,'mti','maiwa (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4390,0,NULL,'mtj','moskona','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4391,0,NULL,'mtk','mbe''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4392,0,NULL,'mtl','montol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4393,0,NULL,'mtm','mator','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4394,0,NULL,'mtn','matagalpa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4395,0,NULL,'mto','totontepec mixe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4396,0,NULL,'mtp','wichí lhamtés nocten','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4397,0,NULL,'mtq','muong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4398,0,NULL,'mtr','mewari','1248825600',NULL,NULL,NULL,NULL,'mwr',NULL,NULL); +INSERT INTO "iana_records" VALUES(4399,0,NULL,'mts','yora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4400,0,NULL,'mtt','mota','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4401,0,NULL,'mtu','tututepec mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4402,0,NULL,'mtv','asaro''o','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4403,0,NULL,'mtw','southern binukidnon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4404,0,NULL,'mtx','tidaá mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4405,0,NULL,'mty','nabi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4406,0,NULL,'mua','mundang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4407,0,NULL,'mub','mubi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4408,0,NULL,'muc','mbu''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4409,0,NULL,'mud','mednyj aleut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4410,0,NULL,'mue','media lengua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4411,0,NULL,'mug','musgu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4412,0,NULL,'muh','mündü','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4413,0,NULL,'mui','musi','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(4414,0,NULL,'muj','mabire','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4415,0,NULL,'muk','mugom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4416,0,NULL,'mul','multiple languages','1129420800',NULL,NULL,NULL,NULL,NULL,'special',NULL); +INSERT INTO "iana_records" VALUES(4417,0,NULL,'mum','maiwala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4418,0,NULL,'mun','munda languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(4419,0,NULL,'muo','nyong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4420,0,NULL,'mup','malvi','1248825600',NULL,NULL,NULL,NULL,'raj',NULL,NULL); +INSERT INTO "iana_records" VALUES(4421,0,NULL,'muq','eastern xiangxi miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(4422,0,NULL,'mur','murle','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4423,0,NULL,'mus','creek','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4424,0,NULL,'mut','western muria','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4425,0,NULL,'muu','yaaku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4426,0,NULL,'muv','muthuvan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4427,0,NULL,'mux','bo-ung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4428,0,NULL,'muy','muyang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4429,0,NULL,'muz','mursi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4430,0,NULL,'mva','manam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4431,0,NULL,'mvb','mattole','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4432,0,NULL,'mvd','mamboru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4433,0,NULL,'mve','marwari (pakistan)','1248825600',NULL,NULL,NULL,NULL,'mwr',NULL,NULL); +INSERT INTO "iana_records" VALUES(4434,0,NULL,'mvf','peripheral mongolian','1248825600',NULL,NULL,NULL,NULL,'mn',NULL,NULL); +INSERT INTO "iana_records" VALUES(4435,0,NULL,'mvg','yucuañe mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4436,0,NULL,'mvh','mire','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4437,0,NULL,'mvi','miyako','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4438,0,NULL,'mvk','mekmek','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4439,0,NULL,'mvl','mbara (australia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4440,0,NULL,'mvm','muya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4441,0,NULL,'mvn','minaveha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4442,0,NULL,'mvo','marovo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4443,0,NULL,'mvp','duri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4444,0,NULL,'mvq','moere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4445,0,NULL,'mvr','marau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4446,0,NULL,'mvs','massep','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4447,0,NULL,'mvt','mpotovoro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4448,0,NULL,'mvu','marfa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4449,0,NULL,'mvv','tagal murut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4450,0,NULL,'mvw','machinga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4451,0,NULL,'mvx','meoswar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4452,0,NULL,'mvy','indus kohistani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4453,0,NULL,'mvz','mesqan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4454,0,NULL,'mwa','mwatebu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4455,0,NULL,'mwb','juwal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4456,0,NULL,'mwc','are','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4457,0,NULL,'mwd','mudbura','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4458,0,NULL,'mwe','mwera (chimwera)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4459,0,NULL,'mwf','murrinh-patha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4460,0,NULL,'mwg','aiklep','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4461,0,NULL,'mwh','mouk-aria','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4462,0,NULL,'mwi','labo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4462,0,NULL,'mwi','ninde','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4463,0,NULL,'mwj','maligo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4464,0,NULL,'mwk','kita maninkakan','1248825600',NULL,NULL,NULL,NULL,'man',NULL,NULL); +INSERT INTO "iana_records" VALUES(4465,0,NULL,'mwl','mirandese','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4466,0,NULL,'mwm','sar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4467,0,NULL,'mwn','nyamwanga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4468,0,NULL,'mwo','central maewo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4469,0,NULL,'mwp','kala lagaw ya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4470,0,NULL,'mwq','mün chin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4471,0,NULL,'mwr','marwari','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(4472,0,NULL,'mws','mwimbi-muthambi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4473,0,NULL,'mwt','moken','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4474,0,NULL,'mwu','mittu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4475,0,NULL,'mwv','mentawai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4476,0,NULL,'mww','hmong daw','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(4477,0,NULL,'mwx','mediak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4478,0,NULL,'mwy','mosiro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4479,0,NULL,'mwz','moingi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4480,0,NULL,'mxa','northwest oaxaca mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4481,0,NULL,'mxb','tezoatlán mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4482,0,NULL,'mxc','manyika','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4483,0,NULL,'mxd','modang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4484,0,NULL,'mxe','mele-fila','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4485,0,NULL,'mxf','malgbe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4486,0,NULL,'mxg','mbangala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4487,0,NULL,'mxh','mvuba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4488,0,NULL,'mxi','mozarabic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4489,0,NULL,'mxj','geman deng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4489,0,NULL,'mxj','miju-mishmi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4490,0,NULL,'mxk','monumbo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4491,0,NULL,'mxl','maxi gbe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4492,0,NULL,'mxm','meramera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4493,0,NULL,'mxn','moi (indonesia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4494,0,NULL,'mxo','mbowe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4495,0,NULL,'mxp','tlahuitoltepec mixe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4496,0,NULL,'mxq','juquila mixe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4497,0,NULL,'mxr','murik (malaysia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4498,0,NULL,'mxs','huitepec mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4499,0,NULL,'mxt','jamiltepec mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4500,0,NULL,'mxu','mada (cameroon)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4501,0,NULL,'mxv','metlatónoc mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4502,0,NULL,'mxw','namo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4503,0,NULL,'mxx','mahou','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4503,0,NULL,'mxx','mawukakan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4504,0,NULL,'mxy','southeastern nochixtlán mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4505,0,NULL,'mxz','central masela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4506,0,NULL,'myb','mbay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4507,0,NULL,'myc','mayeka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4508,0,NULL,'myd','maramba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4509,0,NULL,'mye','myene','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4510,0,NULL,'myf','bambassi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4511,0,NULL,'myg','manta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4512,0,NULL,'myh','makah','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4513,0,NULL,'myi','mina (india)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4514,0,NULL,'myj','mangayat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4515,0,NULL,'myk','mamara senoufo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4516,0,NULL,'myl','moma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4517,0,NULL,'mym','me''en','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4518,0,NULL,'myn','mayan languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(4519,0,NULL,'myo','anfillo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4520,0,NULL,'myp','pirahã','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4521,0,NULL,'myq','forest maninka','1248825600',NULL,NULL,NULL,NULL,'man',NULL,NULL); +INSERT INTO "iana_records" VALUES(4522,0,NULL,'myr','muniche','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4523,0,NULL,'mys','mesmes','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4524,0,NULL,'myt','sangab mandaya','1248825600',1268265600,'mry',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4525,0,NULL,'myu','mundurukú','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4526,0,NULL,'myv','erzya','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4527,0,NULL,'myw','muyuw','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4528,0,NULL,'myx','masaaba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4529,0,NULL,'myy','macuna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4530,0,NULL,'myz','classical mandaic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4531,0,NULL,'mza','santa maría zacatepec mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4532,0,NULL,'mzb','tumzabt','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4533,0,NULL,'mzc','madagascar sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4534,0,NULL,'mzd','malimba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4535,0,NULL,'mze','morawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4536,0,NULL,'mzg','monastic sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4537,0,NULL,'mzh','wichí lhamtés güisnay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4538,0,NULL,'mzi','ixcatlán mazatec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4539,0,NULL,'mzj','manya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4540,0,NULL,'mzk','nigeria mambila','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4541,0,NULL,'mzl','mazatlán mixe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4542,0,NULL,'mzm','mumuye','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4543,0,NULL,'mzn','mazanderani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4544,0,NULL,'mzo','matipuhy','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4545,0,NULL,'mzp','movima','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4546,0,NULL,'mzq','mori atas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4547,0,NULL,'mzr','marúbo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4548,0,NULL,'mzs','macanese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4549,0,NULL,'mzt','mintil','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4550,0,NULL,'mzu','inapang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4551,0,NULL,'mzv','manza','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4552,0,NULL,'mzw','deg','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4553,0,NULL,'mzx','mawayana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4554,0,NULL,'mzy','mozambican sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4555,0,NULL,'mzz','maiadomu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4556,0,NULL,'naa','namla','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4557,0,NULL,'nab','southern nambikuára','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4558,0,NULL,'nac','narak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4559,0,NULL,'nad','nijadali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4560,0,NULL,'nae','naka''ela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4561,0,NULL,'naf','nabak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4562,0,NULL,'nag','naga pidgin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4563,0,NULL,'nah','nahuatl languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(4564,0,NULL,'nai','north american indian languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(4565,0,NULL,'naj','nalu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4566,0,NULL,'nak','nakanai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4567,0,NULL,'nal','nalik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4568,0,NULL,'nam','nangikurrunggurr','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4569,0,NULL,'nan','min nan chinese','1248825600',NULL,NULL,NULL,NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(4570,0,NULL,'nao','naaba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4571,0,NULL,'nap','neapolitan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4572,0,NULL,'naq','nama (namibia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4573,0,NULL,'nar','iguta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4574,0,NULL,'nas','naasioi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4575,0,NULL,'nat','hungworo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4576,0,NULL,'naw','nawuri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4577,0,NULL,'nax','nakwi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4578,0,NULL,'nay','narrinyeri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4579,0,NULL,'naz','coatepec nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4580,0,NULL,'nba','nyemba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4581,0,NULL,'nbb','ndoe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4582,0,NULL,'nbc','chang naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4583,0,NULL,'nbd','ngbinda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4584,0,NULL,'nbe','konyak naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4585,0,NULL,'nbf','naxi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4586,0,NULL,'nbg','nagarchal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4587,0,NULL,'nbh','ngamo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4588,0,NULL,'nbi','mao naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4589,0,NULL,'nbj','ngarinman','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4590,0,NULL,'nbk','nake','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4591,0,NULL,'nbm','ngbaka ma''bo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4592,0,NULL,'nbn','kuri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4593,0,NULL,'nbo','nkukoli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4594,0,NULL,'nbp','nnam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4595,0,NULL,'nbq','nggem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4596,0,NULL,'nbr','numana-nunku-gbantu-numbu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4597,0,NULL,'nbs','namibian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4598,0,NULL,'nbt','na','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4599,0,NULL,'nbu','rongmei naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4600,0,NULL,'nbv','ngamambo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4601,0,NULL,'nbw','southern ngbandi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4602,0,NULL,'nbx','ngura','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4603,0,NULL,'nby','ningera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4604,0,NULL,'nca','iyo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4605,0,NULL,'ncb','central nicobarese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4606,0,NULL,'ncc','ponam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4607,0,NULL,'ncd','nachering','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4608,0,NULL,'nce','yale','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4609,0,NULL,'ncf','notsi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4610,0,NULL,'ncg','nisga''a','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4611,0,NULL,'nch','central huasteca nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4612,0,NULL,'nci','classical nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4613,0,NULL,'ncj','northern puebla nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4614,0,NULL,'nck','nakara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4615,0,NULL,'ncl','michoacán nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4616,0,NULL,'ncm','nambo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4617,0,NULL,'ncn','nauna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4618,0,NULL,'nco','sibe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4619,0,NULL,'ncp','ndaktup','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4620,0,NULL,'ncr','ncane','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4621,0,NULL,'ncs','nicaraguan sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4622,0,NULL,'nct','chothe naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4623,0,NULL,'ncu','chumburung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4624,0,NULL,'ncx','central puebla nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4625,0,NULL,'ncz','natchez','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4626,0,NULL,'nda','ndasa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4627,0,NULL,'ndb','kenswei nsei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4628,0,NULL,'ndc','ndau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4629,0,NULL,'ndd','nde-nsele-nta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4630,0,NULL,'ndf','nadruvian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4631,0,NULL,'ndg','ndengereko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4632,0,NULL,'ndh','ndali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4633,0,NULL,'ndi','samba leko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4634,0,NULL,'ndj','ndamba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4635,0,NULL,'ndk','ndaka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4636,0,NULL,'ndl','ndolo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4637,0,NULL,'ndm','ndam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4638,0,NULL,'ndn','ngundi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4639,0,NULL,'ndp','ndo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4640,0,NULL,'ndq','ndombe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4641,0,NULL,'ndr','ndoola','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4642,0,NULL,'nds','low german','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4642,0,NULL,'nds','low saxon','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4643,0,NULL,'ndt','ndunga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4644,0,NULL,'ndu','dugun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4645,0,NULL,'ndv','ndut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4646,0,NULL,'ndw','ndobo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4647,0,NULL,'ndx','nduga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4648,0,NULL,'ndy','lutos','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4649,0,NULL,'ndz','ndogo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4650,0,NULL,'nea','eastern ngad''a','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4651,0,NULL,'neb','toura (côte d''ivoire)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4652,0,NULL,'nec','nedebang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4653,0,NULL,'ned','nde-gbite','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4654,0,NULL,'nee','kumak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4655,0,NULL,'nef','nefamese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4656,0,NULL,'neg','negidal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4657,0,NULL,'neh','nyenkha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4658,0,NULL,'nei','neo-hittite','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4659,0,NULL,'nej','neko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4660,0,NULL,'nek','neku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4661,0,NULL,'nem','nemi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4662,0,NULL,'nen','nengone','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4663,0,NULL,'neo','ná-meo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4664,0,NULL,'neq','north central mixe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4665,0,NULL,'ner','yahadian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4666,0,NULL,'nes','bhoti kinnauri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4667,0,NULL,'net','nete','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4668,0,NULL,'nev','nyaheun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4669,0,NULL,'new','nepal bhasa','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4669,0,NULL,'new','newari','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4670,0,NULL,'nex','neme','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4671,0,NULL,'ney','neyo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4672,0,NULL,'nez','nez perce','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4673,0,NULL,'nfa','dhao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4674,0,NULL,'nfd','ahwai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4675,0,NULL,'nfl','ayiwo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4675,0,NULL,'nfl','Äiwoo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4676,0,NULL,'nfr','nafaanra','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4677,0,NULL,'nfu','mfumte','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4678,0,NULL,'nga','ngbaka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4679,0,NULL,'ngb','northern ngbandi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4680,0,NULL,'ngc','ngombe (democratic republic of congo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4681,0,NULL,'ngd','ngando (central african republic)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4682,0,NULL,'nge','ngemba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4683,0,NULL,'ngf','trans-new guinea languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(4684,0,NULL,'ngg','ngbaka manza','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4685,0,NULL,'ngh','n/u','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4686,0,NULL,'ngi','ngizim','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4687,0,NULL,'ngj','ngie','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4688,0,NULL,'ngk','ngalkbun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4689,0,NULL,'ngl','lomwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4690,0,NULL,'ngm','ngatik men''s creole','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4691,0,NULL,'ngn','ngwo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4692,0,NULL,'ngo','ngoni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4693,0,NULL,'ngp','ngulu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4694,0,NULL,'ngq','ngoreme','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4694,0,NULL,'ngq','ngurimi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4695,0,NULL,'ngr','nagu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4695,0,NULL,'ngr','nanggu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4696,0,NULL,'ngs','gvoko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4697,0,NULL,'ngt','ngeq','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4698,0,NULL,'ngu','guerrero nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4699,0,NULL,'ngv','nagumi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4700,0,NULL,'ngw','ngwaba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4701,0,NULL,'ngx','nggwahyi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4702,0,NULL,'ngy','tibea','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4703,0,NULL,'ngz','ngungwel','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4704,0,NULL,'nha','nhanda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4705,0,NULL,'nhb','beng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4706,0,NULL,'nhc','tabasco nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4707,0,NULL,'nhd','ava guaraní','1248825600',NULL,NULL,NULL,NULL,'gn',NULL,NULL); +INSERT INTO "iana_records" VALUES(4707,0,NULL,'nhd','chiripá','1248825600',NULL,NULL,NULL,NULL,'gn',NULL,NULL); +INSERT INTO "iana_records" VALUES(4708,0,NULL,'nhe','eastern huasteca nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4709,0,NULL,'nhf','nhuwala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4710,0,NULL,'nhg','tetelcingo nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4711,0,NULL,'nhh','nahari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4712,0,NULL,'nhi','zacatlán-ahuacatlán-tepetzintla nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4713,0,NULL,'nhk','isthmus-cosoleacaque nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4714,0,NULL,'nhm','morelos nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4715,0,NULL,'nhn','central nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4716,0,NULL,'nho','takuu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4717,0,NULL,'nhp','isthmus-pajapan nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4718,0,NULL,'nhq','huaxcaleca nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4719,0,NULL,'nhr','naro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4720,0,NULL,'nht','ometepec nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4721,0,NULL,'nhu','noone','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4722,0,NULL,'nhv','temascaltepec nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4723,0,NULL,'nhw','western huasteca nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4724,0,NULL,'nhx','isthmus-mecayapan nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4725,0,NULL,'nhy','northern oaxaca nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4726,0,NULL,'nhz','santa maría la alta nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4727,0,NULL,'nia','nias','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4728,0,NULL,'nib','nakama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4729,0,NULL,'nic','niger-kordofanian languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(4730,0,NULL,'nid','ngandi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4731,0,NULL,'nie','niellim','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4732,0,NULL,'nif','nek','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4733,0,NULL,'nig','ngalakan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4734,0,NULL,'nih','nyiha (tanzania)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4735,0,NULL,'nii','nii','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4736,0,NULL,'nij','ngaju','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4737,0,NULL,'nik','southern nicobarese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4738,0,NULL,'nil','nila','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4739,0,NULL,'nim','nilamba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4740,0,NULL,'nin','ninzo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4741,0,NULL,'nio','nganasan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4742,0,NULL,'niq','nandi','1248825600',NULL,NULL,NULL,NULL,'kln',NULL,NULL); +INSERT INTO "iana_records" VALUES(4743,0,NULL,'nir','nimboran','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4744,0,NULL,'nis','nimi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4745,0,NULL,'nit','southeastern kolami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4746,0,NULL,'niu','niuean','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4747,0,NULL,'niv','gilyak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4748,0,NULL,'niw','nimo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4749,0,NULL,'nix','hema','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4750,0,NULL,'niy','ngiti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4751,0,NULL,'niz','ningil','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4752,0,NULL,'nja','nzanyi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4753,0,NULL,'njb','nocte naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4754,0,NULL,'njd','ndonde hamba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4755,0,NULL,'njh','lotha naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4756,0,NULL,'nji','gudanji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4757,0,NULL,'njj','njen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4758,0,NULL,'njl','njalgulgule','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4759,0,NULL,'njm','angami naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4760,0,NULL,'njn','liangmai naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4761,0,NULL,'njo','ao naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4762,0,NULL,'njr','njerep','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4763,0,NULL,'njs','nisa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4764,0,NULL,'njt','ndyuka-trio pidgin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4765,0,NULL,'nju','ngadjunmaya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4766,0,NULL,'njx','kunyi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4767,0,NULL,'njy','njyem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4768,0,NULL,'nka','nkoya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4769,0,NULL,'nkb','khoibu naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4770,0,NULL,'nkc','nkongho','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4771,0,NULL,'nkd','koireng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4772,0,NULL,'nke','duke','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4773,0,NULL,'nkf','inpui naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4774,0,NULL,'nkg','nekgini','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4775,0,NULL,'nkh','khezha naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4776,0,NULL,'nki','thangal naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4777,0,NULL,'nkj','nakai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4778,0,NULL,'nkk','nokuku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4779,0,NULL,'nkm','namat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4780,0,NULL,'nkn','nkangala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4781,0,NULL,'nko','nkonya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4782,0,NULL,'nkp','niuatoputapu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4783,0,NULL,'nkq','nkami','1271376000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4784,0,NULL,'nkr','nukuoro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4785,0,NULL,'nks','north asmat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4786,0,NULL,'nkt','nyika (tanzania)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4787,0,NULL,'nku','bouna kulango','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4788,0,NULL,'nkv','nyika (malawi and zambia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4789,0,NULL,'nkw','nkutu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4790,0,NULL,'nkx','nkoroo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4791,0,NULL,'nkz','nkari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4792,0,NULL,'nla','ngombale','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4793,0,NULL,'nlc','nalca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4794,0,NULL,'nle','east nyala','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(4795,0,NULL,'nlg','gela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4796,0,NULL,'nli','grangali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4797,0,NULL,'nlj','nyali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4798,0,NULL,'nlk','ninia yali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4799,0,NULL,'nll','nihali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4800,0,NULL,'nln','durango nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4801,0,NULL,'nlo','ngul','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4802,0,NULL,'nlr','ngarla','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4803,0,NULL,'nlu','nchumbulu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4804,0,NULL,'nlv','orizaba nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4805,0,NULL,'nlx','nahali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4806,0,NULL,'nly','nyamal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4807,0,NULL,'nlz','nalögo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4808,0,NULL,'nma','maram naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4809,0,NULL,'nmb','big nambas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4809,0,NULL,'nmb','v''ënen taut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4810,0,NULL,'nmc','ngam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4811,0,NULL,'nmd','ndumu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4812,0,NULL,'nme','mzieme naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4813,0,NULL,'nmf','tangkhul naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4814,0,NULL,'nmg','kwasio','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4815,0,NULL,'nmh','monsang naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4816,0,NULL,'nmi','nyam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4817,0,NULL,'nmj','ngombe (central african republic)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4818,0,NULL,'nmk','namakura','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4819,0,NULL,'nml','ndemli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4820,0,NULL,'nmm','manangba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4821,0,NULL,'nmn','!xóõ','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4822,0,NULL,'nmo','moyon naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4823,0,NULL,'nmp','nimanbur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4824,0,NULL,'nmq','nambya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4825,0,NULL,'nmr','nimbari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4826,0,NULL,'nms','letemboi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4827,0,NULL,'nmt','namonuito','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4828,0,NULL,'nmu','northeast maidu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4829,0,NULL,'nmv','ngamini','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4830,0,NULL,'nmw','nimoa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4831,0,NULL,'nmx','nama (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4832,0,NULL,'nmy','namuyi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4833,0,NULL,'nmz','nawdm','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4834,0,NULL,'nna','nyangumarta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4835,0,NULL,'nnb','nande','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4836,0,NULL,'nnc','nancere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4837,0,NULL,'nnd','west ambae','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4838,0,NULL,'nne','ngandyera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4839,0,NULL,'nnf','ngaing','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4840,0,NULL,'nng','maring naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4841,0,NULL,'nnh','ngiemboon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4842,0,NULL,'nni','north nuaulu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4843,0,NULL,'nnj','nyangatom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4844,0,NULL,'nnk','nankina','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4845,0,NULL,'nnl','northern rengma naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4846,0,NULL,'nnm','namia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4847,0,NULL,'nnn','ngete','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4848,0,NULL,'nnp','wancho naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4849,0,NULL,'nnq','ngindo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4850,0,NULL,'nnr','narungga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4851,0,NULL,'nns','ningye','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4852,0,NULL,'nnt','nanticoke','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4853,0,NULL,'nnu','dwang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4854,0,NULL,'nnv','nugunu (australia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4855,0,NULL,'nnw','southern nuni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4856,0,NULL,'nnx','ngong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4857,0,NULL,'nny','nyangga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4858,0,NULL,'nnz','nda''nda''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4859,0,NULL,'noa','woun meu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4860,0,NULL,'noc','nuk','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4861,0,NULL,'nod','northern thai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4862,0,NULL,'noe','nimadi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4863,0,NULL,'nof','nomane','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4864,0,NULL,'nog','nogai','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4865,0,NULL,'noh','nomu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4866,0,NULL,'noi','noiri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4867,0,NULL,'noj','nonuya','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4868,0,NULL,'nok','nooksack','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4869,0,NULL,'nom','nocamán','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4870,0,NULL,'non','old norse','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4871,0,NULL,'noo','nootka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4872,0,NULL,'nop','numanggang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4873,0,NULL,'noq','ngongo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4874,0,NULL,'nos','eastern nisu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4875,0,NULL,'not','nomatsiguenga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4876,0,NULL,'nou','ewage-notu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4877,0,NULL,'nov','novial','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4878,0,NULL,'now','nyambo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4879,0,NULL,'noy','noy','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4880,0,NULL,'noz','nayi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4881,0,NULL,'npa','nar phu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4882,0,NULL,'npb','nupbikha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4883,0,NULL,'nph','phom naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4884,0,NULL,'npl','southeastern puebla nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4885,0,NULL,'npn','mondropolon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4886,0,NULL,'npo','pochuri naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4887,0,NULL,'nps','nipsan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4888,0,NULL,'npu','puimei naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4889,0,NULL,'npy','napu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4890,0,NULL,'nqg','southern nago','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4891,0,NULL,'nqk','kura ede nago','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4892,0,NULL,'nqm','ndom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4893,0,NULL,'nqn','nen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4894,0,NULL,'nqo','n''ko','1149465600',NULL,NULL,NULL,'nkoo',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4894,0,NULL,'nqo','n’ko','1149465600',NULL,NULL,NULL,'nkoo',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4895,0,NULL,'nra','ngom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4896,0,NULL,'nrb','nara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4897,0,NULL,'nrc','noric','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4898,0,NULL,'nre','southern rengma naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4899,0,NULL,'nrg','narango','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4900,0,NULL,'nri','chokri naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4901,0,NULL,'nrl','ngarluma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4902,0,NULL,'nrm','narom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4903,0,NULL,'nrn','norn','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4904,0,NULL,'nrp','north picene','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4905,0,NULL,'nrr','norra','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4906,0,NULL,'nrt','northern kalapuya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4907,0,NULL,'nrx','ngurmbur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4908,0,NULL,'nrz','lala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4909,0,NULL,'nsa','sangtam naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4910,0,NULL,'nsc','nshi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4911,0,NULL,'nsd','southern nisu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4912,0,NULL,'nse','nsenga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4913,0,NULL,'nsg','ngasa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4914,0,NULL,'nsh','ngoshie','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4915,0,NULL,'nsi','nigerian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4916,0,NULL,'nsk','naskapi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4917,0,NULL,'nsl','norwegian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4918,0,NULL,'nsm','sumi naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4919,0,NULL,'nsn','nehan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4920,0,NULL,'nso','northern sotho','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4920,0,NULL,'nso','pedi','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4920,0,NULL,'nso','sepedi','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4921,0,NULL,'nsp','nepalese sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4922,0,NULL,'nsq','northern sierra miwok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4923,0,NULL,'nsr','maritime sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4924,0,NULL,'nss','nali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4925,0,NULL,'nst','tase naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4926,0,NULL,'nsu','sierra negra nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4927,0,NULL,'nsv','southwestern nisu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4928,0,NULL,'nsw','navut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4929,0,NULL,'nsx','nsongo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4930,0,NULL,'nsy','nasal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4931,0,NULL,'nsz','nisenan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4932,0,NULL,'nte','nathembo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4933,0,NULL,'nti','natioro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4934,0,NULL,'ntj','ngaanyatjarra','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4935,0,NULL,'ntk','ikoma-nata-isenye','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4936,0,NULL,'ntm','nateni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4937,0,NULL,'nto','ntomba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4938,0,NULL,'ntp','northern tepehuan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4939,0,NULL,'ntr','delo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4940,0,NULL,'nts','natagaimas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4941,0,NULL,'ntu','natügu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4942,0,NULL,'ntw','nottoway','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4943,0,NULL,'nty','mantsi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4944,0,NULL,'ntz','natanzi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4945,0,NULL,'nua','yuaga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4946,0,NULL,'nub','nubian languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(4947,0,NULL,'nuc','nukuini','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4948,0,NULL,'nud','ngala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4949,0,NULL,'nue','ngundu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4950,0,NULL,'nuf','nusu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4951,0,NULL,'nug','nungali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4952,0,NULL,'nuh','ndunda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4953,0,NULL,'nui','ngumbi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4954,0,NULL,'nuj','nyole','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4955,0,NULL,'nul','nusa laut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4956,0,NULL,'num','niuafo''ou','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4957,0,NULL,'nun','nung (myanmar)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4958,0,NULL,'nuo','nguôn','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4959,0,NULL,'nup','nupe-nupe-tako','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4960,0,NULL,'nuq','nukumanu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4961,0,NULL,'nur','nukuria','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4962,0,NULL,'nus','nuer','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4963,0,NULL,'nut','nung (viet nam)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4964,0,NULL,'nuu','ngbundu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4965,0,NULL,'nuv','northern nuni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4966,0,NULL,'nuw','nguluwan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4967,0,NULL,'nux','mehek','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4968,0,NULL,'nuy','nunggubuyu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4969,0,NULL,'nuz','tlamacazapa nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4970,0,NULL,'nvh','nasarian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4971,0,NULL,'nvm','namiae','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4972,0,NULL,'nwa','nawathinehena','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4973,0,NULL,'nwb','nyabwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4974,0,NULL,'nwc','classical nepal bhasa','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4974,0,NULL,'nwc','classical newari','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4974,0,NULL,'nwc','old newari','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4975,0,NULL,'nwe','ngwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4976,0,NULL,'nwi','southwest tanna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4977,0,NULL,'nwm','nyamusa-molo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4978,0,NULL,'nwr','nawaru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4979,0,NULL,'nwx','middle newar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4980,0,NULL,'nwy','nottoway-meherrin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4981,0,NULL,'nxa','nauete','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4982,0,NULL,'nxd','ngando (democratic republic of congo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4983,0,NULL,'nxe','nage','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4984,0,NULL,'nxg','ngad''a','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4985,0,NULL,'nxi','nindi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4986,0,NULL,'nxl','south nuaulu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4987,0,NULL,'nxm','numidian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4988,0,NULL,'nxn','ngawun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4989,0,NULL,'nxr','ninggerum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4990,0,NULL,'nxu','narau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4991,0,NULL,'nxx','nafri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4992,0,NULL,'nyb','nyangbo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4993,0,NULL,'nyc','nyanga-li','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4994,0,NULL,'nyd','nyore','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(4994,0,NULL,'nyd','olunyole','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(4995,0,NULL,'nye','nyengo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4996,0,NULL,'nyf','giryama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4996,0,NULL,'nyf','kigiryama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4997,0,NULL,'nyg','nyindu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4998,0,NULL,'nyh','nyigina','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4999,0,NULL,'nyi','ama (sudan)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5000,0,NULL,'nyj','nyanga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5001,0,NULL,'nyk','nyaneka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5002,0,NULL,'nyl','nyeu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5003,0,NULL,'nym','nyamwezi','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5004,0,NULL,'nyn','nyankole','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5005,0,NULL,'nyo','nyoro','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5006,0,NULL,'nyp','nyang''i','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5007,0,NULL,'nyq','nayini','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5008,0,NULL,'nyr','nyiha (malawi)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5009,0,NULL,'nys','nyunga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5010,0,NULL,'nyt','nyawaygi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5011,0,NULL,'nyu','nyungwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5012,0,NULL,'nyv','nyulnyul','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5013,0,NULL,'nyw','nyaw','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5014,0,NULL,'nyx','nganyaywana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5015,0,NULL,'nyy','nyakyusa-ngonde','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5016,0,NULL,'nza','tigon mbembe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5017,0,NULL,'nzb','njebi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5018,0,NULL,'nzi','nzima','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5019,0,NULL,'nzk','nzakara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5020,0,NULL,'nzm','zeme naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5021,0,NULL,'nzs','new zealand sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5022,0,NULL,'nzu','teke-nzikou','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5023,0,NULL,'nzy','nzakambay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5024,0,NULL,'nzz','nanga dama dogon','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5025,0,NULL,'oaa','orok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5026,0,NULL,'oac','oroch','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5027,0,NULL,'oar','ancient aramaic (up to 700 bce)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5027,0,NULL,'oar','old aramaic (up to 700 bce)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5028,0,NULL,'oav','old avar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5029,0,NULL,'obi','obispeño','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5030,0,NULL,'obk','southern bontok','1268265600',NULL,NULL,NULL,NULL,'bnc',NULL,NULL); +INSERT INTO "iana_records" VALUES(5031,0,NULL,'obl','oblo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5032,0,NULL,'obm','moabite','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5033,0,NULL,'obo','obo manobo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5034,0,NULL,'obr','old burmese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5035,0,NULL,'obt','old breton','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5036,0,NULL,'obu','obulom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5037,0,NULL,'oca','ocaina','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5038,0,NULL,'och','old chinese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5039,0,NULL,'oco','old cornish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5040,0,NULL,'ocu','atzingo matlatzinca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5041,0,NULL,'oda','odut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5042,0,NULL,'odk','od','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5043,0,NULL,'odt','old dutch','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5044,0,NULL,'odu','odual','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5045,0,NULL,'ofo','ofo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5046,0,NULL,'ofs','old frisian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5047,0,NULL,'ofu','efutop','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5048,0,NULL,'ogb','ogbia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5049,0,NULL,'ogc','ogbah','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5050,0,NULL,'oge','old georgian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5051,0,NULL,'ogg','ogbogolo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5052,0,NULL,'ogo','khana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5053,0,NULL,'ogu','ogbronuagum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5054,0,NULL,'oht','old hittite','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5055,0,NULL,'ohu','old hungarian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5056,0,NULL,'oia','oirata','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5057,0,NULL,'oin','inebu one','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5058,0,NULL,'ojb','northwestern ojibwa','1248825600',NULL,NULL,NULL,NULL,'oj',NULL,NULL); +INSERT INTO "iana_records" VALUES(5059,0,NULL,'ojc','central ojibwa','1248825600',NULL,NULL,NULL,NULL,'oj',NULL,NULL); +INSERT INTO "iana_records" VALUES(5060,0,NULL,'ojg','eastern ojibwa','1248825600',NULL,NULL,NULL,NULL,'oj',NULL,NULL); +INSERT INTO "iana_records" VALUES(5061,0,NULL,'ojp','old japanese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5062,0,NULL,'ojs','severn ojibwa','1248825600',NULL,NULL,NULL,NULL,'oj',NULL,NULL); +INSERT INTO "iana_records" VALUES(5063,0,NULL,'ojv','ontong java','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5064,0,NULL,'ojw','western ojibwa','1248825600',NULL,NULL,NULL,NULL,'oj',NULL,NULL); +INSERT INTO "iana_records" VALUES(5065,0,NULL,'oka','okanagan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5066,0,NULL,'okb','okobo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5067,0,NULL,'okd','okodia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5068,0,NULL,'oke','okpe (southwestern edo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5069,0,NULL,'okh','koresh-e rostam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5070,0,NULL,'oki','okiek','1248825600',NULL,NULL,NULL,NULL,'kln',NULL,NULL); +INSERT INTO "iana_records" VALUES(5071,0,NULL,'okj','oko-juwoi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5072,0,NULL,'okk','kwamtim one','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5073,0,NULL,'okl','old kentish sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5074,0,NULL,'okm','middle korean (10th-16th cent.)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5075,0,NULL,'okn','oki-no-erabu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5076,0,NULL,'oko','old korean (3rd-9th cent.)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5077,0,NULL,'okr','kirike','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5078,0,NULL,'oks','oko-eni-osayen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5079,0,NULL,'oku','oku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5080,0,NULL,'okv','orokaiva','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5081,0,NULL,'okx','okpe (northwestern edo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5082,0,NULL,'ola','walungge','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5083,0,NULL,'old','mochi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5084,0,NULL,'ole','olekha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5085,0,NULL,'olm','oloma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5086,0,NULL,'olo','livvi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5087,0,NULL,'olr','olrat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5088,0,NULL,'oma','omaha-ponca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5089,0,NULL,'omb','east ambae','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5090,0,NULL,'omc','mochica','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5091,0,NULL,'ome','omejes','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5092,0,NULL,'omg','omagua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5093,0,NULL,'omi','omi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5094,0,NULL,'omk','omok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5095,0,NULL,'oml','ombo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5096,0,NULL,'omn','minoan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5097,0,NULL,'omo','utarmbung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5098,0,NULL,'omp','old manipuri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5099,0,NULL,'omq','oto-manguean languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(5100,0,NULL,'omr','old marathi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5101,0,NULL,'omt','omotik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5102,0,NULL,'omu','omurano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5103,0,NULL,'omv','omotic languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(5104,0,NULL,'omw','south tairora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5105,0,NULL,'omx','old mon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5106,0,NULL,'ona','ona','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5107,0,NULL,'onb','lingao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5108,0,NULL,'one','oneida','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5109,0,NULL,'ong','olo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5110,0,NULL,'oni','onin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5111,0,NULL,'onj','onjob','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5112,0,NULL,'onk','kabore one','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5113,0,NULL,'onn','onobasulu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5114,0,NULL,'ono','onondaga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5115,0,NULL,'onp','sartang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5116,0,NULL,'onr','northern one','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5117,0,NULL,'ons','ono','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5118,0,NULL,'ont','ontenu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5119,0,NULL,'onu','unua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5120,0,NULL,'onw','old nubian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5121,0,NULL,'onx','onin based pidgin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5122,0,NULL,'ood','tohono o''odham','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5123,0,NULL,'oog','ong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5124,0,NULL,'oon','Önge','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5125,0,NULL,'oor','oorlams','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5126,0,NULL,'oos','old ossetic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5127,0,NULL,'opa','okpamheri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5128,0,NULL,'opk','kopkaka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5129,0,NULL,'opm','oksapmin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5130,0,NULL,'opo','opao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5131,0,NULL,'opt','opata','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5132,0,NULL,'opy','ofayé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5133,0,NULL,'ora','oroha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5134,0,NULL,'orc','orma','1248825600',NULL,NULL,NULL,NULL,'om',NULL,NULL); +INSERT INTO "iana_records" VALUES(5135,0,NULL,'ore','orejón','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5136,0,NULL,'org','oring','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5137,0,NULL,'orh','oroqen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5138,0,NULL,'orn','orang kanaq','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(5139,0,NULL,'oro','orokolo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5140,0,NULL,'orr','oruma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5141,0,NULL,'ors','orang seletar','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(5142,0,NULL,'ort','adivasi oriya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5143,0,NULL,'oru','ormuri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5144,0,NULL,'orv','old russian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5145,0,NULL,'orw','oro win','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5146,0,NULL,'orx','oro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5147,0,NULL,'orz','ormu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5148,0,NULL,'osa','osage','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5149,0,NULL,'osc','oscan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5150,0,NULL,'osi','osing','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5151,0,NULL,'oso','ososo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5152,0,NULL,'osp','old spanish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5153,0,NULL,'ost','osatu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5154,0,NULL,'osu','southern one','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5155,0,NULL,'osx','old saxon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5156,0,NULL,'ota','ottoman turkish (1500-1928)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5157,0,NULL,'otb','old tibetan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5158,0,NULL,'otd','ot danum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5159,0,NULL,'ote','mezquital otomi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5160,0,NULL,'oti','oti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5161,0,NULL,'otk','old turkish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5162,0,NULL,'otl','tilapa otomi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5163,0,NULL,'otm','eastern highland otomi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5164,0,NULL,'otn','tenango otomi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5165,0,NULL,'oto','otomian languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(5166,0,NULL,'otq','querétaro otomi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5167,0,NULL,'otr','otoro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5168,0,NULL,'ots','estado de méxico otomi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5169,0,NULL,'ott','temoaya otomi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5170,0,NULL,'otu','otuke','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5171,0,NULL,'otw','ottawa','1248825600',NULL,NULL,NULL,NULL,'oj',NULL,NULL); +INSERT INTO "iana_records" VALUES(5172,0,NULL,'otx','texcatepec otomi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5173,0,NULL,'oty','old tamil','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5174,0,NULL,'otz','ixtenco otomi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5175,0,NULL,'oua','tagargrent','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5176,0,NULL,'oub','glio-oubi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5177,0,NULL,'oue','ounge','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5178,0,NULL,'oui','old uighur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5179,0,NULL,'oum','ouma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5180,0,NULL,'oun','!o!ung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5181,0,NULL,'owi','owiniga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5182,0,NULL,'owl','old welsh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5183,0,NULL,'oyb','oy','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5184,0,NULL,'oyd','oyda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5185,0,NULL,'oym','wayampi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5186,0,NULL,'oyy','oya''oya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5187,0,NULL,'ozm','koonzime','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5188,0,NULL,'paa','papuan languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(5189,0,NULL,'pab','parecís','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5190,0,NULL,'pac','pacoh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5191,0,NULL,'pad','paumarí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5192,0,NULL,'pae','pagibete','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5193,0,NULL,'paf','paranawát','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5194,0,NULL,'pag','pangasinan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5195,0,NULL,'pah','tenharim','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5196,0,NULL,'pai','pe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5197,0,NULL,'pak','parakanã','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5198,0,NULL,'pal','pahlavi','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5199,0,NULL,'pam','kapampangan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5199,0,NULL,'pam','pampanga','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5200,0,NULL,'pao','northern paiute','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5201,0,NULL,'pap','papiamento','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5202,0,NULL,'paq','parya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5203,0,NULL,'par','panamint','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5203,0,NULL,'par','timbisha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5204,0,NULL,'pas','papasena','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5205,0,NULL,'pat','papitalai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5206,0,NULL,'pau','palauan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5207,0,NULL,'pav','pakaásnovos','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5208,0,NULL,'paw','pawnee','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5209,0,NULL,'pax','pankararé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5210,0,NULL,'pay','pech','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5211,0,NULL,'paz','pankararú','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5212,0,NULL,'pbb','páez','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5213,0,NULL,'pbc','patamona','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5214,0,NULL,'pbe','mezontla popoloca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5215,0,NULL,'pbf','coyotepec popoloca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5216,0,NULL,'pbg','paraujano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5217,0,NULL,'pbh','e''ñapa woromaipu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5218,0,NULL,'pbi','parkwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5219,0,NULL,'pbl','mak (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5220,0,NULL,'pbn','kpasam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5221,0,NULL,'pbo','papel','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5222,0,NULL,'pbp','badyara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5223,0,NULL,'pbr','pangwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5224,0,NULL,'pbs','central pame','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5225,0,NULL,'pbt','southern pashto','1248825600',NULL,NULL,NULL,NULL,'ps',NULL,NULL); +INSERT INTO "iana_records" VALUES(5226,0,NULL,'pbu','northern pashto','1248825600',NULL,NULL,NULL,NULL,'ps',NULL,NULL); +INSERT INTO "iana_records" VALUES(5227,0,NULL,'pbv','pnar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5228,0,NULL,'pby','pyu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5229,0,NULL,'pbz','palu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5230,0,NULL,'pca','santa inés ahuatempan popoloca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5231,0,NULL,'pcb','pear','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5232,0,NULL,'pcc','bouyei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5233,0,NULL,'pcd','picard','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5234,0,NULL,'pce','ruching palaung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5235,0,NULL,'pcf','paliyan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5236,0,NULL,'pcg','paniya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5237,0,NULL,'pch','pardhan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5238,0,NULL,'pci','duruwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5239,0,NULL,'pcj','parenga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5240,0,NULL,'pck','paite chin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5241,0,NULL,'pcl','pardhi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5242,0,NULL,'pcm','nigerian pidgin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5243,0,NULL,'pcn','piti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5244,0,NULL,'pcp','pacahuara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5245,0,NULL,'pcr','panang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5246,0,NULL,'pcw','pyapun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5247,0,NULL,'pda','anam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5248,0,NULL,'pdc','pennsylvania german','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5249,0,NULL,'pdi','pa di','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5250,0,NULL,'pdn','fedan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5250,0,NULL,'pdn','podena','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5251,0,NULL,'pdo','padoe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5252,0,NULL,'pdt','plautdietsch','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5253,0,NULL,'pdu','kayan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5254,0,NULL,'pea','peranakan indonesian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5255,0,NULL,'peb','eastern pomo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5256,0,NULL,'ped','mala (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5257,0,NULL,'pee','taje','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5258,0,NULL,'pef','northeastern pomo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5259,0,NULL,'peg','pengo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5260,0,NULL,'peh','bonan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5261,0,NULL,'pei','chichimeca-jonaz','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5262,0,NULL,'pej','northern pomo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5263,0,NULL,'pek','penchal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5264,0,NULL,'pel','pekal','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(5265,0,NULL,'pem','phende','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5266,0,NULL,'peo','old persian (ca. 600-400 b.c.)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5267,0,NULL,'pep','kunja','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5268,0,NULL,'peq','southern pomo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5269,0,NULL,'pes','iranian persian','1248825600',NULL,NULL,NULL,NULL,'fa',NULL,NULL); +INSERT INTO "iana_records" VALUES(5270,0,NULL,'pev','pémono','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5271,0,NULL,'pex','petats','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5272,0,NULL,'pey','petjo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5273,0,NULL,'pez','eastern penan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5274,0,NULL,'pfa','pááfang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5275,0,NULL,'pfe','peere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5276,0,NULL,'pfl','pfaelzisch','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5277,0,NULL,'pga','sudanese creole arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(5278,0,NULL,'pgg','pangwali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5279,0,NULL,'pgi','pagi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5280,0,NULL,'pgk','rerep','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5281,0,NULL,'pgn','paelignian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5282,0,NULL,'pgs','pangseng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5283,0,NULL,'pgu','pagu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5284,0,NULL,'pgy','pongyong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5285,0,NULL,'pha','pa-hng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5286,0,NULL,'phd','phudagi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5287,0,NULL,'phg','phuong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5288,0,NULL,'phh','phukha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5289,0,NULL,'phi','philippine languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(5290,0,NULL,'phk','phake','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5291,0,NULL,'phl','palula','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5291,0,NULL,'phl','phalura','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5292,0,NULL,'phm','phimbi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5293,0,NULL,'phn','phoenician','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5294,0,NULL,'pho','phunoi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5295,0,NULL,'phq','phana''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5296,0,NULL,'phr','pahari-potwari','1248825600',NULL,NULL,NULL,NULL,'lah',NULL,NULL); +INSERT INTO "iana_records" VALUES(5297,0,NULL,'pht','phu thai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5298,0,NULL,'phu','phuan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5299,0,NULL,'phv','pahlavani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5300,0,NULL,'phw','phangduwali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5301,0,NULL,'pia','pima bajo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5302,0,NULL,'pib','yine','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5303,0,NULL,'pic','pinji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5304,0,NULL,'pid','piaroa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5305,0,NULL,'pie','piro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5306,0,NULL,'pif','pingelapese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5307,0,NULL,'pig','pisabo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5308,0,NULL,'pih','pitcairn-norfolk','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5309,0,NULL,'pii','pini','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5310,0,NULL,'pij','pijao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5311,0,NULL,'pil','yom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5312,0,NULL,'pim','powhatan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5313,0,NULL,'pin','piame','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5314,0,NULL,'pio','piapoco','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5315,0,NULL,'pip','pero','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5316,0,NULL,'pir','piratapuyo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5317,0,NULL,'pis','pijin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5318,0,NULL,'pit','pitta pitta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5319,0,NULL,'piu','pintupi-luritja','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5320,0,NULL,'piv','pileni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5320,0,NULL,'piv','vaeakau-taumako','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5321,0,NULL,'piw','pimbwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5322,0,NULL,'pix','piu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5323,0,NULL,'piy','piya-kwonci','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5324,0,NULL,'piz','pije','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5325,0,NULL,'pjt','pitjantjatjara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5326,0,NULL,'pka','ardhamāgadhī prākrit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5327,0,NULL,'pkb','kipfokomo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5327,0,NULL,'pkb','pokomo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5328,0,NULL,'pkc','paekche','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5329,0,NULL,'pkg','pak-tong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5330,0,NULL,'pkh','pankhu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5331,0,NULL,'pkn','pakanha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5332,0,NULL,'pko','pökoot','1248825600',NULL,NULL,NULL,NULL,'kln',NULL,NULL); +INSERT INTO "iana_records" VALUES(5333,0,NULL,'pkp','pukapuka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5334,0,NULL,'pkr','attapady kurumba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5335,0,NULL,'pks','pakistan sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5336,0,NULL,'pkt','maleng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5337,0,NULL,'pku','paku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5338,0,NULL,'pla','miani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5339,0,NULL,'plb','polonombauk','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5340,0,NULL,'plc','central palawano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5341,0,NULL,'pld','polari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5342,0,NULL,'ple','palu''e','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5343,0,NULL,'plf','central malayo-polynesian languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(5344,0,NULL,'plg','pilagá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5345,0,NULL,'plh','paulohi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5346,0,NULL,'plj','polci','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5347,0,NULL,'plk','kohistani shina','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5348,0,NULL,'pll','shwe palaung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5349,0,NULL,'pln','palenquero','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5350,0,NULL,'plo','oluta popoluca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5351,0,NULL,'plp','palpa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5352,0,NULL,'plq','palaic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5353,0,NULL,'plr','palaka senoufo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5354,0,NULL,'pls','san marcos tlalcoyalco popoloca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5355,0,NULL,'plt','plateau malagasy','1248825600',NULL,NULL,NULL,NULL,'mg',NULL,NULL); +INSERT INTO "iana_records" VALUES(5356,0,NULL,'plu','palikúr','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5357,0,NULL,'plv','southwest palawano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5358,0,NULL,'plw','brooke''s point palawano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5359,0,NULL,'ply','bolyu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5360,0,NULL,'plz','paluan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5361,0,NULL,'pma','paama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5362,0,NULL,'pmb','pambia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5363,0,NULL,'pmc','palumata','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5364,0,NULL,'pme','pwaamei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5365,0,NULL,'pmf','pamona','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5366,0,NULL,'pmh','māhārāṣṭri prākrit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5367,0,NULL,'pmi','northern pumi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5368,0,NULL,'pmj','southern pumi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5369,0,NULL,'pmk','pamlico','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5370,0,NULL,'pml','lingua franca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5371,0,NULL,'pmm','pomo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5372,0,NULL,'pmn','pam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5373,0,NULL,'pmo','pom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5374,0,NULL,'pmq','northern pame','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5375,0,NULL,'pmr','paynamar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5376,0,NULL,'pms','piemontese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5377,0,NULL,'pmt','tuamotuan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5378,0,NULL,'pmu','mirpur panjabi','1248825600',NULL,NULL,NULL,NULL,'lah',NULL,NULL); +INSERT INTO "iana_records" VALUES(5379,0,NULL,'pmw','plains miwok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5380,0,NULL,'pmx','poumei naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5381,0,NULL,'pmy','papuan malay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5382,0,NULL,'pmz','southern pame','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5383,0,NULL,'pna','punan bah-biau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5384,0,NULL,'pnb','western panjabi','1248825600',NULL,NULL,NULL,NULL,'lah',NULL,NULL); +INSERT INTO "iana_records" VALUES(5385,0,NULL,'pnc','pannei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5386,0,NULL,'pne','western penan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5387,0,NULL,'png','pongu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5388,0,NULL,'pnh','penrhyn','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5389,0,NULL,'pni','aoheng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5390,0,NULL,'pnm','punan batu 1','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5391,0,NULL,'pnn','pinai-hagahai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5392,0,NULL,'pno','panobo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5393,0,NULL,'pnp','pancana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5394,0,NULL,'pnq','pana (burkina faso)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5395,0,NULL,'pnr','panim','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5396,0,NULL,'pns','ponosakan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5397,0,NULL,'pnt','pontic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5398,0,NULL,'pnu','jiongnai bunu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5399,0,NULL,'pnv','pinigura','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5400,0,NULL,'pnw','panytyima','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5401,0,NULL,'pnx','phong-kniang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5402,0,NULL,'pny','pinyin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,'a niger-congo language spoken in cameroon; not to be confused with the pinyin romanization systems used for chinese and tibetan'); +INSERT INTO "iana_records" VALUES(5403,0,NULL,'pnz','pana (central african republic)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5404,0,NULL,'poc','poqomam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5405,0,NULL,'pod','ponares','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5406,0,NULL,'poe','san juan atzingo popoloca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5407,0,NULL,'pof','poke','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5408,0,NULL,'pog','potiguára','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5409,0,NULL,'poh','poqomchi''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5410,0,NULL,'poi','highland popoluca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5411,0,NULL,'pok','pokangá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5412,0,NULL,'pom','southeastern pomo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5413,0,NULL,'pon','pohnpeian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5414,0,NULL,'poo','central pomo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5415,0,NULL,'pop','pwapwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5416,0,NULL,'poq','texistepec popoluca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5417,0,NULL,'pos','sayula popoluca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5418,0,NULL,'pot','potawatomi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5419,0,NULL,'pov','upper guinea crioulo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5420,0,NULL,'pow','san felipe otlaltepec popoloca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5421,0,NULL,'pox','polabian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5422,0,NULL,'poy','pogolo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5423,0,NULL,'poz','malayo-polynesian languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(5424,0,NULL,'ppa','pao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5425,0,NULL,'ppe','papi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5426,0,NULL,'ppi','paipai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5427,0,NULL,'ppk','uma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5428,0,NULL,'ppl','nicarao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5428,0,NULL,'ppl','pipil','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5429,0,NULL,'ppm','papuma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5430,0,NULL,'ppn','papapana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5431,0,NULL,'ppo','folopa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5432,0,NULL,'ppp','pelende','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5433,0,NULL,'ppq','pei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5434,0,NULL,'ppr','piru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5435,0,NULL,'pps','san luís temalacayuca popoloca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5436,0,NULL,'ppt','pare','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5437,0,NULL,'ppu','papora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5438,0,NULL,'pqa','pa''a','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5439,0,NULL,'pqe','eastern malayo-polynesian languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(5440,0,NULL,'pqm','malecite-passamaquoddy','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5441,0,NULL,'pqw','western malayo-polynesian languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(5442,0,NULL,'pra','prakrit languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(5443,0,NULL,'prb','lua''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5444,0,NULL,'prc','parachi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5445,0,NULL,'prd','parsi-dari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5446,0,NULL,'pre','principense','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5447,0,NULL,'prf','paranan','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5448,0,NULL,'prg','prussian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5449,0,NULL,'prh','porohanon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5450,0,NULL,'pri','paicî','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5451,0,NULL,'prk','parauk','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5452,0,NULL,'prl','peruvian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5453,0,NULL,'prm','kibiri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5454,0,NULL,'prn','prasuni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5455,0,NULL,'pro','old occitan (to 1500)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5455,0,NULL,'pro','old provençal (to 1500)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5456,0,NULL,'prp','parsi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5457,0,NULL,'prq','ashéninka perené','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5458,0,NULL,'prr','puri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5459,0,NULL,'prs','afghan persian','1248825600',NULL,NULL,NULL,NULL,'fa',NULL,NULL); +INSERT INTO "iana_records" VALUES(5459,0,NULL,'prs','dari','1248825600',NULL,NULL,NULL,NULL,'fa',NULL,NULL); +INSERT INTO "iana_records" VALUES(5460,0,NULL,'prt','phai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5461,0,NULL,'pru','puragi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5462,0,NULL,'prw','parawen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5463,0,NULL,'prx','purik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5464,0,NULL,'pry','pray 3','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5465,0,NULL,'prz','providencia sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5466,0,NULL,'psa','asue awyu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5467,0,NULL,'psc','persian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5468,0,NULL,'psd','plains indian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5469,0,NULL,'pse','central malay','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(5470,0,NULL,'psg','penang sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5471,0,NULL,'psh','southwest pashayi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5472,0,NULL,'psi','southeast pashayi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5473,0,NULL,'psl','puerto rican sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5474,0,NULL,'psm','pauserna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5475,0,NULL,'psn','panasuan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5476,0,NULL,'pso','polish sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5477,0,NULL,'psp','philippine sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5478,0,NULL,'psq','pasi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5479,0,NULL,'psr','portuguese sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5480,0,NULL,'pss','kaulong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5481,0,NULL,'pst','central pashto','1248825600',NULL,NULL,NULL,NULL,'ps',NULL,NULL); +INSERT INTO "iana_records" VALUES(5482,0,NULL,'psu','sauraseni prākrit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5483,0,NULL,'psw','port sandwich','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5484,0,NULL,'psy','piscataway','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5485,0,NULL,'pta','pai tavytera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5486,0,NULL,'pth','pataxó hã-ha-hãe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5487,0,NULL,'pti','pintiini','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5488,0,NULL,'ptn','patani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5489,0,NULL,'pto','zo''é','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5490,0,NULL,'ptp','patep','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5491,0,NULL,'ptr','piamatsina','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5492,0,NULL,'ptt','enrekang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5493,0,NULL,'ptu','bambam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5494,0,NULL,'ptv','port vato','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5495,0,NULL,'ptw','pentlatch','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5496,0,NULL,'pty','pathiya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5497,0,NULL,'pua','western highland purepecha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5498,0,NULL,'pub','purum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5499,0,NULL,'puc','punan merap','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5500,0,NULL,'pud','punan aput','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5501,0,NULL,'pue','puelche','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5502,0,NULL,'puf','punan merah','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5503,0,NULL,'pug','phuie','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5504,0,NULL,'pui','puinave','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5505,0,NULL,'puj','punan tubu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5506,0,NULL,'puk','pu ko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5507,0,NULL,'pum','puma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5508,0,NULL,'puo','puoc','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5509,0,NULL,'pup','pulabu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5510,0,NULL,'puq','puquina','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5511,0,NULL,'pur','puruborá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5512,0,NULL,'put','putoh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5513,0,NULL,'puu','punu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5514,0,NULL,'puw','puluwatese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5515,0,NULL,'pux','puare','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5516,0,NULL,'puy','purisimeño','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5517,0,NULL,'puz','purum naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5518,0,NULL,'pwa','pawaia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5519,0,NULL,'pwb','panawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5520,0,NULL,'pwg','gapapaiwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5521,0,NULL,'pwm','molbog','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5522,0,NULL,'pwn','paiwan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5523,0,NULL,'pwo','pwo western karen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5524,0,NULL,'pwr','powari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5525,0,NULL,'pww','pwo northern karen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5526,0,NULL,'pxm','quetzaltepec mixe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5527,0,NULL,'pye','pye krumen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5528,0,NULL,'pym','fyam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5529,0,NULL,'pyn','poyanáwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5530,0,NULL,'pys','lengua de señas del paraguay','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5530,0,NULL,'pys','paraguayan sign language','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5531,0,NULL,'pyu','puyuma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5532,0,NULL,'pyx','pyu (myanmar)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5533,0,NULL,'pyy','pyen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5534,0,NULL,'pzn','para naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5535,0,NULL,'qaa..qtz','private use','1129420800',NULL,NULL,NULL,NULL,NULL,'private-use',NULL); +INSERT INTO "iana_records" VALUES(5536,0,NULL,'qua','quapaw','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5537,0,NULL,'qub','huallaga huánuco quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5538,0,NULL,'quc','k''iche''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5538,0,NULL,'quc','quiché','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5539,0,NULL,'qud','calderón highland quichua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5540,0,NULL,'quf','lambayeque quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5541,0,NULL,'qug','chimborazo highland quichua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5542,0,NULL,'quh','south bolivian quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5543,0,NULL,'qui','quileute','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5544,0,NULL,'quk','chachapoyas quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5545,0,NULL,'qul','north bolivian quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5546,0,NULL,'qum','sipacapense','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5547,0,NULL,'qun','quinault','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5548,0,NULL,'qup','southern pastaza quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5549,0,NULL,'quq','quinqui','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5550,0,NULL,'qur','yanahuanca pasco quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5551,0,NULL,'qus','santiago del estero quichua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5552,0,NULL,'quv','sacapulteco','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5553,0,NULL,'quw','tena lowland quichua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5554,0,NULL,'qux','yauyos quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5555,0,NULL,'quy','ayacucho quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5556,0,NULL,'quz','cusco quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5557,0,NULL,'qva','ambo-pasco quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5558,0,NULL,'qvc','cajamarca quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5559,0,NULL,'qve','eastern apurímac quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5560,0,NULL,'qvh','huamalíes-dos de mayo huánuco quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5561,0,NULL,'qvi','imbabura highland quichua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5562,0,NULL,'qvj','loja highland quichua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5563,0,NULL,'qvl','cajatambo north lima quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5564,0,NULL,'qvm','margos-yarowilca-lauricocha quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5565,0,NULL,'qvn','north junín quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5566,0,NULL,'qvo','napo lowland quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5567,0,NULL,'qvp','pacaraos quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5568,0,NULL,'qvs','san martín quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5569,0,NULL,'qvw','huaylla wanca quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5570,0,NULL,'qvy','queyu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5571,0,NULL,'qvz','northern pastaza quichua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5572,0,NULL,'qwa','corongo ancash quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5573,0,NULL,'qwc','classical quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5574,0,NULL,'qwe','quechuan (family)','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(5575,0,NULL,'qwh','huaylas ancash quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5576,0,NULL,'qwm','kuman (russia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5577,0,NULL,'qws','sihuas ancash quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5578,0,NULL,'qwt','kwalhioqua-tlatskanai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5579,0,NULL,'qxa','chiquián ancash quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5580,0,NULL,'qxc','chincha quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5581,0,NULL,'qxh','panao huánuco quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5582,0,NULL,'qxl','salasaca highland quichua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5583,0,NULL,'qxn','northern conchucos ancash quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5584,0,NULL,'qxo','southern conchucos ancash quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5585,0,NULL,'qxp','puno quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5586,0,NULL,'qxq','qashqa''i','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5587,0,NULL,'qxr','cañar highland quichua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5588,0,NULL,'qxs','southern qiang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5589,0,NULL,'qxt','santa ana de tusi pasco quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5590,0,NULL,'qxu','arequipa-la unión quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5591,0,NULL,'qxw','jauja wanca quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5592,0,NULL,'qya','quenya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5593,0,NULL,'qyp','quiripi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5594,0,NULL,'raa','dungmali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5595,0,NULL,'rab','camling','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5596,0,NULL,'rac','rasawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5597,0,NULL,'rad','rade','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5598,0,NULL,'raf','western meohang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5599,0,NULL,'rag','logooli','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(5599,0,NULL,'rag','lulogooli','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(5600,0,NULL,'rah','rabha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5601,0,NULL,'rai','ramoaaina','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5602,0,NULL,'raj','rajasthani','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(5603,0,NULL,'rak','tulu-bohuai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5604,0,NULL,'ral','ralte','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5605,0,NULL,'ram','canela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5606,0,NULL,'ran','riantana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5607,0,NULL,'rao','rao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5608,0,NULL,'rap','rapanui','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5609,0,NULL,'raq','saam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5610,0,NULL,'rar','cook islands maori','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5610,0,NULL,'rar','rarotongan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5611,0,NULL,'ras','tegali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5612,0,NULL,'rat','razajerdi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5613,0,NULL,'rau','raute','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5614,0,NULL,'rav','sampang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5615,0,NULL,'raw','rawang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5616,0,NULL,'rax','rang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5617,0,NULL,'ray','rapa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5618,0,NULL,'raz','rahambuu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5619,0,NULL,'rbb','rumai palaung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5620,0,NULL,'rbk','northern bontok','1268265600',NULL,NULL,NULL,NULL,'bnc',NULL,NULL); +INSERT INTO "iana_records" VALUES(5621,0,NULL,'rbl','miraya bikol','1268265600',NULL,NULL,NULL,NULL,'bik',NULL,NULL); +INSERT INTO "iana_records" VALUES(5622,0,NULL,'rcf','réunion creole french','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5623,0,NULL,'rdb','rudbari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5624,0,NULL,'rea','rerau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5625,0,NULL,'reb','rembong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5626,0,NULL,'ree','rejang kayan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5627,0,NULL,'reg','kara (tanzania)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5628,0,NULL,'rei','reli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5629,0,NULL,'rej','rejang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5630,0,NULL,'rel','rendille','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5631,0,NULL,'rem','remo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5632,0,NULL,'ren','rengao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5633,0,NULL,'rer','rer bare','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5634,0,NULL,'res','reshe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5635,0,NULL,'ret','retta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5636,0,NULL,'rey','reyesano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5637,0,NULL,'rga','roria','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5638,0,NULL,'rge','romano-greek','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5639,0,NULL,'rgk','rangkas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5640,0,NULL,'rgn','romagnol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5641,0,NULL,'rgr','resígaro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5642,0,NULL,'rgs','southern roglai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5643,0,NULL,'rgu','ringgou','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5644,0,NULL,'rhg','rohingya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5645,0,NULL,'rhp','yahang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5646,0,NULL,'ria','riang (india)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5647,0,NULL,'rie','rien','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5648,0,NULL,'rif','tarifit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5649,0,NULL,'ril','riang (myanmar)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5650,0,NULL,'rim','nyaturu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5651,0,NULL,'rin','nungu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5652,0,NULL,'rir','ribun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5653,0,NULL,'rit','ritarungo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5654,0,NULL,'riu','riung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5655,0,NULL,'rjg','rajong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5656,0,NULL,'rji','raji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5657,0,NULL,'rjs','rajbanshi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5658,0,NULL,'rka','kraol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5659,0,NULL,'rkb','rikbaktsa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5660,0,NULL,'rkh','rakahanga-manihiki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5661,0,NULL,'rki','rakhine','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5662,0,NULL,'rkm','marka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5663,0,NULL,'rkt','kamta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5663,0,NULL,'rkt','rangpuri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5664,0,NULL,'rma','rama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5665,0,NULL,'rmb','rembarunga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5666,0,NULL,'rmc','carpathian romani','1248825600',NULL,NULL,NULL,NULL,'rom',NULL,NULL); +INSERT INTO "iana_records" VALUES(5667,0,NULL,'rmd','traveller danish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5668,0,NULL,'rme','angloromani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5669,0,NULL,'rmf','kalo finnish romani','1248825600',NULL,NULL,NULL,NULL,'rom',NULL,NULL); +INSERT INTO "iana_records" VALUES(5670,0,NULL,'rmg','traveller norwegian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5671,0,NULL,'rmh','murkim','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5672,0,NULL,'rmi','lomavren','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5673,0,NULL,'rmk','romkun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5674,0,NULL,'rml','baltic romani','1248825600',NULL,NULL,NULL,NULL,'rom',NULL,NULL); +INSERT INTO "iana_records" VALUES(5675,0,NULL,'rmm','roma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5676,0,NULL,'rmn','balkan romani','1248825600',NULL,NULL,NULL,NULL,'rom',NULL,NULL); +INSERT INTO "iana_records" VALUES(5677,0,NULL,'rmo','sinte romani','1248825600',NULL,NULL,NULL,NULL,'rom',NULL,NULL); +INSERT INTO "iana_records" VALUES(5678,0,NULL,'rmp','rempi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5679,0,NULL,'rmq','caló','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5680,0,NULL,'rmr','caló','1248825600',1268265600,NULL,NULL,NULL,NULL,NULL,'see emx, rmq'); +INSERT INTO "iana_records" VALUES(5681,0,NULL,'rms','romanian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5682,0,NULL,'rmt','domari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5683,0,NULL,'rmu','tavringer romani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5684,0,NULL,'rmv','romanova','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5685,0,NULL,'rmw','welsh romani','1248825600',NULL,NULL,NULL,NULL,'rom',NULL,NULL); +INSERT INTO "iana_records" VALUES(5686,0,NULL,'rmx','romam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5687,0,NULL,'rmy','vlax romani','1248825600',NULL,NULL,NULL,NULL,'rom',NULL,NULL); +INSERT INTO "iana_records" VALUES(5688,0,NULL,'rmz','marma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5689,0,NULL,'rna','runa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5690,0,NULL,'rnd','ruund','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5691,0,NULL,'rng','ronga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5692,0,NULL,'rnl','ranglong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5693,0,NULL,'rnn','roon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5694,0,NULL,'rnp','rongpo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5695,0,NULL,'rnw','rungwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5696,0,NULL,'roa','romance languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(5697,0,NULL,'rob','tae''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5698,0,NULL,'roc','cacgia roglai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5699,0,NULL,'rod','rogo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5700,0,NULL,'roe','ronji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5701,0,NULL,'rof','rombo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5702,0,NULL,'rog','northern roglai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5703,0,NULL,'rol','romblomanon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5704,0,NULL,'rom','romany','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(5705,0,NULL,'roo','rotokas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5706,0,NULL,'rop','kriol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5707,0,NULL,'ror','rongga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5708,0,NULL,'rou','runga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5709,0,NULL,'row','dela-oenale','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5710,0,NULL,'rpn','repanbitip','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5711,0,NULL,'rpt','rapting','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5712,0,NULL,'rri','ririo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5713,0,NULL,'rro','waima','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5714,0,NULL,'rsb','romano-serbian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5715,0,NULL,'rsi','rennellese sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5716,0,NULL,'rsl','russian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5717,0,NULL,'rth','ratahan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5718,0,NULL,'rtm','rotuman','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5719,0,NULL,'rtw','rathawi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5720,0,NULL,'rub','gungu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5721,0,NULL,'ruc','ruuli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5722,0,NULL,'rue','rusyn','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5723,0,NULL,'ruf','luguru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5724,0,NULL,'rug','roviana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5725,0,NULL,'ruh','ruga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5726,0,NULL,'rui','rufiji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5727,0,NULL,'ruk','che','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5728,0,NULL,'ruo','istro romanian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5729,0,NULL,'rup','aromanian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5729,0,NULL,'rup','arumanian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5729,0,NULL,'rup','macedo-romanian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5730,0,NULL,'ruq','megleno romanian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5731,0,NULL,'rut','rutul','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5732,0,NULL,'ruu','lanas lobu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5733,0,NULL,'ruy','mala (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5734,0,NULL,'ruz','ruma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5735,0,NULL,'rwa','rawo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5736,0,NULL,'rwk','rwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5737,0,NULL,'rwm','amba (uganda)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5738,0,NULL,'rwo','rawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5739,0,NULL,'rwr','marwari (india)','1248825600',NULL,NULL,NULL,NULL,'mwr',NULL,NULL); +INSERT INTO "iana_records" VALUES(5740,0,NULL,'ryn','northern amami-oshima','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5741,0,NULL,'rys','yaeyama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5742,0,NULL,'ryu','central okinawan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5743,0,NULL,'saa','saba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5744,0,NULL,'sab','buglere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5745,0,NULL,'sac','meskwaki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5746,0,NULL,'sad','sandawe','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5747,0,NULL,'sae','sabanê','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5748,0,NULL,'saf','safaliba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5749,0,NULL,'sah','yakut','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5750,0,NULL,'sai','south american indian languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(5751,0,NULL,'saj','sahu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5752,0,NULL,'sak','sake','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5753,0,NULL,'sal','salishan languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(5754,0,NULL,'sam','samaritan aramaic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5755,0,NULL,'sao','sause','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5756,0,NULL,'sap','sanapaná','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5757,0,NULL,'saq','samburu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5758,0,NULL,'sar','saraveca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5759,0,NULL,'sas','sasak','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5760,0,NULL,'sat','santali','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5761,0,NULL,'sau','saleman','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5762,0,NULL,'sav','saafi-saafi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5763,0,NULL,'saw','sawi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5764,0,NULL,'sax','sa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5765,0,NULL,'say','saya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5766,0,NULL,'saz','saurashtra','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5767,0,NULL,'sba','ngambay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5768,0,NULL,'sbb','simbo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5769,0,NULL,'sbc','kele (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5770,0,NULL,'sbd','southern samo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5771,0,NULL,'sbe','saliba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5772,0,NULL,'sbf','shabo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5773,0,NULL,'sbg','seget','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5774,0,NULL,'sbh','sori-harengan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5775,0,NULL,'sbi','seti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5776,0,NULL,'sbj','surbakhal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5777,0,NULL,'sbk','safwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5778,0,NULL,'sbl','botolan sambal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5779,0,NULL,'sbm','sagala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5780,0,NULL,'sbn','sindhi bhil','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5781,0,NULL,'sbo','sabüm','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5782,0,NULL,'sbp','sangu (tanzania)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5783,0,NULL,'sbq','sileibi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5784,0,NULL,'sbr','sembakung murut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5785,0,NULL,'sbs','subiya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5786,0,NULL,'sbt','kimki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5787,0,NULL,'sbu','stod bhoti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5788,0,NULL,'sbv','sabine','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5789,0,NULL,'sbw','simba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5790,0,NULL,'sbx','seberuang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5791,0,NULL,'sby','soli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5792,0,NULL,'sbz','sara kaba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5793,0,NULL,'sca','sansu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5794,0,NULL,'scb','chut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5795,0,NULL,'sce','dongxiang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5796,0,NULL,'scf','san miguel creole french','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5797,0,NULL,'scg','sanggau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5798,0,NULL,'sch','sakachep','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5799,0,NULL,'sci','sri lankan creole malay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5800,0,NULL,'sck','sadri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5801,0,NULL,'scl','shina','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5802,0,NULL,'scn','sicilian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5803,0,NULL,'sco','scots','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5804,0,NULL,'scp','helambu sherpa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5805,0,NULL,'scq','sa''och','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5806,0,NULL,'scs','north slavey','1248825600',NULL,NULL,NULL,NULL,'den',NULL,NULL); +INSERT INTO "iana_records" VALUES(5807,0,NULL,'scu','shumcho','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5808,0,NULL,'scv','sheni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5809,0,NULL,'scw','sha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5810,0,NULL,'scx','sicel','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5811,0,NULL,'sda','toraja-sa''dan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5812,0,NULL,'sdb','shabak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5813,0,NULL,'sdc','sassarese sardinian','1248825600',NULL,NULL,NULL,NULL,'sc',NULL,NULL); +INSERT INTO "iana_records" VALUES(5814,0,NULL,'sde','surubu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5815,0,NULL,'sdf','sarli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5816,0,NULL,'sdg','savi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5817,0,NULL,'sdh','southern kurdish','1248825600',NULL,NULL,NULL,NULL,'ku',NULL,NULL); +INSERT INTO "iana_records" VALUES(5818,0,NULL,'sdj','suundi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5819,0,NULL,'sdk','sos kundi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5820,0,NULL,'sdl','saudi arabian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5821,0,NULL,'sdm','semandang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5822,0,NULL,'sdn','gallurese sardinian','1248825600',NULL,NULL,NULL,NULL,'sc',NULL,NULL); +INSERT INTO "iana_records" VALUES(5823,0,NULL,'sdo','bukar-sadung bidayuh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5824,0,NULL,'sdp','sherdukpen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5825,0,NULL,'sdr','oraon sadri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5826,0,NULL,'sds','sened','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5827,0,NULL,'sdt','shuadit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5828,0,NULL,'sdu','sarudu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5829,0,NULL,'sdv','eastern sudanic languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(5830,0,NULL,'sdx','sibu melanau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5831,0,NULL,'sdz','sallands','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5832,0,NULL,'sea','semai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5833,0,NULL,'seb','shempire senoufo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5834,0,NULL,'sec','sechelt','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5835,0,NULL,'sed','sedang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5836,0,NULL,'see','seneca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5837,0,NULL,'sef','cebaara senoufo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5838,0,NULL,'seg','segeju','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5839,0,NULL,'seh','sena','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5840,0,NULL,'sei','seri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5841,0,NULL,'sej','sene','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5842,0,NULL,'sek','sekani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5843,0,NULL,'sel','selkup','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5844,0,NULL,'sem','semitic languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(5845,0,NULL,'sen','nanerigé sénoufo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5846,0,NULL,'seo','suarmin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5847,0,NULL,'sep','sìcìté sénoufo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5848,0,NULL,'seq','senara sénoufo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5849,0,NULL,'ser','serrano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5850,0,NULL,'ses','koyraboro senni songhai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5851,0,NULL,'set','sentani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5852,0,NULL,'seu','serui-laut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5853,0,NULL,'sev','nyarafolo senoufo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5854,0,NULL,'sew','sewa bay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5855,0,NULL,'sey','secoya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5856,0,NULL,'sez','senthang chin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5857,0,NULL,'sfb','french belgian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5857,0,NULL,'sfb','langue des signes de belgique francophone','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5858,0,NULL,'sfm','small flowery miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(5859,0,NULL,'sfs','south african sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5860,0,NULL,'sfw','sehwi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5861,0,NULL,'sga','old irish (to 900)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5862,0,NULL,'sgb','mag-antsi ayta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5863,0,NULL,'sgc','kipsigis','1248825600',NULL,NULL,NULL,NULL,'kln',NULL,NULL); +INSERT INTO "iana_records" VALUES(5864,0,NULL,'sgd','surigaonon','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5865,0,NULL,'sge','segai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5866,0,NULL,'sgg','swiss-german sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5867,0,NULL,'sgh','shughni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5868,0,NULL,'sgi','suga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5869,0,NULL,'sgk','sangkong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5870,0,NULL,'sgl','sanglechi-ishkashimi','1248825600',1268265600,NULL,NULL,NULL,NULL,NULL,'see isk, sgy'); +INSERT INTO "iana_records" VALUES(5871,0,NULL,'sgm','singa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5872,0,NULL,'sgn','sign languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(5873,0,NULL,'sgo','songa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5874,0,NULL,'sgp','singpho','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5875,0,NULL,'sgr','sangisari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5876,0,NULL,'sgt','brokpake','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5877,0,NULL,'sgu','salas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5878,0,NULL,'sgw','sebat bet gurage','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5879,0,NULL,'sgx','sierra leone sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5880,0,NULL,'sgy','sanglechi','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5881,0,NULL,'sgz','sursurunga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5882,0,NULL,'sha','shall-zwall','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5883,0,NULL,'shb','ninam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5884,0,NULL,'shc','sonde','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5885,0,NULL,'shd','kundal shahi','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5886,0,NULL,'she','sheko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5887,0,NULL,'shg','shua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5888,0,NULL,'shh','shoshoni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5889,0,NULL,'shi','tachelhit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5890,0,NULL,'shj','shatt','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5891,0,NULL,'shk','shilluk','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5892,0,NULL,'shl','shendu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5893,0,NULL,'shm','shahrudi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5894,0,NULL,'shn','shan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5895,0,NULL,'sho','shanga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5896,0,NULL,'shp','shipibo-conibo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5897,0,NULL,'shq','sala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5898,0,NULL,'shr','shi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5899,0,NULL,'shs','shuswap','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5900,0,NULL,'sht','shasta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5901,0,NULL,'shu','chadian arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(5902,0,NULL,'shv','shehri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5903,0,NULL,'shw','shwai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5904,0,NULL,'shx','she','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5905,0,NULL,'shy','tachawit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5906,0,NULL,'shz','syenara senoufo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5907,0,NULL,'sia','akkala sami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5908,0,NULL,'sib','sebop','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5909,0,NULL,'sid','sidamo','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5910,0,NULL,'sie','simaa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5911,0,NULL,'sif','siamou','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5912,0,NULL,'sig','paasaal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5913,0,NULL,'sih','zire','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5914,0,NULL,'sii','shom peng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5915,0,NULL,'sij','numbami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5916,0,NULL,'sik','sikiana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5917,0,NULL,'sil','tumulung sisaala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5918,0,NULL,'sim','mende (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5919,0,NULL,'sio','siouan languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(5920,0,NULL,'sip','sikkimese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5921,0,NULL,'siq','sonia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5922,0,NULL,'sir','siri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5923,0,NULL,'sis','siuslaw','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5924,0,NULL,'sit','sino-tibetan languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(5925,0,NULL,'siu','sinagen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5926,0,NULL,'siv','sumariup','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5927,0,NULL,'siw','siwai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5928,0,NULL,'six','sumau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5929,0,NULL,'siy','sivandi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5930,0,NULL,'siz','siwi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5931,0,NULL,'sja','epena','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5932,0,NULL,'sjb','sajau basap','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5933,0,NULL,'sjd','kildin sami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5934,0,NULL,'sje','pite sami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5935,0,NULL,'sjg','assangori','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5936,0,NULL,'sjk','kemi sami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5937,0,NULL,'sjl','miji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5937,0,NULL,'sjl','sajalong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5938,0,NULL,'sjm','mapun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5939,0,NULL,'sjn','sindarin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5940,0,NULL,'sjo','xibe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5941,0,NULL,'sjp','surjapuri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5942,0,NULL,'sjr','siar-lak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5943,0,NULL,'sjs','senhaja de srair','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5944,0,NULL,'sjt','ter sami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5945,0,NULL,'sju','ume sami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5946,0,NULL,'sjw','shawnee','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5947,0,NULL,'ska','skagit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5948,0,NULL,'skb','saek','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5949,0,NULL,'skc','sauk','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5950,0,NULL,'skd','southern sierra miwok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5951,0,NULL,'ske','seke (vanuatu)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5952,0,NULL,'skf','sakirabiá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5953,0,NULL,'skg','sakalava malagasy','1248825600',NULL,NULL,NULL,NULL,'mg',NULL,NULL); +INSERT INTO "iana_records" VALUES(5954,0,NULL,'skh','sikule','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5955,0,NULL,'ski','sika','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5956,0,NULL,'skj','seke (nepal)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5957,0,NULL,'skk','sok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5958,0,NULL,'skm','sakam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5959,0,NULL,'skn','kolibugan subanon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5960,0,NULL,'sko','seko tengah','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5961,0,NULL,'skp','sekapan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5962,0,NULL,'skq','sininkere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5963,0,NULL,'skr','seraiki','1248825600',NULL,NULL,NULL,NULL,'lah',NULL,NULL); +INSERT INTO "iana_records" VALUES(5964,0,NULL,'sks','maia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5965,0,NULL,'skt','sakata','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5966,0,NULL,'sku','sakao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5967,0,NULL,'skv','skou','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5968,0,NULL,'skw','skepi creole dutch','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5969,0,NULL,'skx','seko padang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5970,0,NULL,'sky','sikaiana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5971,0,NULL,'skz','sekar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5972,0,NULL,'sla','slavic languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(5973,0,NULL,'slc','sáliba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5974,0,NULL,'sld','sissala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5975,0,NULL,'sle','sholaga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5976,0,NULL,'slf','swiss-italian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5977,0,NULL,'slg','selungai murut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5978,0,NULL,'slh','southern puget sound salish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5979,0,NULL,'sli','lower silesian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5980,0,NULL,'slj','salumá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5981,0,NULL,'sll','salt-yui','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5982,0,NULL,'slm','pangutaran sama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5983,0,NULL,'sln','salinan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5984,0,NULL,'slp','lamaholot','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5985,0,NULL,'slq','salchuq','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5986,0,NULL,'slr','salar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5987,0,NULL,'sls','singapore sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5988,0,NULL,'slt','sila','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5989,0,NULL,'slu','selaru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5990,0,NULL,'slw','sialum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5991,0,NULL,'slx','salampasu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5992,0,NULL,'sly','selayar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5993,0,NULL,'slz','ma''ya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5994,0,NULL,'sma','southern sami','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5995,0,NULL,'smb','simbari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5996,0,NULL,'smc','som','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5997,0,NULL,'smd','sama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5998,0,NULL,'smf','auwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5999,0,NULL,'smg','simbali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6000,0,NULL,'smh','samei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6001,0,NULL,'smi','sami languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(6002,0,NULL,'smj','lule sami','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6003,0,NULL,'smk','bolinao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6004,0,NULL,'sml','central sama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6005,0,NULL,'smm','musasa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6006,0,NULL,'smn','inari sami','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6007,0,NULL,'smp','samaritan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6008,0,NULL,'smq','samo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6009,0,NULL,'smr','simeulue','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6010,0,NULL,'sms','skolt sami','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6011,0,NULL,'smt','simte','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6012,0,NULL,'smu','somray','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6013,0,NULL,'smv','samvedi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6014,0,NULL,'smw','sumbawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6015,0,NULL,'smx','samba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6016,0,NULL,'smy','semnani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6017,0,NULL,'smz','simeku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6018,0,NULL,'snb','sebuyau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6019,0,NULL,'snc','sinaugoro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6020,0,NULL,'sne','bau bidayuh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6021,0,NULL,'snf','noon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6022,0,NULL,'sng','sanga (democratic republic of congo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6023,0,NULL,'snh','shinabo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6024,0,NULL,'sni','sensi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6025,0,NULL,'snj','riverain sango','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6026,0,NULL,'snk','soninke','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6027,0,NULL,'snl','sangil','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6028,0,NULL,'snm','southern ma''di','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6029,0,NULL,'snn','siona','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6030,0,NULL,'sno','snohomish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6031,0,NULL,'snp','siane','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6032,0,NULL,'snq','sangu (gabon)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6033,0,NULL,'snr','sihan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6034,0,NULL,'sns','nahavaq','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6034,0,NULL,'sns','south west bay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6035,0,NULL,'snu','senggi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6035,0,NULL,'snu','viid','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6036,0,NULL,'snv','sa''ban','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6037,0,NULL,'snw','selee','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6038,0,NULL,'snx','sam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6039,0,NULL,'sny','saniyo-hiyewe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6040,0,NULL,'snz','sinsauru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6041,0,NULL,'soa','thai song','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6042,0,NULL,'sob','sobei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6043,0,NULL,'soc','so (democratic republic of congo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6044,0,NULL,'sod','songoora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6045,0,NULL,'soe','songomeno','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6046,0,NULL,'sog','sogdian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6047,0,NULL,'soh','aka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6048,0,NULL,'soi','sonha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6049,0,NULL,'soj','soi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6050,0,NULL,'sok','sokoro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6051,0,NULL,'sol','solos','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6052,0,NULL,'son','songhai languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(6053,0,NULL,'soo','songo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6054,0,NULL,'sop','songe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6055,0,NULL,'soq','kanasi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6056,0,NULL,'sor','somrai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6057,0,NULL,'sos','seeku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6058,0,NULL,'sou','southern thai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6059,0,NULL,'sov','sonsorol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6060,0,NULL,'sow','sowanda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6061,0,NULL,'sox','so (cameroon)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6062,0,NULL,'soy','miyobe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6063,0,NULL,'soz','temi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6064,0,NULL,'spb','sepa (indonesia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6065,0,NULL,'spc','sapé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6066,0,NULL,'spd','saep','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6067,0,NULL,'spe','sepa (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6068,0,NULL,'spg','sian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6069,0,NULL,'spi','saponi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6070,0,NULL,'spk','sengo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6071,0,NULL,'spl','selepet','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6072,0,NULL,'spm','sepen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6073,0,NULL,'spo','spokane','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6074,0,NULL,'spp','supyire senoufo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6075,0,NULL,'spq','loreto-ucayali spanish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6076,0,NULL,'spr','saparua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6077,0,NULL,'sps','saposa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6078,0,NULL,'spt','spiti bhoti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6079,0,NULL,'spu','sapuan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6080,0,NULL,'spx','south picene','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6081,0,NULL,'spy','sabaot','1248825600',NULL,NULL,NULL,NULL,'kln',NULL,NULL); +INSERT INTO "iana_records" VALUES(6082,0,NULL,'sqa','shama-sambuga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6083,0,NULL,'sqh','shau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6084,0,NULL,'sqj','albanian languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(6085,0,NULL,'sqm','suma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6086,0,NULL,'sqn','susquehannock','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6087,0,NULL,'sqo','sorkhei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6088,0,NULL,'sqq','sou','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6089,0,NULL,'sqr','siculo arabic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6090,0,NULL,'sqs','sri lankan sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6091,0,NULL,'sqt','soqotri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6092,0,NULL,'squ','squamish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6093,0,NULL,'sra','saruga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6094,0,NULL,'srb','sora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6095,0,NULL,'src','logudorese sardinian','1248825600',NULL,NULL,NULL,NULL,'sc',NULL,NULL); +INSERT INTO "iana_records" VALUES(6096,0,NULL,'sre','sara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6097,0,NULL,'srf','nafi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6098,0,NULL,'srg','sulod','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6099,0,NULL,'srh','sarikoli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6100,0,NULL,'sri','siriano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6101,0,NULL,'srk','serudung murut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6102,0,NULL,'srl','isirawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6103,0,NULL,'srm','saramaccan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6104,0,NULL,'srn','sranan tongo','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6105,0,NULL,'sro','campidanese sardinian','1248825600',NULL,NULL,NULL,NULL,'sc',NULL,NULL); +INSERT INTO "iana_records" VALUES(6106,0,NULL,'srq','sirionó','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6107,0,NULL,'srr','serer','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6108,0,NULL,'srs','sarsi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6109,0,NULL,'srt','sauri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6110,0,NULL,'sru','suruí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6111,0,NULL,'srv','southern sorsoganon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6112,0,NULL,'srw','serua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6113,0,NULL,'srx','sirmauri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6114,0,NULL,'sry','sera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6115,0,NULL,'srz','shahmirzadi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6116,0,NULL,'ssa','nilo-saharan languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(6117,0,NULL,'ssb','southern sama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6118,0,NULL,'ssc','suba-simbiti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6119,0,NULL,'ssd','siroi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6120,0,NULL,'sse','balangingi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6120,0,NULL,'sse','bangingih sama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6121,0,NULL,'ssf','thao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6122,0,NULL,'ssg','seimat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6123,0,NULL,'ssh','shihhi arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(6124,0,NULL,'ssi','sansi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6125,0,NULL,'ssj','sausi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6126,0,NULL,'ssk','sunam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6127,0,NULL,'ssl','western sisaala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6128,0,NULL,'ssm','semnam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6129,0,NULL,'ssn','waata','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6130,0,NULL,'sso','sissano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6131,0,NULL,'ssp','spanish sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6132,0,NULL,'ssq','so''a','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6133,0,NULL,'ssr','swiss-french sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6134,0,NULL,'sss','sô','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6135,0,NULL,'sst','sinasina','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6136,0,NULL,'ssu','susuami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6137,0,NULL,'ssv','shark bay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6138,0,NULL,'ssx','samberigi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6139,0,NULL,'ssy','saho','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6140,0,NULL,'ssz','sengseng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6141,0,NULL,'sta','settla','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6142,0,NULL,'stb','northern subanen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6143,0,NULL,'std','sentinel','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6144,0,NULL,'ste','liana-seti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6145,0,NULL,'stf','seta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6146,0,NULL,'stg','trieng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6147,0,NULL,'sth','shelta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6148,0,NULL,'sti','bulo stieng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6149,0,NULL,'stj','matya samo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6150,0,NULL,'stk','arammba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6151,0,NULL,'stl','stellingwerfs','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6152,0,NULL,'stm','setaman','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6153,0,NULL,'stn','owa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6154,0,NULL,'sto','stoney','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6155,0,NULL,'stp','southeastern tepehuan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6156,0,NULL,'stq','saterfriesisch','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6157,0,NULL,'str','straits salish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6158,0,NULL,'sts','shumashti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6159,0,NULL,'stt','budeh stieng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6160,0,NULL,'stu','samtao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6161,0,NULL,'stv','silt''e','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6162,0,NULL,'stw','satawalese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6163,0,NULL,'sua','sulka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6164,0,NULL,'sub','suku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6165,0,NULL,'suc','western subanon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6166,0,NULL,'sue','suena','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6167,0,NULL,'sug','suganga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6168,0,NULL,'sui','suki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6169,0,NULL,'suj','shubi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6170,0,NULL,'suk','sukuma','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6171,0,NULL,'sul','surigaonon','1248825600',1268265600,NULL,NULL,NULL,NULL,NULL,'see sgd, tgn'); +INSERT INTO "iana_records" VALUES(6172,0,NULL,'sum','sumo-mayangna','1248825600',1268265600,NULL,NULL,NULL,NULL,NULL,'see ulw, yan'); +INSERT INTO "iana_records" VALUES(6173,0,NULL,'suq','suri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6174,0,NULL,'sur','mwaghavul','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6175,0,NULL,'sus','susu','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6176,0,NULL,'sut','subtiaba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6177,0,NULL,'suv','sulung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6178,0,NULL,'suw','sumbwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6179,0,NULL,'sux','sumerian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6180,0,NULL,'suy','suyá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6181,0,NULL,'suz','sunwar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6182,0,NULL,'sva','svan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6183,0,NULL,'svb','ulau-suain','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6184,0,NULL,'svc','vincentian creole english','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6185,0,NULL,'sve','serili','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6186,0,NULL,'svk','slovakian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6187,0,NULL,'svr','savara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6188,0,NULL,'svs','savosavo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6189,0,NULL,'svx','skalvian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6190,0,NULL,'swb','maore comorian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6191,0,NULL,'swc','congo swahili','1248825600',NULL,NULL,NULL,NULL,'sw',NULL,NULL); +INSERT INTO "iana_records" VALUES(6192,0,NULL,'swf','sere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6193,0,NULL,'swg','swabian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6194,0,NULL,'swh','kiswahili','1248825600',NULL,NULL,NULL,NULL,'sw',NULL,NULL); +INSERT INTO "iana_records" VALUES(6194,0,NULL,'swh','swahili (individual language)','1248825600',NULL,NULL,NULL,NULL,'sw',NULL,NULL); +INSERT INTO "iana_records" VALUES(6195,0,NULL,'swi','sui','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6196,0,NULL,'swj','sira','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6197,0,NULL,'swk','malawi sena','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6198,0,NULL,'swl','swedish sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6199,0,NULL,'swm','samosa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6200,0,NULL,'swn','sawknah','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6201,0,NULL,'swo','shanenawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6202,0,NULL,'swp','suau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6203,0,NULL,'swq','sharwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6204,0,NULL,'swr','saweru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6205,0,NULL,'sws','seluwasan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6206,0,NULL,'swt','sawila','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6207,0,NULL,'swu','suwawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6208,0,NULL,'swv','shekhawati','1248825600',NULL,NULL,NULL,NULL,'mwr',NULL,NULL); +INSERT INTO "iana_records" VALUES(6209,0,NULL,'sww','sowa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6210,0,NULL,'swx','suruahá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6211,0,NULL,'swy','sarua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6212,0,NULL,'sxb','suba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6213,0,NULL,'sxc','sicanian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6214,0,NULL,'sxe','sighu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6215,0,NULL,'sxg','shixing','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6216,0,NULL,'sxk','southern kalapuya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6217,0,NULL,'sxl','selian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6218,0,NULL,'sxm','samre','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6219,0,NULL,'sxn','sangir','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6220,0,NULL,'sxo','sorothaptic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6221,0,NULL,'sxr','saaroa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6222,0,NULL,'sxs','sasaru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6223,0,NULL,'sxu','upper saxon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6224,0,NULL,'sxw','saxwe gbe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6225,0,NULL,'sya','siang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6226,0,NULL,'syb','central subanen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6227,0,NULL,'syc','classical syriac','1175558400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6228,0,NULL,'syd','samoyedic languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(6229,0,NULL,'syi','seki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6230,0,NULL,'syk','sukur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6231,0,NULL,'syl','sylheti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6232,0,NULL,'sym','maya samo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6233,0,NULL,'syn','senaya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6234,0,NULL,'syo','suoy','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6235,0,NULL,'syr','syriac','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(6236,0,NULL,'sys','sinyar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6237,0,NULL,'syw','kagate','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6238,0,NULL,'syy','al-sayyid bedouin sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6239,0,NULL,'sza','semelai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6240,0,NULL,'szb','ngalum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6241,0,NULL,'szc','semaq beri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6242,0,NULL,'szd','seru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6243,0,NULL,'sze','seze','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6244,0,NULL,'szg','sengele','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6245,0,NULL,'szl','silesian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6246,0,NULL,'szn','sula','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6247,0,NULL,'szp','suabo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6248,0,NULL,'szv','isu (fako division)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6249,0,NULL,'szw','sawai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6250,0,NULL,'taa','lower tanana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6251,0,NULL,'tab','tabassaran','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6252,0,NULL,'tac','lowland tarahumara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6253,0,NULL,'tad','tause','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6254,0,NULL,'tae','tariana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6255,0,NULL,'taf','tapirapé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6256,0,NULL,'tag','tagoi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6257,0,NULL,'tai','tai languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(6258,0,NULL,'taj','eastern tamang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6259,0,NULL,'tak','tala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6260,0,NULL,'tal','tal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6261,0,NULL,'tan','tangale','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6262,0,NULL,'tao','yami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6263,0,NULL,'tap','taabwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6264,0,NULL,'taq','tamasheq','1248825600',NULL,NULL,NULL,NULL,'tmh',NULL,NULL); +INSERT INTO "iana_records" VALUES(6265,0,NULL,'tar','central tarahumara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6266,0,NULL,'tas','tay boi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6267,0,NULL,'tau','upper tanana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6268,0,NULL,'tav','tatuyo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6269,0,NULL,'taw','tai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6270,0,NULL,'tax','tamki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6271,0,NULL,'tay','atayal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6272,0,NULL,'taz','tocho','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6273,0,NULL,'tba','aikanã','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6274,0,NULL,'tbb','tapeba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6275,0,NULL,'tbc','takia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6276,0,NULL,'tbd','kaki ae','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6277,0,NULL,'tbe','tanimbili','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6278,0,NULL,'tbf','mandara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6279,0,NULL,'tbg','north tairora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6280,0,NULL,'tbh','thurawal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6281,0,NULL,'tbi','gaam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6282,0,NULL,'tbj','tiang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6283,0,NULL,'tbk','calamian tagbanwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6284,0,NULL,'tbl','tboli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6285,0,NULL,'tbm','tagbu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6286,0,NULL,'tbn','barro negro tunebo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6287,0,NULL,'tbo','tawala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6288,0,NULL,'tbp','diebroud','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6288,0,NULL,'tbp','taworta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6289,0,NULL,'tbq','tibeto-burman languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(6290,0,NULL,'tbr','tumtum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6291,0,NULL,'tbs','tanguat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6292,0,NULL,'tbt','tembo (kitembo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6293,0,NULL,'tbu','tubar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6294,0,NULL,'tbv','tobo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6295,0,NULL,'tbw','tagbanwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6296,0,NULL,'tbx','kapin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6297,0,NULL,'tby','tabaru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6298,0,NULL,'tbz','ditammari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6299,0,NULL,'tca','ticuna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6300,0,NULL,'tcb','tanacross','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6301,0,NULL,'tcc','datooga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6302,0,NULL,'tcd','tafi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6303,0,NULL,'tce','southern tutchone','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6304,0,NULL,'tcf','malinaltepec me''phaa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6304,0,NULL,'tcf','malinaltepec tlapanec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6305,0,NULL,'tcg','tamagario','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6306,0,NULL,'tch','turks and caicos creole english','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6307,0,NULL,'tci','wára','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6308,0,NULL,'tck','tchitchege','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6309,0,NULL,'tcl','taman (myanmar)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6310,0,NULL,'tcm','tanahmerah','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6311,0,NULL,'tcn','tichurong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6312,0,NULL,'tco','taungyo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6313,0,NULL,'tcp','tawr chin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6314,0,NULL,'tcq','kaiy','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6315,0,NULL,'tcs','torres strait creole','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6316,0,NULL,'tct','t''en','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6317,0,NULL,'tcu','southeastern tarahumara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6318,0,NULL,'tcw','tecpatlán totonac','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6319,0,NULL,'tcx','toda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6320,0,NULL,'tcy','tulu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6321,0,NULL,'tcz','thado chin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6322,0,NULL,'tda','tagdal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6323,0,NULL,'tdb','panchpargania','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6324,0,NULL,'tdc','emberá-tadó','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6325,0,NULL,'tdd','tai nüa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6326,0,NULL,'tde','tiranige diga dogon','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6327,0,NULL,'tdf','talieng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6328,0,NULL,'tdg','western tamang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6329,0,NULL,'tdh','thulung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6330,0,NULL,'tdi','tomadino','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6331,0,NULL,'tdj','tajio','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6332,0,NULL,'tdk','tambas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6333,0,NULL,'tdl','sur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6334,0,NULL,'tdn','tondano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6335,0,NULL,'tdo','teme','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6336,0,NULL,'tdq','tita','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6337,0,NULL,'tdr','todrah','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6338,0,NULL,'tds','doutai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6339,0,NULL,'tdt','tetun dili','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6340,0,NULL,'tdu','tempasuk dusun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6341,0,NULL,'tdv','toro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6342,0,NULL,'tdx','tandroy-mahafaly malagasy','1248825600',NULL,NULL,NULL,NULL,'mg',NULL,NULL); +INSERT INTO "iana_records" VALUES(6343,0,NULL,'tdy','tadyawan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6344,0,NULL,'tea','temiar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6345,0,NULL,'teb','tetete','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6346,0,NULL,'tec','terik','1248825600',NULL,NULL,NULL,NULL,'kln',NULL,NULL); +INSERT INTO "iana_records" VALUES(6347,0,NULL,'ted','tepo krumen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6348,0,NULL,'tee','huehuetla tepehua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6349,0,NULL,'tef','teressa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6350,0,NULL,'teg','teke-tege','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6351,0,NULL,'teh','tehuelche','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6352,0,NULL,'tei','torricelli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6353,0,NULL,'tek','ibali teke','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6354,0,NULL,'tem','timne','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6355,0,NULL,'ten','tama (colombia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6356,0,NULL,'teo','teso','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6357,0,NULL,'tep','tepecano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6358,0,NULL,'teq','temein','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6359,0,NULL,'ter','tereno','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6360,0,NULL,'tes','tengger','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6361,0,NULL,'tet','tetum','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6362,0,NULL,'teu','soo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6363,0,NULL,'tev','teor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6364,0,NULL,'tew','tewa (usa)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6365,0,NULL,'tex','tennet','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6366,0,NULL,'tey','tulishi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6367,0,NULL,'tfi','tofin gbe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6368,0,NULL,'tfn','tanaina','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6369,0,NULL,'tfo','tefaro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6370,0,NULL,'tfr','teribe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6371,0,NULL,'tft','ternate','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6372,0,NULL,'tga','sagalla','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6373,0,NULL,'tgb','tobilung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6374,0,NULL,'tgc','tigak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6375,0,NULL,'tgd','ciwogai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6376,0,NULL,'tge','eastern gorkha tamang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6377,0,NULL,'tgf','chalikha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6378,0,NULL,'tgg','tangga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6379,0,NULL,'tgh','tobagonian creole english','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6380,0,NULL,'tgi','lawunuia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6381,0,NULL,'tgn','tandaganon','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6382,0,NULL,'tgo','sudest','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6383,0,NULL,'tgp','tangoa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6384,0,NULL,'tgq','tring','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6385,0,NULL,'tgr','tareng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6386,0,NULL,'tgs','nume','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6387,0,NULL,'tgt','central tagbanwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6388,0,NULL,'tgu','tanggu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6389,0,NULL,'tgv','tingui-boto','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6390,0,NULL,'tgw','tagwana senoufo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6391,0,NULL,'tgx','tagish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6392,0,NULL,'tgy','togoyo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6393,0,NULL,'thc','tai hang tong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6394,0,NULL,'thd','thayore','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6395,0,NULL,'the','chitwania tharu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6396,0,NULL,'thf','thangmi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6397,0,NULL,'thh','northern tarahumara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6398,0,NULL,'thi','tai long','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6399,0,NULL,'thk','kitharaka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6399,0,NULL,'thk','tharaka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6400,0,NULL,'thl','dangaura tharu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6401,0,NULL,'thm','aheu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6402,0,NULL,'thn','thachanadan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6403,0,NULL,'thp','thompson','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6404,0,NULL,'thq','kochila tharu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6405,0,NULL,'thr','rana tharu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6406,0,NULL,'ths','thakali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6407,0,NULL,'tht','tahltan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6408,0,NULL,'thu','thuri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6409,0,NULL,'thv','tahaggart tamahaq','1248825600',NULL,NULL,NULL,NULL,'tmh',NULL,NULL); +INSERT INTO "iana_records" VALUES(6410,0,NULL,'thw','thudam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6411,0,NULL,'thx','the','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6412,0,NULL,'thy','tha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6413,0,NULL,'thz','tayart tamajeq','1248825600',NULL,NULL,NULL,NULL,'tmh',NULL,NULL); +INSERT INTO "iana_records" VALUES(6414,0,NULL,'tia','tidikelt tamazight','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6415,0,NULL,'tic','tira','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6416,0,NULL,'tid','tidong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6417,0,NULL,'tie','tingal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6418,0,NULL,'tif','tifal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6419,0,NULL,'tig','tigre','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6420,0,NULL,'tih','timugon murut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6421,0,NULL,'tii','tiene','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6422,0,NULL,'tij','tilung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6423,0,NULL,'tik','tikar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6424,0,NULL,'til','tillamook','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6425,0,NULL,'tim','timbe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6426,0,NULL,'tin','tindi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6427,0,NULL,'tio','teop','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6428,0,NULL,'tip','trimuris','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6429,0,NULL,'tiq','tiéfo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6430,0,NULL,'tis','masadiit itneg','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6431,0,NULL,'tit','tinigua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6432,0,NULL,'tiu','adasen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6433,0,NULL,'tiv','tiv','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6434,0,NULL,'tiw','tiwi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6435,0,NULL,'tix','southern tiwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6436,0,NULL,'tiy','tiruray','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6437,0,NULL,'tiz','tai hongjin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6438,0,NULL,'tja','tajuasohn','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6439,0,NULL,'tjg','tunjung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6440,0,NULL,'tji','northern tujia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6441,0,NULL,'tjm','timucua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6442,0,NULL,'tjn','tonjon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6443,0,NULL,'tjo','temacine tamazight','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6444,0,NULL,'tjs','southern tujia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6445,0,NULL,'tju','tjurruru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6446,0,NULL,'tka','truká','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6447,0,NULL,'tkb','buksa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6448,0,NULL,'tkd','tukudede','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6449,0,NULL,'tke','takwane','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6450,0,NULL,'tkf','tukumanféd','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6451,0,NULL,'tkk','takpa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6452,0,NULL,'tkl','tokelau','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6453,0,NULL,'tkm','takelma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6454,0,NULL,'tkn','toku-no-shima','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6455,0,NULL,'tkp','tikopia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6456,0,NULL,'tkq','tee','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6457,0,NULL,'tkr','tsakhur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6458,0,NULL,'tks','takestani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6459,0,NULL,'tkt','kathoriya tharu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6460,0,NULL,'tku','upper necaxa totonac','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6461,0,NULL,'tkw','teanu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6462,0,NULL,'tkx','tangko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6463,0,NULL,'tkz','takua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6464,0,NULL,'tla','southwestern tepehuan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6465,0,NULL,'tlb','tobelo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6466,0,NULL,'tlc','yecuatla totonac','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6467,0,NULL,'tld','talaud','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6468,0,NULL,'tlf','telefol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6469,0,NULL,'tlg','tofanma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6470,0,NULL,'tlh','klingon','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6470,0,NULL,'tlh','tlhingan-hol','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6471,0,NULL,'tli','tlingit','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6472,0,NULL,'tlj','talinga-bwisi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6473,0,NULL,'tlk','taloki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6474,0,NULL,'tll','tetela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6475,0,NULL,'tlm','tolomako','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6476,0,NULL,'tln','talondo''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6477,0,NULL,'tlo','talodi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6478,0,NULL,'tlp','filomena mata-coahuitlán totonac','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6479,0,NULL,'tlq','tai loi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6480,0,NULL,'tlr','talise','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6481,0,NULL,'tls','tambotalo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6482,0,NULL,'tlt','teluti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6483,0,NULL,'tlu','tulehu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6484,0,NULL,'tlv','taliabu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6485,0,NULL,'tlw','south wemale','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6486,0,NULL,'tlx','khehek','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6487,0,NULL,'tly','talysh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6488,0,NULL,'tma','tama (chad)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6489,0,NULL,'tmb','avava','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6489,0,NULL,'tmb','katbol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6490,0,NULL,'tmc','tumak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6491,0,NULL,'tmd','haruai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6492,0,NULL,'tme','tremembé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6493,0,NULL,'tmf','toba-maskoy','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6494,0,NULL,'tmg','ternateño','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6495,0,NULL,'tmh','tamashek','1129420800',NULL,NULL,NULL,'latn',NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(6496,0,NULL,'tmi','tutuba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6497,0,NULL,'tmj','samarokena','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6498,0,NULL,'tmk','northwestern tamang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6499,0,NULL,'tml','tamnim citak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6500,0,NULL,'tmm','tai thanh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6501,0,NULL,'tmn','taman (indonesia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6502,0,NULL,'tmo','temoq','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6503,0,NULL,'tmp','tai mène','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6504,0,NULL,'tmq','tumleo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6505,0,NULL,'tmr','jewish babylonian aramaic (ca. 200-1200 ce)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6506,0,NULL,'tms','tima','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6507,0,NULL,'tmt','tasmate','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6508,0,NULL,'tmu','iau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6509,0,NULL,'tmv','tembo (motembo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6510,0,NULL,'tmw','temuan','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(6511,0,NULL,'tmy','tami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6512,0,NULL,'tmz','tamanaku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6513,0,NULL,'tna','tacana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6514,0,NULL,'tnb','western tunebo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6515,0,NULL,'tnc','tanimuca-retuarã','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6516,0,NULL,'tnd','angosturas tunebo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6517,0,NULL,'tne','tinoc kallahan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6518,0,NULL,'tnf','tangshewi','1248825600',1268265600,'prs',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6519,0,NULL,'tng','tobanga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6520,0,NULL,'tnh','maiani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6521,0,NULL,'tni','tandia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6522,0,NULL,'tnk','kwamera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6523,0,NULL,'tnl','lenakel','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6524,0,NULL,'tnm','tabla','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6525,0,NULL,'tnn','north tanna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6526,0,NULL,'tno','toromono','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6527,0,NULL,'tnp','whitesands','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6528,0,NULL,'tnq','taino','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6529,0,NULL,'tnr','bedik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6530,0,NULL,'tns','tenis','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6531,0,NULL,'tnt','tontemboan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6532,0,NULL,'tnu','tay khang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6533,0,NULL,'tnv','tangchangya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6534,0,NULL,'tnw','tonsawang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6535,0,NULL,'tnx','tanema','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6536,0,NULL,'tny','tongwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6537,0,NULL,'tnz','tonga (thailand)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6538,0,NULL,'tob','toba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6539,0,NULL,'toc','coyutla totonac','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6540,0,NULL,'tod','toma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6541,0,NULL,'toe','tomedes','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6542,0,NULL,'tof','gizrra','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6543,0,NULL,'tog','tonga (nyasa)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6544,0,NULL,'toh','gitonga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6545,0,NULL,'toi','tonga (zambia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6546,0,NULL,'toj','tojolabal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6547,0,NULL,'tol','tolowa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6548,0,NULL,'tom','tombulu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6549,0,NULL,'too','xicotepec de juárez totonac','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6550,0,NULL,'top','papantla totonac','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6551,0,NULL,'toq','toposa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6552,0,NULL,'tor','togbo-vara banda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6553,0,NULL,'tos','highland totonac','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6554,0,NULL,'tou','tho','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6555,0,NULL,'tov','upper taromi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6556,0,NULL,'tow','jemez','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6557,0,NULL,'tox','tobian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6558,0,NULL,'toy','topoiyo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6559,0,NULL,'toz','to','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6560,0,NULL,'tpa','taupota','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6561,0,NULL,'tpc','azoyú me''phaa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6561,0,NULL,'tpc','azoyú tlapanec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6562,0,NULL,'tpe','tippera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6563,0,NULL,'tpf','tarpia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6564,0,NULL,'tpg','kula','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6565,0,NULL,'tpi','tok pisin','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6566,0,NULL,'tpj','tapieté','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6567,0,NULL,'tpk','tupinikin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6568,0,NULL,'tpl','tlacoapa me''phaa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6568,0,NULL,'tpl','tlacoapa tlapanec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6569,0,NULL,'tpm','tampulma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6570,0,NULL,'tpn','tupinambá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6571,0,NULL,'tpo','tai pao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6572,0,NULL,'tpp','pisaflores tepehua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6573,0,NULL,'tpq','tukpa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6574,0,NULL,'tpr','tuparí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6575,0,NULL,'tpt','tlachichilco tepehua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6576,0,NULL,'tpu','tampuan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6577,0,NULL,'tpv','tanapag','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6578,0,NULL,'tpw','tupí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6579,0,NULL,'tpx','acatepec me''phaa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6579,0,NULL,'tpx','acatepec tlapanec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6580,0,NULL,'tpy','trumai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6581,0,NULL,'tpz','tinputz','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6582,0,NULL,'tqb','tembé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6583,0,NULL,'tql','lehali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6584,0,NULL,'tqm','turumsa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6585,0,NULL,'tqn','tenino','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6586,0,NULL,'tqo','toaripi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6587,0,NULL,'tqp','tomoip','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6588,0,NULL,'tqq','tunni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6589,0,NULL,'tqr','torona','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6590,0,NULL,'tqt','western totonac','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6591,0,NULL,'tqu','touo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6592,0,NULL,'tqw','tonkawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6593,0,NULL,'tra','tirahi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6594,0,NULL,'trb','terebu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6595,0,NULL,'trc','copala triqui','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6596,0,NULL,'trd','turi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6597,0,NULL,'tre','east tarangan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6598,0,NULL,'trf','trinidadian creole english','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6599,0,NULL,'trg','lishán didán','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6600,0,NULL,'trh','turaka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6601,0,NULL,'tri','trió','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6602,0,NULL,'trj','toram','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6603,0,NULL,'trk','turkic languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(6604,0,NULL,'trl','traveller scottish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6605,0,NULL,'trm','tregami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6606,0,NULL,'trn','trinitario','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6607,0,NULL,'tro','tarao naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6608,0,NULL,'trp','kok borok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6609,0,NULL,'trq','san martín itunyoso triqui','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6610,0,NULL,'trr','taushiro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6611,0,NULL,'trs','chicahuaxtla triqui','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6612,0,NULL,'trt','tunggare','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6613,0,NULL,'tru','turoyo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6614,0,NULL,'trv','taroko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6615,0,NULL,'trw','torwali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6616,0,NULL,'trx','tringgus-sembaan bidayuh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6617,0,NULL,'try','turung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6618,0,NULL,'trz','torá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6619,0,NULL,'tsa','tsaangi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6620,0,NULL,'tsb','tsamai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6621,0,NULL,'tsc','tswa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6622,0,NULL,'tsd','tsakonian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6623,0,NULL,'tse','tunisian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6624,0,NULL,'tsf','southwestern tamang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6625,0,NULL,'tsg','tausug','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6626,0,NULL,'tsh','tsuvan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6627,0,NULL,'tsi','tsimshian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6628,0,NULL,'tsj','tshangla','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6629,0,NULL,'tsk','tseku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6630,0,NULL,'tsl','ts''ün-lao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6631,0,NULL,'tsm','turkish sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6631,0,NULL,'tsm','türk İşaret dili','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6632,0,NULL,'tsp','northern toussian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6633,0,NULL,'tsq','thai sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6634,0,NULL,'tsr','akei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6635,0,NULL,'tss','taiwan sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6636,0,NULL,'tsu','tsou','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6637,0,NULL,'tsv','tsogo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6638,0,NULL,'tsw','tsishingini','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6639,0,NULL,'tsx','mubami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6640,0,NULL,'tsy','tebul sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6641,0,NULL,'tsz','purepecha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6642,0,NULL,'tta','tutelo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6643,0,NULL,'ttb','gaa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6644,0,NULL,'ttc','tektiteko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6645,0,NULL,'ttd','tauade','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6646,0,NULL,'tte','bwanabwana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6647,0,NULL,'ttf','tuotomb','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6648,0,NULL,'ttg','tutong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6649,0,NULL,'tth','upper ta''oih','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6650,0,NULL,'tti','tobati','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6651,0,NULL,'ttj','tooro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6652,0,NULL,'ttk','totoro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6653,0,NULL,'ttl','totela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6654,0,NULL,'ttm','northern tutchone','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6655,0,NULL,'ttn','towei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6656,0,NULL,'tto','lower ta''oih','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6657,0,NULL,'ttp','tombelala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6658,0,NULL,'ttq','tawallammat tamajaq','1248825600',NULL,NULL,NULL,NULL,'tmh',NULL,NULL); +INSERT INTO "iana_records" VALUES(6659,0,NULL,'ttr','tera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6660,0,NULL,'tts','northeastern thai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6661,0,NULL,'ttt','muslim tat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6662,0,NULL,'ttu','torau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6663,0,NULL,'ttv','titan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6664,0,NULL,'ttw','long wat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6665,0,NULL,'tty','sikaritai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6666,0,NULL,'ttz','tsum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6667,0,NULL,'tua','wiarumus','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6668,0,NULL,'tub','tübatulabal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6669,0,NULL,'tuc','mutu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6670,0,NULL,'tud','tuxá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6671,0,NULL,'tue','tuyuca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6672,0,NULL,'tuf','central tunebo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6673,0,NULL,'tug','tunia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6674,0,NULL,'tuh','taulil','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6675,0,NULL,'tui','tupuri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6676,0,NULL,'tuj','tugutil','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6677,0,NULL,'tul','tula','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6678,0,NULL,'tum','tumbuka','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6679,0,NULL,'tun','tunica','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6680,0,NULL,'tuo','tucano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6681,0,NULL,'tup','tupi languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(6682,0,NULL,'tuq','tedaga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6683,0,NULL,'tus','tuscarora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6684,0,NULL,'tut','altaic languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(6685,0,NULL,'tuu','tututni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6686,0,NULL,'tuv','turkana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6687,0,NULL,'tuw','tungus languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(6688,0,NULL,'tux','tuxináwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6689,0,NULL,'tuy','tugen','1248825600',NULL,NULL,NULL,NULL,'kln',NULL,NULL); +INSERT INTO "iana_records" VALUES(6690,0,NULL,'tuz','turka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6691,0,NULL,'tva','vaghua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6692,0,NULL,'tvd','tsuvadi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6693,0,NULL,'tve','te''un','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6694,0,NULL,'tvk','southeast ambrym','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6695,0,NULL,'tvl','tuvalu','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6696,0,NULL,'tvm','tela-masbuar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6697,0,NULL,'tvn','tavoyan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6698,0,NULL,'tvo','tidore','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6699,0,NULL,'tvs','taveta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6700,0,NULL,'tvt','tutsa naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6701,0,NULL,'tvw','sedoa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6702,0,NULL,'tvy','timor pidgin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6703,0,NULL,'twa','twana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6704,0,NULL,'twb','western tawbuid','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6705,0,NULL,'twc','teshenawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6706,0,NULL,'twd','twents','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6707,0,NULL,'twe','tewa (indonesia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6708,0,NULL,'twf','northern tiwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6709,0,NULL,'twg','tereweng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6710,0,NULL,'twh','tai dón','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6711,0,NULL,'twl','tawara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6712,0,NULL,'twm','tawang monpa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6713,0,NULL,'twn','twendi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6714,0,NULL,'two','tswapong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6715,0,NULL,'twp','ere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6716,0,NULL,'twq','tasawaq','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6717,0,NULL,'twr','southwestern tarahumara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6718,0,NULL,'twt','turiwára','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6719,0,NULL,'twu','termanu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6720,0,NULL,'tww','tuwari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6721,0,NULL,'twx','tewe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6722,0,NULL,'twy','tawoyan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6723,0,NULL,'txa','tombonuo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6724,0,NULL,'txb','tokharian b','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6725,0,NULL,'txc','tsetsaut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6726,0,NULL,'txe','totoli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6727,0,NULL,'txg','tangut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6728,0,NULL,'txh','thracian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6729,0,NULL,'txi','ikpeng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6730,0,NULL,'txm','tomini','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6731,0,NULL,'txn','west tarangan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6732,0,NULL,'txo','toto','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6733,0,NULL,'txq','tii','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6734,0,NULL,'txr','tartessian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6735,0,NULL,'txs','tonsea','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6736,0,NULL,'txt','citak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6737,0,NULL,'txu','kayapó','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6738,0,NULL,'txx','tatana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6739,0,NULL,'txy','tanosy malagasy','1248825600',NULL,NULL,NULL,NULL,'mg',NULL,NULL); +INSERT INTO "iana_records" VALUES(6740,0,NULL,'tya','tauya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6741,0,NULL,'tye','kyenga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6742,0,NULL,'tyh','o''du','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6743,0,NULL,'tyi','teke-tsaayi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6744,0,NULL,'tyj','tai do','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6745,0,NULL,'tyl','thu lao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6746,0,NULL,'tyn','kombai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6747,0,NULL,'typ','thaypan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6748,0,NULL,'tyr','tai daeng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6749,0,NULL,'tys','tày sa pa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6750,0,NULL,'tyt','tày tac','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6751,0,NULL,'tyu','kua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6752,0,NULL,'tyv','tuvinian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6753,0,NULL,'tyx','teke-tyee','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6754,0,NULL,'tyz','tày','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6755,0,NULL,'tza','tanzanian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6756,0,NULL,'tzh','tzeltal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6757,0,NULL,'tzj','tz''utujil','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6758,0,NULL,'tzm','central atlas tamazight','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6759,0,NULL,'tzn','tugun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6760,0,NULL,'tzo','tzotzil','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6761,0,NULL,'tzx','tabriak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6762,0,NULL,'uam','uamué','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6763,0,NULL,'uan','kuan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6764,0,NULL,'uar','tairuma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6765,0,NULL,'uba','ubang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6766,0,NULL,'ubi','ubi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6767,0,NULL,'ubl','buhi''non bikol','1268265600',NULL,NULL,NULL,NULL,'bik',NULL,NULL); +INSERT INTO "iana_records" VALUES(6768,0,NULL,'ubr','ubir','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6769,0,NULL,'ubu','umbu-ungu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6770,0,NULL,'uby','ubykh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6771,0,NULL,'uda','uda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6772,0,NULL,'ude','udihe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6773,0,NULL,'udg','muduga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6774,0,NULL,'udi','udi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6775,0,NULL,'udj','ujir','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6776,0,NULL,'udl','wuzlam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6777,0,NULL,'udm','udmurt','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6778,0,NULL,'udu','uduk','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6779,0,NULL,'ues','kioko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6780,0,NULL,'ufi','ufim','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6781,0,NULL,'uga','ugaritic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6782,0,NULL,'ugb','kuku-ugbanh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6783,0,NULL,'uge','ughele','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6784,0,NULL,'ugn','ugandan sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6785,0,NULL,'ugo','ugong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6786,0,NULL,'ugy','uruguayan sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6787,0,NULL,'uha','uhami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6788,0,NULL,'uhn','damal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6789,0,NULL,'uis','uisai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6790,0,NULL,'uiv','iyive','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6791,0,NULL,'uji','tanjijili','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6792,0,NULL,'uka','kaburi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6793,0,NULL,'ukg','ukuriguma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6794,0,NULL,'ukh','ukhwejo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6795,0,NULL,'ukl','ukrainian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6796,0,NULL,'ukp','ukpe-bayobiri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6797,0,NULL,'ukq','ukwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6798,0,NULL,'uks','kaapor sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6798,0,NULL,'uks','urubú-kaapor sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6799,0,NULL,'uku','ukue','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6800,0,NULL,'ukw','ukwuani-aboh-ndoni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6801,0,NULL,'ula','fungwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6802,0,NULL,'ulb','ulukwumi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6803,0,NULL,'ulc','ulch','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6804,0,NULL,'ulf','afra','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6804,0,NULL,'ulf','usku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6805,0,NULL,'uli','ulithian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6806,0,NULL,'ulk','meriam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6807,0,NULL,'ull','ullatan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6808,0,NULL,'ulm','ulumanda''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6809,0,NULL,'uln','unserdeutsch','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6810,0,NULL,'ulu','uma'' lung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6811,0,NULL,'ulw','ulwa','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6812,0,NULL,'uma','umatilla','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6813,0,NULL,'umb','umbundu','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6814,0,NULL,'umc','marrucinian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6815,0,NULL,'umd','umbindhamu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6816,0,NULL,'umg','umbuygamu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6817,0,NULL,'umi','ukit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6818,0,NULL,'umm','umon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6819,0,NULL,'umn','makyan naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6820,0,NULL,'umo','umotína','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6821,0,NULL,'ump','umpila','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6822,0,NULL,'umr','umbugarla','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6823,0,NULL,'ums','pendau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6824,0,NULL,'umu','munsee','1248825600',NULL,NULL,NULL,NULL,'del',NULL,NULL); +INSERT INTO "iana_records" VALUES(6825,0,NULL,'una','north watut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6826,0,NULL,'und','undetermined','1129420800',NULL,NULL,NULL,NULL,NULL,'special',NULL); +INSERT INTO "iana_records" VALUES(6827,0,NULL,'une','uneme','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6828,0,NULL,'ung','ngarinyin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6829,0,NULL,'unk','enawené-nawé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6830,0,NULL,'unm','unami','1248825600',NULL,NULL,NULL,NULL,'del',NULL,NULL); +INSERT INTO "iana_records" VALUES(6831,0,NULL,'unp','worora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6832,0,NULL,'unr','mundari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6833,0,NULL,'unx','munda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6834,0,NULL,'unz','unde kaili','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6835,0,NULL,'uok','uokha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6836,0,NULL,'upi','umeda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6837,0,NULL,'upv','uripiv-wala-rano-atchin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6838,0,NULL,'ura','urarina','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6839,0,NULL,'urb','kaapor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6839,0,NULL,'urb','urubú-kaapor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6840,0,NULL,'urc','urningangg','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6841,0,NULL,'ure','uru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6842,0,NULL,'urf','uradhi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6843,0,NULL,'urg','urigina','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6844,0,NULL,'urh','urhobo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6845,0,NULL,'uri','urim','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6846,0,NULL,'urj','uralic languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(6847,0,NULL,'urk','urak lawoi''','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(6848,0,NULL,'url','urali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6849,0,NULL,'urm','urapmin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6850,0,NULL,'urn','uruangnirin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6851,0,NULL,'uro','ura (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6852,0,NULL,'urp','uru-pa-in','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6853,0,NULL,'urr','lehalurup','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6853,0,NULL,'urr','löyöp','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6854,0,NULL,'urt','urat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6855,0,NULL,'uru','urumi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6856,0,NULL,'urv','uruava','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6857,0,NULL,'urw','sop','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6858,0,NULL,'urx','urimo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6859,0,NULL,'ury','orya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6860,0,NULL,'urz','uru-eu-wau-wau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6861,0,NULL,'usa','usarufa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6862,0,NULL,'ush','ushojo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6863,0,NULL,'usi','usui','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6864,0,NULL,'usk','usaghade','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6865,0,NULL,'usp','uspanteco','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6866,0,NULL,'usu','uya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6867,0,NULL,'uta','otank','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6868,0,NULL,'ute','ute-southern paiute','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6869,0,NULL,'utp','amba (solomon islands)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6870,0,NULL,'utr','etulo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6871,0,NULL,'utu','utu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6872,0,NULL,'uum','urum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6873,0,NULL,'uun','kulon-pazeh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6874,0,NULL,'uur','ura (vanuatu)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6875,0,NULL,'uuu','u','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6876,0,NULL,'uve','west uvean','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6877,0,NULL,'uvh','uri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6878,0,NULL,'uvl','lote','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6879,0,NULL,'uwa','kuku-uwanh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6880,0,NULL,'uya','doko-uyanga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6881,0,NULL,'uzn','northern uzbek','1248825600',NULL,NULL,NULL,NULL,'uz',NULL,NULL); +INSERT INTO "iana_records" VALUES(6882,0,NULL,'uzs','southern uzbek','1248825600',NULL,NULL,NULL,NULL,'uz',NULL,NULL); +INSERT INTO "iana_records" VALUES(6883,0,NULL,'vaa','vaagri booli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6884,0,NULL,'vae','vale','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6885,0,NULL,'vaf','vafsi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6886,0,NULL,'vag','vagla','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6887,0,NULL,'vah','varhadi-nagpuri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6888,0,NULL,'vai','vai','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6889,0,NULL,'vaj','vasekela bushman','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6890,0,NULL,'val','vehes','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6891,0,NULL,'vam','vanimo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6892,0,NULL,'van','valman','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6893,0,NULL,'vao','vao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6894,0,NULL,'vap','vaiphei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6895,0,NULL,'var','huarijio','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6896,0,NULL,'vas','vasavi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6897,0,NULL,'vau','vanuma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6898,0,NULL,'vav','varli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6899,0,NULL,'vay','wayu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6900,0,NULL,'vbb','southeast babar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6901,0,NULL,'vbk','southwestern bontok','1268265600',NULL,NULL,NULL,NULL,'bnc',NULL,NULL); +INSERT INTO "iana_records" VALUES(6902,0,NULL,'vec','venetian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6903,0,NULL,'ved','veddah','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6904,0,NULL,'vel','veluws','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6905,0,NULL,'vem','vemgo-mabas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6906,0,NULL,'veo','ventureño','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6907,0,NULL,'vep','veps','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6908,0,NULL,'ver','mom jango','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6909,0,NULL,'vgr','vaghri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6910,0,NULL,'vgt','flemish sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6910,0,NULL,'vgt','vlaamse gebarentaal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6911,0,NULL,'vic','virgin islands creole english','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6912,0,NULL,'vid','vidunda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6913,0,NULL,'vif','vili','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6914,0,NULL,'vig','viemo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6915,0,NULL,'vil','vilela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6916,0,NULL,'vin','vinza','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6917,0,NULL,'vis','vishavan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6918,0,NULL,'vit','viti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6919,0,NULL,'viv','iduna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6920,0,NULL,'vka','kariyarra','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6921,0,NULL,'vki','ija-zuba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6922,0,NULL,'vkj','kujarge','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6923,0,NULL,'vkk','kaur','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(6924,0,NULL,'vkl','kulisusu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6925,0,NULL,'vkm','kamakan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6926,0,NULL,'vko','kodeoha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6927,0,NULL,'vkp','korlai creole portuguese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6928,0,NULL,'vkt','tenggarong kutai malay','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(6929,0,NULL,'vku','kurrama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6930,0,NULL,'vlp','valpei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6931,0,NULL,'vls','vlaams','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6932,0,NULL,'vma','martuyhunira','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6933,0,NULL,'vmb','mbabaram','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6934,0,NULL,'vmc','juxtlahuaca mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6935,0,NULL,'vmd','mudu koraga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6936,0,NULL,'vme','east masela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6937,0,NULL,'vmf','mainfränkisch','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6938,0,NULL,'vmg','minigir','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6939,0,NULL,'vmh','maraghei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6940,0,NULL,'vmi','miwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6941,0,NULL,'vmj','ixtayutla mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6942,0,NULL,'vmk','makhuwa-shirima','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6943,0,NULL,'vml','malgana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6944,0,NULL,'vmm','mitlatongo mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6945,0,NULL,'vmp','soyaltepec mazatec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6946,0,NULL,'vmq','soyaltepec mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6947,0,NULL,'vmr','marenje','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6948,0,NULL,'vms','moksela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6949,0,NULL,'vmu','muluridyi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6950,0,NULL,'vmv','valley maidu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6951,0,NULL,'vmw','makhuwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6952,0,NULL,'vmx','tamazola mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6953,0,NULL,'vmy','ayautla mazatec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6954,0,NULL,'vmz','mazatlán mazatec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6955,0,NULL,'vnk','lovono','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6955,0,NULL,'vnk','vano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6956,0,NULL,'vnm','neve''ei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6956,0,NULL,'vnm','vinmavis','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6957,0,NULL,'vnp','vunapu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6958,0,NULL,'vor','voro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6959,0,NULL,'vot','votic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6960,0,NULL,'vra','vera''a','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6961,0,NULL,'vro','võro','1248825600',NULL,NULL,NULL,NULL,'et',NULL,NULL); +INSERT INTO "iana_records" VALUES(6962,0,NULL,'vrs','varisi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6963,0,NULL,'vrt','banam bay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6963,0,NULL,'vrt','burmbar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6964,0,NULL,'vsi','moldova sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6965,0,NULL,'vsl','venezuelan sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6966,0,NULL,'vsv','llengua de signes valenciana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6966,0,NULL,'vsv','valencian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6967,0,NULL,'vto','vitou','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6968,0,NULL,'vum','vumbu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6969,0,NULL,'vun','vunjo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6970,0,NULL,'vut','vute','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6971,0,NULL,'vwa','awa (china)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6972,0,NULL,'waa','walla walla','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6973,0,NULL,'wab','wab','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6974,0,NULL,'wac','wasco-wishram','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6975,0,NULL,'wad','wandamen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6976,0,NULL,'wae','walser','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6977,0,NULL,'waf','wakoná','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6978,0,NULL,'wag','wa''ema','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6979,0,NULL,'wah','watubela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6980,0,NULL,'wai','wares','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6981,0,NULL,'waj','waffa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6982,0,NULL,'wak','wakashan languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(6983,0,NULL,'wal','wolaitta','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6983,0,NULL,'wal','wolaytta','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6984,0,NULL,'wam','wampanoag','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6985,0,NULL,'wan','wan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6986,0,NULL,'wao','wappo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6987,0,NULL,'wap','wapishana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6988,0,NULL,'waq','wageman','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6989,0,NULL,'war','waray (philippines)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6990,0,NULL,'was','washo','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6991,0,NULL,'wat','kaninuwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6992,0,NULL,'wau','waurá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6993,0,NULL,'wav','waka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6994,0,NULL,'waw','waiwai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6995,0,NULL,'wax','watam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6996,0,NULL,'way','wayana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6997,0,NULL,'waz','wampur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6998,0,NULL,'wba','warao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6999,0,NULL,'wbb','wabo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7000,0,NULL,'wbe','waritai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7001,0,NULL,'wbf','wara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7002,0,NULL,'wbh','wanda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7003,0,NULL,'wbi','vwanji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7004,0,NULL,'wbj','alagwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7005,0,NULL,'wbk','waigali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7006,0,NULL,'wbl','wakhi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7007,0,NULL,'wbm','wa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7008,0,NULL,'wbp','warlpiri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7009,0,NULL,'wbq','waddar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7010,0,NULL,'wbr','wagdi','1248825600',NULL,NULL,NULL,NULL,'raj',NULL,NULL); +INSERT INTO "iana_records" VALUES(7011,0,NULL,'wbt','wanman','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7012,0,NULL,'wbv','wajarri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7013,0,NULL,'wbw','woi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7014,0,NULL,'wca','yanomámi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7015,0,NULL,'wci','waci gbe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7016,0,NULL,'wdd','wandji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7017,0,NULL,'wdg','wadaginam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7018,0,NULL,'wdj','wadjiginy','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7019,0,NULL,'wdu','wadjigu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7020,0,NULL,'wea','wewaw','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7021,0,NULL,'wec','wè western','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7022,0,NULL,'wed','wedau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7023,0,NULL,'weh','weh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7024,0,NULL,'wei','were','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7025,0,NULL,'wem','weme gbe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7026,0,NULL,'wen','sorbian languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(7027,0,NULL,'weo','north wemale','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7028,0,NULL,'wep','westphalien','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7029,0,NULL,'wer','weri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7030,0,NULL,'wes','cameroon pidgin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7031,0,NULL,'wet','perai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7032,0,NULL,'weu','welaung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7033,0,NULL,'wew','wejewa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7034,0,NULL,'wfg','yafi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7034,0,NULL,'wfg','zorop','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7035,0,NULL,'wga','wagaya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7036,0,NULL,'wgb','wagawaga','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7037,0,NULL,'wgg','wangganguru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7038,0,NULL,'wgi','wahgi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7039,0,NULL,'wgo','waigeo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7040,0,NULL,'wgw','wagawaga','1248825600',1268265600,NULL,NULL,NULL,NULL,NULL,'see wgb, ylb'); +INSERT INTO "iana_records" VALUES(7041,0,NULL,'wgy','warrgamay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7042,0,NULL,'wha','manusela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7043,0,NULL,'whg','north wahgi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7044,0,NULL,'whk','wahau kenyah','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7045,0,NULL,'whu','wahau kayan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7046,0,NULL,'wib','southern toussian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7047,0,NULL,'wic','wichita','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7048,0,NULL,'wie','wik-epa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7049,0,NULL,'wif','wik-keyangan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7050,0,NULL,'wig','wik-ngathana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7051,0,NULL,'wih','wik-me''anha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7052,0,NULL,'wii','minidien','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7053,0,NULL,'wij','wik-iiyanh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7054,0,NULL,'wik','wikalkan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7055,0,NULL,'wil','wilawila','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7056,0,NULL,'wim','wik-mungkan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7057,0,NULL,'win','ho-chunk','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7058,0,NULL,'wir','wiraféd','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7059,0,NULL,'wit','wintu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7060,0,NULL,'wiu','wiru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7061,0,NULL,'wiv','muduapa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7062,0,NULL,'wiw','wirangu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7063,0,NULL,'wiy','wiyot','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7064,0,NULL,'wja','waja','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7065,0,NULL,'wji','warji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7066,0,NULL,'wka','kw''adza','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7067,0,NULL,'wkb','kumbaran','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7068,0,NULL,'wkd','mo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7068,0,NULL,'wkd','wakde','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7069,0,NULL,'wkl','kalanadi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7070,0,NULL,'wku','kunduvadi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7071,0,NULL,'wkw','wakawaka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7072,0,NULL,'wla','walio','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7073,0,NULL,'wlc','mwali comorian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7074,0,NULL,'wle','wolane','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7075,0,NULL,'wlg','kunbarlang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7076,0,NULL,'wli','waioli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7077,0,NULL,'wlk','wailaki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7078,0,NULL,'wll','wali (sudan)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7079,0,NULL,'wlm','middle welsh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7080,0,NULL,'wlo','wolio','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7081,0,NULL,'wlr','wailapa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7082,0,NULL,'wls','wallisian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7083,0,NULL,'wlu','wuliwuli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7084,0,NULL,'wlv','wichí lhamtés vejoz','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7085,0,NULL,'wlw','walak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7086,0,NULL,'wlx','wali (ghana)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7087,0,NULL,'wly','waling','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7088,0,NULL,'wma','mawa (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7089,0,NULL,'wmb','wambaya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7090,0,NULL,'wmc','wamas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7091,0,NULL,'wmd','mamaindé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7092,0,NULL,'wme','wambule','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7093,0,NULL,'wmh','waima''a','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7094,0,NULL,'wmi','wamin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7095,0,NULL,'wmm','maiwa (indonesia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7096,0,NULL,'wmn','waamwang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7097,0,NULL,'wmo','wom (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7098,0,NULL,'wms','wambon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7099,0,NULL,'wmt','walmajarri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7100,0,NULL,'wmw','mwani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7101,0,NULL,'wmx','womo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7102,0,NULL,'wnb','wanambre','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7103,0,NULL,'wnc','wantoat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7104,0,NULL,'wnd','wandarang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7105,0,NULL,'wne','waneci','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7106,0,NULL,'wng','wanggom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7107,0,NULL,'wni','ndzwani comorian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7108,0,NULL,'wnk','wanukaka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7109,0,NULL,'wnm','wanggamala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7110,0,NULL,'wno','wano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7111,0,NULL,'wnp','wanap','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7112,0,NULL,'wnu','usan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7113,0,NULL,'woa','tyaraity','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7114,0,NULL,'wob','wè northern','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7115,0,NULL,'woc','wogeo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7116,0,NULL,'wod','wolani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7117,0,NULL,'woe','woleaian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7118,0,NULL,'wof','gambian wolof','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7119,0,NULL,'wog','wogamusin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7120,0,NULL,'woi','kamang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7121,0,NULL,'wok','longto','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7122,0,NULL,'wom','wom (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7123,0,NULL,'won','wongo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7124,0,NULL,'woo','manombai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7125,0,NULL,'wor','woria','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7126,0,NULL,'wos','hanga hundi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7127,0,NULL,'wow','wawonii','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7128,0,NULL,'woy','weyto','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7129,0,NULL,'wpc','maco','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7130,0,NULL,'wra','warapu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7131,0,NULL,'wrb','warluwara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7132,0,NULL,'wrd','warduji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7133,0,NULL,'wrg','warungu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7134,0,NULL,'wrh','wiradhuri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7135,0,NULL,'wri','wariyangga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7136,0,NULL,'wrl','warlmanpa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7137,0,NULL,'wrm','warumungu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7138,0,NULL,'wrn','warnang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7139,0,NULL,'wrp','waropen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7140,0,NULL,'wrr','wardaman','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7141,0,NULL,'wrs','waris','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7142,0,NULL,'wru','waru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7143,0,NULL,'wrv','waruna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7144,0,NULL,'wrw','gugu warra','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7145,0,NULL,'wrx','wae rana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7146,0,NULL,'wry','merwari','1248825600',NULL,NULL,NULL,NULL,'mwr',NULL,NULL); +INSERT INTO "iana_records" VALUES(7147,0,NULL,'wrz','waray (australia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7148,0,NULL,'wsa','warembori','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7149,0,NULL,'wsi','wusi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7150,0,NULL,'wsk','waskia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7151,0,NULL,'wsr','owenia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7152,0,NULL,'wss','wasa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7153,0,NULL,'wsu','wasu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7154,0,NULL,'wsv','wotapuri-katarqalai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7155,0,NULL,'wtf','dumpu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7156,0,NULL,'wti','berta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7157,0,NULL,'wtk','watakataui','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7158,0,NULL,'wtm','mewati','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7159,0,NULL,'wtw','wotu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7160,0,NULL,'wua','wikngenchera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7161,0,NULL,'wub','wunambal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7162,0,NULL,'wud','wudu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7163,0,NULL,'wuh','wutunhua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7164,0,NULL,'wul','silimo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7165,0,NULL,'wum','wumbvu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7166,0,NULL,'wun','bungu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7167,0,NULL,'wur','wurrugu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7168,0,NULL,'wut','wutung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7169,0,NULL,'wuu','wu chinese','1248825600',NULL,NULL,NULL,NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(7170,0,NULL,'wuv','wuvulu-aua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7171,0,NULL,'wux','wulna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7172,0,NULL,'wuy','wauyai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7173,0,NULL,'wwa','waama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7174,0,NULL,'wwo','dorig','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7174,0,NULL,'wwo','wetamut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7175,0,NULL,'wwr','warrwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7176,0,NULL,'www','wawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7177,0,NULL,'wxa','waxianghua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7178,0,NULL,'wya','wyandot','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7179,0,NULL,'wyb','wangaaybuwan-ngiyambaa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7180,0,NULL,'wym','wymysorys','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7181,0,NULL,'wyr','wayoró','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7182,0,NULL,'wyy','western fijian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7183,0,NULL,'xaa','andalusian arabic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7184,0,NULL,'xab','sambe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7185,0,NULL,'xac','kachari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7186,0,NULL,'xad','adai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7187,0,NULL,'xae','aequian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7188,0,NULL,'xag','aghwan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7189,0,NULL,'xai','kaimbé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7190,0,NULL,'xal','kalmyk','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7190,0,NULL,'xal','oirat','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7191,0,NULL,'xam','/xam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7192,0,NULL,'xan','xamtanga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7193,0,NULL,'xao','khao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7194,0,NULL,'xap','apalachee','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7195,0,NULL,'xaq','aquitanian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7196,0,NULL,'xar','karami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7197,0,NULL,'xas','kamas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7198,0,NULL,'xat','katawixi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7199,0,NULL,'xau','kauwera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7200,0,NULL,'xav','xavánte','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7201,0,NULL,'xaw','kawaiisu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7202,0,NULL,'xay','kayan mahakam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7203,0,NULL,'xba','kamba (brazil)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7204,0,NULL,'xbb','lower burdekin','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7205,0,NULL,'xbc','bactrian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7206,0,NULL,'xbi','kombio','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7207,0,NULL,'xbm','middle breton','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7208,0,NULL,'xbn','kenaboi','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7209,0,NULL,'xbo','bolgarian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7210,0,NULL,'xbr','kambera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7211,0,NULL,'xbw','kambiwá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7212,0,NULL,'xbx','kabixí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7213,0,NULL,'xcb','cumbric','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7214,0,NULL,'xcc','camunic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7215,0,NULL,'xce','celtiberian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7216,0,NULL,'xcg','cisalpine gaulish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7217,0,NULL,'xch','chemakum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7217,0,NULL,'xch','chimakum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7218,0,NULL,'xcl','classical armenian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7219,0,NULL,'xcm','comecrudo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7220,0,NULL,'xcn','cotoname','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7221,0,NULL,'xco','chorasmian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7222,0,NULL,'xcr','carian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7223,0,NULL,'xct','classical tibetan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7224,0,NULL,'xcu','curonian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7225,0,NULL,'xcv','chuvantsy','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7226,0,NULL,'xcw','coahuilteco','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7227,0,NULL,'xcy','cayuse','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7228,0,NULL,'xdc','dacian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7229,0,NULL,'xdm','edomite','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7230,0,NULL,'xdy','malayic dayak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7231,0,NULL,'xeb','eblan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7232,0,NULL,'xed','hdi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7233,0,NULL,'xeg','//xegwi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7234,0,NULL,'xel','kelo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7235,0,NULL,'xem','kembayan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7236,0,NULL,'xep','epi-olmec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7237,0,NULL,'xer','xerénte','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7238,0,NULL,'xes','kesawai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7239,0,NULL,'xet','xetá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7240,0,NULL,'xeu','keoru-ahia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7241,0,NULL,'xfa','faliscan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7242,0,NULL,'xga','galatian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7243,0,NULL,'xgf','gabrielino-fernandeño','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7244,0,NULL,'xgl','galindan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7245,0,NULL,'xgn','mongolian languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(7246,0,NULL,'xgr','garza','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7247,0,NULL,'xha','harami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7248,0,NULL,'xhc','hunnic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7249,0,NULL,'xhd','hadrami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7250,0,NULL,'xhe','khetrani','1248825600',NULL,NULL,NULL,NULL,'lah',NULL,NULL); +INSERT INTO "iana_records" VALUES(7251,0,NULL,'xhr','hernican','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7252,0,NULL,'xht','hattic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7253,0,NULL,'xhu','hurrian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7254,0,NULL,'xhv','khua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7255,0,NULL,'xia','xiandao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7256,0,NULL,'xib','iberian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7257,0,NULL,'xii','xiri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7258,0,NULL,'xil','illyrian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7259,0,NULL,'xin','xinca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7260,0,NULL,'xip','xipináwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7261,0,NULL,'xir','xiriâna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7262,0,NULL,'xiv','indus valley language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7263,0,NULL,'xiy','xipaya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7264,0,NULL,'xka','kalkoti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7265,0,NULL,'xkb','northern nago','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7266,0,NULL,'xkc','kho''ini','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7267,0,NULL,'xkd','mendalam kayan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7268,0,NULL,'xke','kereho','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7269,0,NULL,'xkf','khengkha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7270,0,NULL,'xkg','kagoro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7271,0,NULL,'xkh','karahawyana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7272,0,NULL,'xki','kenyan sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7273,0,NULL,'xkj','kajali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7274,0,NULL,'xkk','kaco''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7275,0,NULL,'xkl','mainstream kenyah','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7276,0,NULL,'xkn','kayan river kayan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7277,0,NULL,'xko','kiorr','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7278,0,NULL,'xkp','kabatei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7279,0,NULL,'xkq','koroni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7280,0,NULL,'xkr','xakriabá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7281,0,NULL,'xks','kumbewaha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7282,0,NULL,'xkt','kantosi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7283,0,NULL,'xku','kaamba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7284,0,NULL,'xkv','kgalagadi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7285,0,NULL,'xkw','kembra','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7286,0,NULL,'xkx','karore','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7287,0,NULL,'xky','uma'' lasan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7288,0,NULL,'xkz','kurtokha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7289,0,NULL,'xla','kamula','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7290,0,NULL,'xlb','loup b','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7291,0,NULL,'xlc','lycian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7292,0,NULL,'xld','lydian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7293,0,NULL,'xle','lemnian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7294,0,NULL,'xlg','ligurian (ancient)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7295,0,NULL,'xli','liburnian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7296,0,NULL,'xln','alanic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7297,0,NULL,'xlo','loup a','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7298,0,NULL,'xlp','lepontic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7299,0,NULL,'xls','lusitanian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7300,0,NULL,'xlu','cuneiform luwian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7301,0,NULL,'xly','elymian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7302,0,NULL,'xma','mushungulu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7303,0,NULL,'xmb','mbonga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7304,0,NULL,'xmc','makhuwa-marrevone','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7305,0,NULL,'xmd','mbedam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7306,0,NULL,'xme','median','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7307,0,NULL,'xmf','mingrelian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7308,0,NULL,'xmg','mengaka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7309,0,NULL,'xmh','kuku-muminh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7310,0,NULL,'xmj','majera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7311,0,NULL,'xmk','ancient macedonian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7312,0,NULL,'xml','malaysian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7313,0,NULL,'xmm','manado malay','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7314,0,NULL,'xmn','manichaean middle persian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7315,0,NULL,'xmo','morerebi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7316,0,NULL,'xmp','kuku-mu''inh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7317,0,NULL,'xmq','kuku-mangk','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7318,0,NULL,'xmr','meroitic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7319,0,NULL,'xms','moroccan sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7320,0,NULL,'xmt','matbat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7321,0,NULL,'xmu','kamu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7322,0,NULL,'xmv','antankarana malagasy','1248825600',NULL,NULL,NULL,NULL,'mg',NULL,NULL); +INSERT INTO "iana_records" VALUES(7323,0,NULL,'xmw','tsimihety malagasy','1248825600',NULL,NULL,NULL,NULL,'mg',NULL,NULL); +INSERT INTO "iana_records" VALUES(7324,0,NULL,'xmx','maden','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7325,0,NULL,'xmy','mayaguduna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7326,0,NULL,'xmz','mori bawah','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7327,0,NULL,'xna','ancient north arabian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7328,0,NULL,'xnb','kanakanabu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7329,0,NULL,'xnd','na-dene languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(7330,0,NULL,'xng','middle mongolian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7331,0,NULL,'xnh','kuanhua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7332,0,NULL,'xnn','northern kankanay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7333,0,NULL,'xno','anglo-norman','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7334,0,NULL,'xnr','kangri','1248825600',NULL,NULL,NULL,NULL,'doi',NULL,NULL); +INSERT INTO "iana_records" VALUES(7335,0,NULL,'xns','kanashi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7336,0,NULL,'xnt','narragansett','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7337,0,NULL,'xoc','o''chi''chi''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7338,0,NULL,'xod','kokoda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7339,0,NULL,'xog','soga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7340,0,NULL,'xoi','kominimung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7341,0,NULL,'xok','xokleng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7342,0,NULL,'xom','komo (sudan)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7343,0,NULL,'xon','konkomba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7344,0,NULL,'xoo','xukurú','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7345,0,NULL,'xop','kopar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7346,0,NULL,'xor','korubo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7347,0,NULL,'xow','kowaki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7348,0,NULL,'xpc','pecheneg','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7349,0,NULL,'xpe','liberia kpelle','1248825600',NULL,NULL,NULL,NULL,'kpe',NULL,NULL); +INSERT INTO "iana_records" VALUES(7350,0,NULL,'xpg','phrygian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7351,0,NULL,'xpi','pictish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7352,0,NULL,'xpk','kulina pano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7353,0,NULL,'xpm','pumpokol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7354,0,NULL,'xpn','kapinawá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7355,0,NULL,'xpo','pochutec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7356,0,NULL,'xpp','puyo-paekche','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7357,0,NULL,'xpq','mohegan-pequot','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7358,0,NULL,'xpr','parthian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7359,0,NULL,'xps','pisidian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7360,0,NULL,'xpu','punic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7361,0,NULL,'xpy','puyo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7362,0,NULL,'xqa','karakhanid','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7363,0,NULL,'xqt','qatabanian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7364,0,NULL,'xra','krahô','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7365,0,NULL,'xrb','eastern karaboro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7366,0,NULL,'xre','kreye','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7367,0,NULL,'xri','krikati-timbira','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7368,0,NULL,'xrm','armazic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7369,0,NULL,'xrn','arin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7370,0,NULL,'xrr','raetic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7371,0,NULL,'xrt','aranama-tamique','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7372,0,NULL,'xru','marriammu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7373,0,NULL,'xrw','karawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7374,0,NULL,'xsa','sabaean','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7375,0,NULL,'xsb','tinà sambal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7376,0,NULL,'xsc','scythian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7377,0,NULL,'xsd','sidetic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7378,0,NULL,'xse','sempan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7379,0,NULL,'xsh','shamang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7380,0,NULL,'xsi','sio','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7381,0,NULL,'xsj','subi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7382,0,NULL,'xsl','south slavey','1248825600',NULL,NULL,NULL,NULL,'den',NULL,NULL); +INSERT INTO "iana_records" VALUES(7383,0,NULL,'xsm','kasem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7384,0,NULL,'xsn','sanga (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7385,0,NULL,'xso','solano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7386,0,NULL,'xsp','silopi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7387,0,NULL,'xsq','makhuwa-saka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7388,0,NULL,'xsr','sherpa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7389,0,NULL,'xss','assan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7390,0,NULL,'xsu','sanumá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7391,0,NULL,'xsv','sudovian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7392,0,NULL,'xsy','saisiyat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7393,0,NULL,'xta','alcozauca mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7394,0,NULL,'xtb','chazumba mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7395,0,NULL,'xtc','katcha-kadugli-miri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7396,0,NULL,'xtd','diuxi-tilantongo mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7397,0,NULL,'xte','ketengban','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7398,0,NULL,'xtg','transalpine gaulish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7399,0,NULL,'xti','sinicahua mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7400,0,NULL,'xtj','san juan teita mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7401,0,NULL,'xtl','tijaltepec mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7402,0,NULL,'xtm','magdalena peñasco mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7403,0,NULL,'xtn','northern tlaxiaco mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7404,0,NULL,'xto','tokharian a','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7405,0,NULL,'xtp','san miguel piedras mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7406,0,NULL,'xtq','tumshuqese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7407,0,NULL,'xtr','early tripuri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7408,0,NULL,'xts','sindihui mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7409,0,NULL,'xtt','tacahua mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7410,0,NULL,'xtu','cuyamecalco mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7411,0,NULL,'xtw','tawandê','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7412,0,NULL,'xty','yoloxochitl mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7413,0,NULL,'xtz','tasmanian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7414,0,NULL,'xua','alu kurumba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7415,0,NULL,'xub','betta kurumba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7416,0,NULL,'xug','kunigami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7417,0,NULL,'xuj','jennu kurumba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7418,0,NULL,'xum','umbrian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7419,0,NULL,'xuo','kuo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7420,0,NULL,'xup','upper umpqua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7421,0,NULL,'xur','urartian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7422,0,NULL,'xut','kuthant','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7423,0,NULL,'xuu','kxoe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7424,0,NULL,'xve','venetic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7425,0,NULL,'xvi','kamviri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7426,0,NULL,'xvn','vandalic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7427,0,NULL,'xvo','volscian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7428,0,NULL,'xvs','vestinian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7429,0,NULL,'xwa','kwaza','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7430,0,NULL,'xwc','woccon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7431,0,NULL,'xwe','xwela gbe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7432,0,NULL,'xwg','kwegu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7433,0,NULL,'xwl','western xwla gbe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7434,0,NULL,'xwo','written oirat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7435,0,NULL,'xwr','kwerba mamberamo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7436,0,NULL,'xxb','boro (ghana)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7437,0,NULL,'xxk','ke''o','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7438,0,NULL,'xxr','koropó','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7439,0,NULL,'xxt','tambora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7440,0,NULL,'xyl','yalakalore','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7441,0,NULL,'xzh','zhang-zhung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7442,0,NULL,'xzm','zemgalian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7443,0,NULL,'xzp','ancient zapotec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7444,0,NULL,'yaa','yaminahua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7445,0,NULL,'yab','yuhup','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7446,0,NULL,'yac','pass valley yali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7447,0,NULL,'yad','yagua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7448,0,NULL,'yae','pumé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7449,0,NULL,'yaf','yaka (democratic republic of congo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7450,0,NULL,'yag','yámana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7451,0,NULL,'yah','yazgulyam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7452,0,NULL,'yai','yagnobi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7453,0,NULL,'yaj','banda-yangere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7454,0,NULL,'yak','yakama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7455,0,NULL,'yal','yalunka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7456,0,NULL,'yam','yamba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7457,0,NULL,'yan','mayangna','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7458,0,NULL,'yao','yao','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7459,0,NULL,'yap','yapese','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7460,0,NULL,'yaq','yaqui','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7461,0,NULL,'yar','yabarana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7462,0,NULL,'yas','nugunu (cameroon)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7463,0,NULL,'yat','yambeta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7464,0,NULL,'yau','yuwana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7465,0,NULL,'yav','yangben','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7466,0,NULL,'yaw','yawalapití','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7467,0,NULL,'yax','yauma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7468,0,NULL,'yay','agwagwune','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7469,0,NULL,'yaz','lokaa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7470,0,NULL,'yba','yala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7471,0,NULL,'ybb','yemba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7472,0,NULL,'ybd','yangbye','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7473,0,NULL,'ybe','west yugur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7474,0,NULL,'ybh','yakha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7475,0,NULL,'ybi','yamphu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7476,0,NULL,'ybj','hasha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7477,0,NULL,'ybk','bokha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7478,0,NULL,'ybl','yukuben','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7479,0,NULL,'ybm','yaben','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7480,0,NULL,'ybn','yabaâna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7481,0,NULL,'ybo','yabong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7482,0,NULL,'ybx','yawiyo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7483,0,NULL,'yby','yaweyuha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7484,0,NULL,'ych','chesu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7485,0,NULL,'ycl','lolopo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7486,0,NULL,'ycn','yucuna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7487,0,NULL,'ycp','chepya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7488,0,NULL,'ydd','eastern yiddish','1248825600',NULL,NULL,NULL,NULL,'yi',NULL,NULL); +INSERT INTO "iana_records" VALUES(7489,0,NULL,'yde','yangum dey','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7490,0,NULL,'ydg','yidgha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7491,0,NULL,'ydk','yoidik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7492,0,NULL,'yds','yiddish sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7493,0,NULL,'yea','ravula','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7494,0,NULL,'yec','yeniche','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7495,0,NULL,'yee','yimas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7496,0,NULL,'yei','yeni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7497,0,NULL,'yej','yevanic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7498,0,NULL,'yel','yela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7499,0,NULL,'yen','yendang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7500,0,NULL,'yer','tarok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7501,0,NULL,'yes','yeskwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7502,0,NULL,'yet','yetfa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7503,0,NULL,'yeu','yerukula','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7504,0,NULL,'yev','yapunda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7505,0,NULL,'yey','yeyi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7506,0,NULL,'ygl','yangum gel','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7507,0,NULL,'ygm','yagomi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7508,0,NULL,'ygp','gepo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7509,0,NULL,'ygr','yagaria','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7510,0,NULL,'ygw','yagwoia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7511,0,NULL,'yha','baha buyang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7512,0,NULL,'yhd','judeo-iraqi arabic','1248825600',NULL,NULL,NULL,NULL,'jrb',NULL,NULL); +INSERT INTO "iana_records" VALUES(7513,0,NULL,'yhl','hlepho phowa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7514,0,NULL,'yia','yinggarda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7515,0,NULL,'yif','ache','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7516,0,NULL,'yig','wusa nasu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7517,0,NULL,'yih','western yiddish','1248825600',NULL,NULL,NULL,NULL,'yi',NULL,NULL); +INSERT INTO "iana_records" VALUES(7518,0,NULL,'yii','yidiny','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7519,0,NULL,'yij','yindjibarndi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7520,0,NULL,'yik','dongshanba lalo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7521,0,NULL,'yil','yindjilandji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7522,0,NULL,'yim','yimchungru naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7523,0,NULL,'yin','yinchia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7524,0,NULL,'yip','pholo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7525,0,NULL,'yiq','miqie','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7526,0,NULL,'yir','north awyu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7527,0,NULL,'yis','yis','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7528,0,NULL,'yit','eastern lalu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7529,0,NULL,'yiu','awu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7530,0,NULL,'yiv','northern nisu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7531,0,NULL,'yix','axi yi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7532,0,NULL,'yiy','yir yoront','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7533,0,NULL,'yiz','azhe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7534,0,NULL,'yka','yakan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7535,0,NULL,'ykg','northern yukaghir','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7536,0,NULL,'yki','yoke','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7537,0,NULL,'ykk','yakaikeke','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7538,0,NULL,'ykl','khlula','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7539,0,NULL,'ykm','kap','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7540,0,NULL,'yko','yasa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7541,0,NULL,'ykr','yekora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7542,0,NULL,'ykt','kathu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7543,0,NULL,'yky','yakoma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7544,0,NULL,'yla','yaul','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7545,0,NULL,'ylb','yaleba','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7546,0,NULL,'yle','yele','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7547,0,NULL,'ylg','yelogu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7548,0,NULL,'yli','angguruk yali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7549,0,NULL,'yll','yil','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7550,0,NULL,'ylm','limi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7551,0,NULL,'yln','langnian buyang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7552,0,NULL,'ylo','naluo yi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7553,0,NULL,'ylr','yalarnnga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7554,0,NULL,'ylu','aribwaung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7555,0,NULL,'yly','nyâlayu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7556,0,NULL,'yma','yamphe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7557,0,NULL,'ymb','yambes','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7558,0,NULL,'ymc','southern muji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7559,0,NULL,'ymd','muda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7560,0,NULL,'yme','yameo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7561,0,NULL,'ymg','yamongeri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7562,0,NULL,'ymh','mili','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7563,0,NULL,'ymi','moji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7564,0,NULL,'ymk','makwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7565,0,NULL,'yml','iamalele','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7566,0,NULL,'ymm','maay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7567,0,NULL,'ymn','sunum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7567,0,NULL,'ymn','yamna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7568,0,NULL,'ymo','yangum mon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7569,0,NULL,'ymp','yamap','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7570,0,NULL,'ymq','qila muji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7571,0,NULL,'ymr','malasar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7572,0,NULL,'yms','mysian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7573,0,NULL,'ymt','mator-taygi-karagas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7574,0,NULL,'ymx','northern muji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7575,0,NULL,'ymz','muzi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7576,0,NULL,'yna','aluo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7577,0,NULL,'ynd','yandruwandha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7578,0,NULL,'yne','lang''e','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7579,0,NULL,'yng','yango','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7580,0,NULL,'ynh','yangho','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7581,0,NULL,'ynk','naukan yupik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7582,0,NULL,'ynl','yangulam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7583,0,NULL,'ynn','yana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7584,0,NULL,'yno','yong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7585,0,NULL,'yns','yansi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7586,0,NULL,'ynu','yahuna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7587,0,NULL,'yob','yoba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7588,0,NULL,'yog','yogad','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7589,0,NULL,'yoi','yonaguni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7590,0,NULL,'yok','yokuts','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7591,0,NULL,'yol','yola','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7592,0,NULL,'yom','yombe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7593,0,NULL,'yon','yonggom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7594,0,NULL,'yos','yos','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7595,0,NULL,'yox','yoron','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7596,0,NULL,'yoy','yoy','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7597,0,NULL,'ypa','phala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7598,0,NULL,'ypb','labo phowa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7599,0,NULL,'ypg','phola','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7600,0,NULL,'yph','phupha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7601,0,NULL,'ypk','yupik languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(7602,0,NULL,'ypm','phuma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7603,0,NULL,'ypn','ani phowa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7604,0,NULL,'ypo','alo phola','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7605,0,NULL,'ypp','phupa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7606,0,NULL,'ypz','phuza','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7607,0,NULL,'yra','yerakai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7608,0,NULL,'yrb','yareba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7609,0,NULL,'yre','yaouré','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7610,0,NULL,'yri','yarí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7611,0,NULL,'yrk','nenets','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7612,0,NULL,'yrl','nhengatu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7613,0,NULL,'yrn','yerong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7614,0,NULL,'yrs','yarsun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7615,0,NULL,'yrw','yarawata','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7616,0,NULL,'ysc','yassic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7617,0,NULL,'ysd','samatao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7618,0,NULL,'ysl','yugoslavian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7619,0,NULL,'ysn','sani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7620,0,NULL,'yso','nisi (china)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7621,0,NULL,'ysp','southern lolopo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7622,0,NULL,'ysr','sirenik yupik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7623,0,NULL,'yss','yessan-mayo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7624,0,NULL,'ysy','sanie','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7625,0,NULL,'yta','talu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7626,0,NULL,'ytl','tanglang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7627,0,NULL,'ytp','thopho','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7628,0,NULL,'ytw','yout wam','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7629,0,NULL,'yua','yucatec maya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7629,0,NULL,'yua','yucateco','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7630,0,NULL,'yub','yugambal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7631,0,NULL,'yuc','yuchi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7632,0,NULL,'yud','judeo-tripolitanian arabic','1248825600',NULL,NULL,NULL,NULL,'jrb',NULL,NULL); +INSERT INTO "iana_records" VALUES(7633,0,NULL,'yue','yue chinese','1248825600',NULL,NULL,NULL,NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(7634,0,NULL,'yuf','havasupai-walapai-yavapai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7635,0,NULL,'yug','yug','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7636,0,NULL,'yui','yurutí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7637,0,NULL,'yuj','karkar-yuri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7638,0,NULL,'yuk','yuki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7639,0,NULL,'yul','yulu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7640,0,NULL,'yum','quechan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7641,0,NULL,'yun','bena (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7642,0,NULL,'yup','yukpa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7643,0,NULL,'yuq','yuqui','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7644,0,NULL,'yur','yurok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7645,0,NULL,'yut','yopno','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7646,0,NULL,'yuu','yugh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7647,0,NULL,'yuw','yau (morobe province)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7648,0,NULL,'yux','southern yukaghir','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7649,0,NULL,'yuy','east yugur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7650,0,NULL,'yuz','yuracare','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7651,0,NULL,'yva','yawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7652,0,NULL,'yvt','yavitero','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7653,0,NULL,'ywa','kalou','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7654,0,NULL,'ywl','western lalu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7655,0,NULL,'ywn','yawanawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7656,0,NULL,'ywq','wuding-luquan yi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7657,0,NULL,'ywr','yawuru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7658,0,NULL,'ywt','xishanba lalo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7659,0,NULL,'ywu','wumeng nasu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7660,0,NULL,'yww','yawarawarga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7661,0,NULL,'yyu','yau (sandaun province)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7662,0,NULL,'yyz','ayizi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7663,0,NULL,'yzg','e''ma buyang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7664,0,NULL,'yzk','zokhuo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7665,0,NULL,'zaa','sierra de juárez zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7666,0,NULL,'zab','san juan guelavía zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7667,0,NULL,'zac','ocotlán zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7668,0,NULL,'zad','cajonos zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7669,0,NULL,'zae','yareni zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7670,0,NULL,'zaf','ayoquesco zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7671,0,NULL,'zag','zaghawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7672,0,NULL,'zah','zangwal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7673,0,NULL,'zai','isthmus zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7674,0,NULL,'zaj','zaramo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7675,0,NULL,'zak','zanaki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7676,0,NULL,'zal','zauzou','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7677,0,NULL,'zam','miahuatlán zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7678,0,NULL,'zao','ozolotepec zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7679,0,NULL,'zap','zapotec','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(7680,0,NULL,'zaq','aloápam zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7681,0,NULL,'zar','rincón zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7682,0,NULL,'zas','santo domingo albarradas zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7683,0,NULL,'zat','tabaa zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7684,0,NULL,'zau','zangskari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7685,0,NULL,'zav','yatzachi zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7686,0,NULL,'zaw','mitla zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7687,0,NULL,'zax','xadani zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7688,0,NULL,'zay','zayse-zergulla','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7688,0,NULL,'zay','zaysete','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7689,0,NULL,'zaz','zari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7690,0,NULL,'zbc','central berawan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7691,0,NULL,'zbe','east berawan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7692,0,NULL,'zbl','bliss','1187654400',NULL,NULL,NULL,'blis',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7692,0,NULL,'zbl','blissymbolics','1187654400',NULL,NULL,NULL,'blis',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7692,0,NULL,'zbl','blissymbols','1187654400',NULL,NULL,NULL,'blis',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7693,0,NULL,'zbt','batui','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7694,0,NULL,'zbw','west berawan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7695,0,NULL,'zca','coatecas altas zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7696,0,NULL,'zch','central hongshuihe zhuang','1248825600',NULL,NULL,NULL,NULL,'za',NULL,NULL); +INSERT INTO "iana_records" VALUES(7697,0,NULL,'zdj','ngazidja comorian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7698,0,NULL,'zea','zeeuws','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7699,0,NULL,'zeg','zenag','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7700,0,NULL,'zeh','eastern hongshuihe zhuang','1248825600',NULL,NULL,NULL,NULL,'za',NULL,NULL); +INSERT INTO "iana_records" VALUES(7701,0,NULL,'zen','zenaga','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7702,0,NULL,'zga','kinga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7703,0,NULL,'zgb','guibei zhuang','1248825600',NULL,NULL,NULL,NULL,'za',NULL,NULL); +INSERT INTO "iana_records" VALUES(7704,0,NULL,'zgm','minz zhuang','1248825600',NULL,NULL,NULL,NULL,'za',NULL,NULL); +INSERT INTO "iana_records" VALUES(7705,0,NULL,'zgn','guibian zhuang','1248825600',NULL,NULL,NULL,NULL,'za',NULL,NULL); +INSERT INTO "iana_records" VALUES(7706,0,NULL,'zgr','magori','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7707,0,NULL,'zhb','zhaba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7708,0,NULL,'zhd','dai zhuang','1248825600',NULL,NULL,NULL,NULL,'za',NULL,NULL); +INSERT INTO "iana_records" VALUES(7709,0,NULL,'zhi','zhire','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7710,0,NULL,'zhn','nong zhuang','1248825600',NULL,NULL,NULL,NULL,'za',NULL,NULL); +INSERT INTO "iana_records" VALUES(7711,0,NULL,'zhw','zhoa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7712,0,NULL,'zhx','chinese (family)','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(7713,0,NULL,'zia','zia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7714,0,NULL,'zib','zimbabwe sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7715,0,NULL,'zik','zimakani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7716,0,NULL,'zim','mesme','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7717,0,NULL,'zin','zinza','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7718,0,NULL,'zir','ziriya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7719,0,NULL,'ziw','zigula','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7720,0,NULL,'ziz','zizilivakan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7721,0,NULL,'zka','kaimbulawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7722,0,NULL,'zkb','koibal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7723,0,NULL,'zkg','koguryo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7724,0,NULL,'zkh','khorezmian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7725,0,NULL,'zkk','karankawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7726,0,NULL,'zko','kott','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7727,0,NULL,'zkp','são paulo kaingáng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7728,0,NULL,'zkr','zakhring','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7729,0,NULL,'zkt','kitan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7730,0,NULL,'zku','kaurna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7731,0,NULL,'zkv','krevinian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7732,0,NULL,'zkz','khazar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7733,0,NULL,'zle','east slavic languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(7734,0,NULL,'zlj','liujiang zhuang','1248825600',NULL,NULL,NULL,NULL,'za',NULL,NULL); +INSERT INTO "iana_records" VALUES(7735,0,NULL,'zlm','malay (individual language)','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7736,0,NULL,'zln','lianshan zhuang','1248825600',NULL,NULL,NULL,NULL,'za',NULL,NULL); +INSERT INTO "iana_records" VALUES(7737,0,NULL,'zlq','liuqian zhuang','1248825600',NULL,NULL,NULL,NULL,'za',NULL,NULL); +INSERT INTO "iana_records" VALUES(7738,0,NULL,'zls','south slavic languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(7739,0,NULL,'zlw','west slavic languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(7740,0,NULL,'zma','manda (australia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7741,0,NULL,'zmb','zimba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7742,0,NULL,'zmc','margany','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7743,0,NULL,'zmd','maridan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7744,0,NULL,'zme','mangerr','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7745,0,NULL,'zmf','mfinu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7746,0,NULL,'zmg','marti ke','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7747,0,NULL,'zmh','makolkol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7748,0,NULL,'zmi','negeri sembilan malay','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7749,0,NULL,'zmj','maridjabin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7750,0,NULL,'zmk','mandandanyi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7751,0,NULL,'zml','madngele','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7752,0,NULL,'zmm','marimanindji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7753,0,NULL,'zmn','mbangwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7754,0,NULL,'zmo','molo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7755,0,NULL,'zmp','mpuono','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7756,0,NULL,'zmq','mituku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7757,0,NULL,'zmr','maranunggu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7758,0,NULL,'zms','mbesa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7759,0,NULL,'zmt','maringarr','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7760,0,NULL,'zmu','muruwari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7761,0,NULL,'zmv','mbariman-gudhinma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7762,0,NULL,'zmw','mbo (democratic republic of congo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7763,0,NULL,'zmx','bomitaba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7764,0,NULL,'zmy','mariyedi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7765,0,NULL,'zmz','mbandja','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7766,0,NULL,'zna','zan gula','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7767,0,NULL,'znd','zande languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(7768,0,NULL,'zne','zande (individual language)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7769,0,NULL,'zng','mang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7770,0,NULL,'znk','manangkari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7771,0,NULL,'zns','mangas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7772,0,NULL,'zoc','copainalá zoque','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7773,0,NULL,'zoh','chimalapa zoque','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7774,0,NULL,'zom','zou','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7775,0,NULL,'zoo','asunción mixtepec zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7776,0,NULL,'zoq','tabasco zoque','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7777,0,NULL,'zor','rayón zoque','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7778,0,NULL,'zos','francisco león zoque','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7779,0,NULL,'zpa','lachiguiri zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7780,0,NULL,'zpb','yautepec zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7781,0,NULL,'zpc','choapan zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7782,0,NULL,'zpd','southeastern ixtlán zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7783,0,NULL,'zpe','petapa zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7784,0,NULL,'zpf','san pedro quiatoni zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7785,0,NULL,'zpg','guevea de humboldt zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7786,0,NULL,'zph','totomachapan zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7787,0,NULL,'zpi','santa maría quiegolani zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7788,0,NULL,'zpj','quiavicuzas zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7789,0,NULL,'zpk','tlacolulita zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7790,0,NULL,'zpl','lachixío zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7791,0,NULL,'zpm','mixtepec zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7792,0,NULL,'zpn','santa inés yatzechi zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7793,0,NULL,'zpo','amatlán zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7794,0,NULL,'zpp','el alto zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7795,0,NULL,'zpq','zoogocho zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7796,0,NULL,'zpr','santiago xanica zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7797,0,NULL,'zps','coatlán zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7798,0,NULL,'zpt','san vicente coatlán zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7799,0,NULL,'zpu','yalálag zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7800,0,NULL,'zpv','chichicapan zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7801,0,NULL,'zpw','zaniza zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7802,0,NULL,'zpx','san baltazar loxicha zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7803,0,NULL,'zpy','mazaltepec zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7804,0,NULL,'zpz','texmelucan zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7805,0,NULL,'zqe','qiubei zhuang','1248825600',NULL,NULL,NULL,NULL,'za',NULL,NULL); +INSERT INTO "iana_records" VALUES(7806,0,NULL,'zra','kara (korea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7807,0,NULL,'zrg','mirgan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7808,0,NULL,'zrn','zerenkel','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7809,0,NULL,'zro','záparo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7810,0,NULL,'zrp','zarphatic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7811,0,NULL,'zrs','mairasi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7812,0,NULL,'zsa','sarasira','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7813,0,NULL,'zsk','kaskean','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7814,0,NULL,'zsl','zambian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7815,0,NULL,'zsm','standard malay','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7816,0,NULL,'zsr','southern rincon zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7817,0,NULL,'zsu','sukurum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7818,0,NULL,'zte','elotepec zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7819,0,NULL,'ztg','xanaguía zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7820,0,NULL,'ztl','lapaguía-guivini zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7821,0,NULL,'ztm','san agustín mixtepec zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7822,0,NULL,'ztn','santa catarina albarradas zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7823,0,NULL,'ztp','loxicha zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7824,0,NULL,'ztq','quioquitani-quierí zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7825,0,NULL,'zts','tilquiapan zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7826,0,NULL,'ztt','tejalapan zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7827,0,NULL,'ztu','güilá zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7828,0,NULL,'ztx','zaachila zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7829,0,NULL,'zty','yatee zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7830,0,NULL,'zua','zeem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7831,0,NULL,'zuh','tokano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7832,0,NULL,'zum','kumzari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7833,0,NULL,'zun','zuni','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7834,0,NULL,'zuy','zumaya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7835,0,NULL,'zwa','zay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7836,0,NULL,'zxx','no linguistic content','1141776000',NULL,NULL,NULL,NULL,NULL,'special',NULL); +INSERT INTO "iana_records" VALUES(7836,0,NULL,'zxx','not applicable','1141776000',NULL,NULL,NULL,NULL,NULL,'special',NULL); +INSERT INTO "iana_records" VALUES(7837,0,NULL,'zyb','yongbei zhuang','1248825600',NULL,NULL,NULL,NULL,'za',NULL,NULL); +INSERT INTO "iana_records" VALUES(7838,0,NULL,'zyg','yang zhuang','1248825600',NULL,NULL,NULL,NULL,'za',NULL,NULL); +INSERT INTO "iana_records" VALUES(7839,0,NULL,'zyj','youjiang zhuang','1248825600',NULL,NULL,NULL,NULL,'za',NULL,NULL); +INSERT INTO "iana_records" VALUES(7840,0,NULL,'zyn','yongnan zhuang','1248825600',NULL,NULL,NULL,NULL,'za',NULL,NULL); +INSERT INTO "iana_records" VALUES(7841,0,NULL,'zyp','zyphe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7842,0,NULL,'zza','dimili','1156377600',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(7842,0,NULL,'zza','dimli (macrolanguage)','1156377600',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(7842,0,NULL,'zza','kirdki','1156377600',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(7842,0,NULL,'zza','kirmanjki (macrolanguage)','1156377600',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(7842,0,NULL,'zza','zaza','1156377600',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(7842,0,NULL,'zza','zazaki','1156377600',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(7843,6,NULL,'zzj','zuojiang zhuang','1248825600',NULL,NULL,NULL,NULL,'za',NULL,NULL); +INSERT INTO "iana_records" VALUES(7844,6,NULL,'aao','algerian saharan arabic','1248825600',NULL,'aao','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7845,6,NULL,'abh','tajiki arabic','1248825600',NULL,'abh','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7846,6,NULL,'abv','baharna arabic','1248825600',NULL,'abv','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7847,6,NULL,'acm','mesopotamian arabic','1248825600',NULL,'acm','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7848,6,NULL,'acq','ta''izzi-adeni arabic','1248825600',NULL,'acq','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7849,6,NULL,'acw','hijazi arabic','1248825600',NULL,'acw','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7850,6,NULL,'acx','omani arabic','1248825600',NULL,'acx','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7851,6,NULL,'acy','cypriot arabic','1248825600',NULL,'acy','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7852,6,NULL,'adf','dhofari arabic','1248825600',NULL,'adf','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7853,6,NULL,'ads','adamorobe sign language','1248825600',NULL,'ads','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7854,6,NULL,'aeb','tunisian arabic','1248825600',NULL,'aeb','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7855,6,NULL,'aec','saidi arabic','1248825600',NULL,'aec','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7856,6,NULL,'aed','argentine sign language','1248825600',NULL,'aed','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7857,6,NULL,'aen','armenian sign language','1248825600',NULL,'aen','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7858,6,NULL,'afb','gulf arabic','1248825600',NULL,'afb','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7859,6,NULL,'afg','afghan sign language','1248825600',NULL,'afg','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7860,6,NULL,'ajp','south levantine arabic','1248825600',NULL,'ajp','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7861,6,NULL,'apc','north levantine arabic','1248825600',NULL,'apc','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7862,6,NULL,'apd','sudanese arabic','1248825600',NULL,'apd','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7863,6,NULL,'arb','standard arabic','1248825600',NULL,'arb','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7864,6,NULL,'arq','algerian arabic','1248825600',NULL,'arq','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7865,6,NULL,'ars','najdi arabic','1248825600',NULL,'ars','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7866,6,NULL,'ary','moroccan arabic','1248825600',NULL,'ary','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7867,6,NULL,'arz','egyptian arabic','1248825600',NULL,'arz','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7868,6,NULL,'ase','american sign language','1248825600',NULL,'ase','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7869,6,NULL,'asf','australian sign language','1248825600',NULL,'asf','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7870,6,NULL,'asp','algerian sign language','1248825600',NULL,'asp','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7871,6,NULL,'asq','austrian sign language','1248825600',NULL,'asq','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7872,6,NULL,'asw','australian aborigines sign language','1248825600',NULL,'asw','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7873,6,NULL,'auz','uzbeki arabic','1248825600',NULL,'auz','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7874,6,NULL,'avl','eastern egyptian bedawi arabic','1248825600',NULL,'avl','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7875,6,NULL,'ayh','hadrami arabic','1248825600',NULL,'ayh','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7876,6,NULL,'ayl','libyan arabic','1248825600',NULL,'ayl','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7877,6,NULL,'ayn','sanaani arabic','1248825600',NULL,'ayn','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7878,6,NULL,'ayp','north mesopotamian arabic','1248825600',NULL,'ayp','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7879,6,NULL,'bbz','babalia creole arabic','1248825600',NULL,'bbz','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7880,6,NULL,'bfi','british sign language','1248825600',NULL,'bfi','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7881,6,NULL,'bfk','ban khor sign language','1248825600',NULL,'bfk','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7882,6,NULL,'bjn','banjar','1248825600',NULL,'bjn','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7883,6,NULL,'bog','bamako sign language','1248825600',NULL,'bog','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7884,6,NULL,'bqn','bulgarian sign language','1248825600',NULL,'bqn','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7885,6,NULL,'bqy','bengkala sign language','1248825600',NULL,'bqy','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7886,6,NULL,'btj','bacanese malay','1248825600',NULL,'btj','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7887,6,NULL,'bve','berau malay','1248825600',NULL,'bve','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7888,6,NULL,'bvl','bolivian sign language','1248825600',NULL,'bvl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7889,6,NULL,'bvu','bukit malay','1248825600',NULL,'bvu','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7890,6,NULL,'bzs','brazilian sign language','1248825600',NULL,'bzs','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7891,6,NULL,'cdo','min dong chinese','1248825600',NULL,'cdo','zh',NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(7892,6,NULL,'cds','chadian sign language','1248825600',NULL,'cds','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7893,6,NULL,'cjy','jinyu chinese','1248825600',NULL,'cjy','zh',NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(7894,6,NULL,'cmn','mandarin chinese','1248825600',NULL,'cmn','zh',NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(7895,6,NULL,'coa','cocos islands malay','1248825600',NULL,'coa','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7896,6,NULL,'cpx','pu-xian chinese','1248825600',NULL,'cpx','zh',NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(7897,6,NULL,'csc','catalan sign language','1248825600',NULL,'csc','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7897,6,NULL,'csc','lengua de señas catalana','1248825600',NULL,'csc','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7897,6,NULL,'csc','llengua de signes catalana','1248825600',NULL,'csc','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7898,6,NULL,'csd','chiangmai sign language','1248825600',NULL,'csd','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7899,6,NULL,'cse','czech sign language','1248825600',NULL,'cse','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7900,6,NULL,'csf','cuba sign language','1248825600',NULL,'csf','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7901,6,NULL,'csg','chilean sign language','1248825600',NULL,'csg','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7902,6,NULL,'csl','chinese sign language','1248825600',NULL,'csl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7903,6,NULL,'csn','colombian sign language','1248825600',NULL,'csn','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7904,6,NULL,'csq','croatia sign language','1248825600',NULL,'csq','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7905,6,NULL,'csr','costa rican sign language','1248825600',NULL,'csr','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7906,6,NULL,'czh','huizhou chinese','1248825600',NULL,'czh','zh',NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(7907,6,NULL,'czo','min zhong chinese','1248825600',NULL,'czo','zh',NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(7908,6,NULL,'doq','dominican sign language','1248825600',NULL,'doq','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7909,6,NULL,'dse','dutch sign language','1248825600',NULL,'dse','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7910,6,NULL,'dsl','danish sign language','1248825600',NULL,'dsl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7911,6,NULL,'dup','duano','1248825600',NULL,'dup','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7912,6,NULL,'ecs','ecuadorian sign language','1248825600',NULL,'ecs','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7913,6,NULL,'esl','egypt sign language','1248825600',NULL,'esl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7914,6,NULL,'esn','salvadoran sign language','1248825600',NULL,'esn','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7915,6,NULL,'eso','estonian sign language','1248825600',NULL,'eso','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7916,6,NULL,'eth','ethiopian sign language','1248825600',NULL,'eth','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7917,6,NULL,'fcs','quebec sign language','1248825600',NULL,'fcs','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7918,6,NULL,'fse','finnish sign language','1248825600',NULL,'fse','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7919,6,NULL,'fsl','french sign language','1248825600',NULL,'fsl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7920,6,NULL,'fss','finland-swedish sign language','1248825600',NULL,'fss','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7920,6,NULL,'fss','finlandssvenskt teckenspråk','1248825600',NULL,'fss','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7920,6,NULL,'fss','suomenruotsalainen viittomakieli','1248825600',NULL,'fss','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7921,6,NULL,'gan','gan chinese','1248825600',NULL,'gan','zh',NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(7922,6,NULL,'gom','goan konkani','1248825600',NULL,'gom','kok',NULL,'kok',NULL,NULL); +INSERT INTO "iana_records" VALUES(7923,6,NULL,'gse','ghanaian sign language','1248825600',NULL,'gse','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7924,6,NULL,'gsg','german sign language','1248825600',NULL,'gsg','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7925,6,NULL,'gsm','guatemalan sign language','1248825600',NULL,'gsm','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7926,6,NULL,'gss','greek sign language','1248825600',NULL,'gss','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7927,6,NULL,'gus','guinean sign language','1248825600',NULL,'gus','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7928,6,NULL,'hab','hanoi sign language','1248825600',NULL,'hab','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7929,6,NULL,'haf','haiphong sign language','1248825600',NULL,'haf','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7930,6,NULL,'hak','hakka chinese','1248825600',NULL,'hak','zh',NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(7931,6,NULL,'hds','honduras sign language','1248825600',NULL,'hds','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7932,6,NULL,'hji','haji','1248825600',NULL,'hji','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7933,6,NULL,'hks','heung kong sau yue','1248825600',NULL,'hks','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7933,6,NULL,'hks','hong kong sign language','1248825600',NULL,'hks','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7934,6,NULL,'hos','ho chi minh city sign language','1248825600',NULL,'hos','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7935,6,NULL,'hps','hawai''i pidgin sign language','1248825600',NULL,'hps','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7936,6,NULL,'hsh','hungarian sign language','1248825600',NULL,'hsh','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7937,6,NULL,'hsl','hausa sign language','1248825600',NULL,'hsl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7938,6,NULL,'hsn','xiang chinese','1248825600',NULL,'hsn','zh',NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(7939,6,NULL,'icl','icelandic sign language','1248825600',NULL,'icl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7940,6,NULL,'ils','international sign','1248825600',NULL,'ils','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7941,6,NULL,'inl','indonesian sign language','1248825600',NULL,'inl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7942,6,NULL,'ins','indian sign language','1248825600',NULL,'ins','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7943,6,NULL,'ise','italian sign language','1248825600',NULL,'ise','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7944,6,NULL,'isg','irish sign language','1248825600',NULL,'isg','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7945,6,NULL,'isr','israeli sign language','1248825600',NULL,'isr','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7946,6,NULL,'jak','jakun','1248825600',NULL,'jak','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7947,6,NULL,'jax','jambi malay','1248825600',NULL,'jax','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7948,6,NULL,'jcs','jamaican country sign language','1248825600',NULL,'jcs','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7949,6,NULL,'jhs','jhankot sign language','1248825600',NULL,'jhs','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7950,6,NULL,'jls','jamaican sign language','1268265600',NULL,'jls','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7951,6,NULL,'jos','jordanian sign language','1248825600',NULL,'jos','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7952,6,NULL,'jsl','japanese sign language','1248825600',NULL,'jsl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7953,6,NULL,'jus','jumla sign language','1248825600',NULL,'jus','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7954,6,NULL,'kgi','selangor sign language','1248825600',NULL,'kgi','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7955,6,NULL,'knn','konkani (individual language)','1248825600',NULL,'knn','kok',NULL,'kok',NULL,NULL); +INSERT INTO "iana_records" VALUES(7956,6,NULL,'kvb','kubu','1248825600',NULL,'kvb','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7957,6,NULL,'kvk','korean sign language','1248825600',NULL,'kvk','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7958,6,NULL,'kvr','kerinci','1248825600',NULL,'kvr','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7959,6,NULL,'kxd','brunei','1248825600',NULL,'kxd','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7960,6,NULL,'lbs','libyan sign language','1248825600',NULL,'lbs','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7961,6,NULL,'lce','loncong','1248825600',NULL,'lce','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7962,6,NULL,'lcf','lubu','1248825600',NULL,'lcf','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7963,6,NULL,'liw','col','1248825600',NULL,'liw','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7964,6,NULL,'lls','lithuanian sign language','1248825600',NULL,'lls','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7965,6,NULL,'lsg','lyons sign language','1248825600',NULL,'lsg','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7966,6,NULL,'lsl','latvian sign language','1248825600',NULL,'lsl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7967,6,NULL,'lso','laos sign language','1248825600',NULL,'lso','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7968,6,NULL,'lsp','lengua de señas panameñas','1248825600',NULL,'lsp','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7968,6,NULL,'lsp','panamanian sign language','1248825600',NULL,'lsp','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7969,6,NULL,'lst','trinidad and tobago sign language','1248825600',NULL,'lst','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7970,6,NULL,'lsy','mauritian sign language','1268265600',NULL,'lsy','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7971,6,NULL,'ltg','latgalian','1268265600',NULL,'ltg','lv',NULL,'lv',NULL,NULL); +INSERT INTO "iana_records" VALUES(7972,6,NULL,'lvs','standard latvian','1268265600',NULL,'lvs','lv',NULL,'lv',NULL,NULL); +INSERT INTO "iana_records" VALUES(7973,6,NULL,'lzh','literary chinese','1248825600',NULL,'lzh','zh',NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(7974,6,NULL,'max','north moluccan malay','1248825600',NULL,'max','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7975,6,NULL,'mdl','maltese sign language','1248825600',NULL,'mdl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7976,6,NULL,'meo','kedah malay','1248825600',NULL,'meo','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7977,6,NULL,'mfa','pattani malay','1248825600',NULL,'mfa','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7978,6,NULL,'mfb','bangka','1248825600',NULL,'mfb','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7979,6,NULL,'mfs','mexican sign language','1248825600',NULL,'mfs','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7980,6,NULL,'min','minangkabau','1248825600',NULL,'min','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7981,6,NULL,'mnp','min bei chinese','1248825600',NULL,'mnp','zh',NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(7982,6,NULL,'mqg','kota bangun kutai malay','1248825600',NULL,'mqg','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7983,6,NULL,'mre','martha''s vineyard sign language','1248825600',NULL,'mre','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7984,6,NULL,'msd','yucatec maya sign language','1248825600',NULL,'msd','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7985,6,NULL,'msi','sabah malay','1248825600',NULL,'msi','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7986,6,NULL,'msr','mongolian sign language','1248825600',NULL,'msr','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7987,6,NULL,'mui','musi','1248825600',NULL,'mui','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7988,6,NULL,'mzc','madagascar sign language','1248825600',NULL,'mzc','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7989,6,NULL,'mzg','monastic sign language','1248825600',NULL,'mzg','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7990,6,NULL,'mzy','mozambican sign language','1248825600',NULL,'mzy','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7991,6,NULL,'nan','min nan chinese','1248825600',NULL,'nan','zh',NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(7992,6,NULL,'nbs','namibian sign language','1248825600',NULL,'nbs','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7993,6,NULL,'ncs','nicaraguan sign language','1248825600',NULL,'ncs','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7994,6,NULL,'nsi','nigerian sign language','1248825600',NULL,'nsi','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7995,6,NULL,'nsl','norwegian sign language','1248825600',NULL,'nsl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7996,6,NULL,'nsp','nepalese sign language','1248825600',NULL,'nsp','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7997,6,NULL,'nsr','maritime sign language','1248825600',NULL,'nsr','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7998,6,NULL,'nzs','new zealand sign language','1248825600',NULL,'nzs','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7999,6,NULL,'okl','old kentish sign language','1248825600',NULL,'okl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8000,6,NULL,'orn','orang kanaq','1248825600',NULL,'orn','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(8001,6,NULL,'ors','orang seletar','1248825600',NULL,'ors','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(8002,6,NULL,'pel','pekal','1248825600',NULL,'pel','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(8003,6,NULL,'pga','sudanese creole arabic','1248825600',NULL,'pga','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(8004,6,NULL,'pks','pakistan sign language','1248825600',NULL,'pks','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8005,6,NULL,'prl','peruvian sign language','1248825600',NULL,'prl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8006,6,NULL,'prz','providencia sign language','1248825600',NULL,'prz','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8007,6,NULL,'psc','persian sign language','1248825600',NULL,'psc','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8008,6,NULL,'psd','plains indian sign language','1248825600',NULL,'psd','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8009,6,NULL,'pse','central malay','1248825600',NULL,'pse','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(8010,6,NULL,'psg','penang sign language','1248825600',NULL,'psg','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8011,6,NULL,'psl','puerto rican sign language','1248825600',NULL,'psl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8012,6,NULL,'pso','polish sign language','1248825600',NULL,'pso','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8013,6,NULL,'psp','philippine sign language','1248825600',NULL,'psp','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8014,6,NULL,'psr','portuguese sign language','1248825600',NULL,'psr','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8015,6,NULL,'pys','lengua de señas del paraguay','1268265600',NULL,'pys','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8015,6,NULL,'pys','paraguayan sign language','1268265600',NULL,'pys','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8016,6,NULL,'rms','romanian sign language','1248825600',NULL,'rms','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8017,6,NULL,'rsi','rennellese sign language','1248825600',NULL,'rsi','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8018,6,NULL,'rsl','russian sign language','1248825600',NULL,'rsl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8019,6,NULL,'sdl','saudi arabian sign language','1248825600',NULL,'sdl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8020,6,NULL,'sfb','french belgian sign language','1248825600',NULL,'sfb','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8020,6,NULL,'sfb','langue des signes de belgique francophone','1248825600',NULL,'sfb','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8021,6,NULL,'sfs','south african sign language','1248825600',NULL,'sfs','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8022,6,NULL,'sgg','swiss-german sign language','1248825600',NULL,'sgg','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8023,6,NULL,'sgx','sierra leone sign language','1248825600',NULL,'sgx','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8024,6,NULL,'shu','chadian arabic','1248825600',NULL,'shu','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(8025,6,NULL,'slf','swiss-italian sign language','1248825600',NULL,'slf','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8026,6,NULL,'sls','singapore sign language','1248825600',NULL,'sls','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8027,6,NULL,'sqs','sri lankan sign language','1248825600',NULL,'sqs','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8028,6,NULL,'ssh','shihhi arabic','1248825600',NULL,'ssh','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(8029,6,NULL,'ssp','spanish sign language','1248825600',NULL,'ssp','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8030,6,NULL,'ssr','swiss-french sign language','1248825600',NULL,'ssr','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8031,6,NULL,'svk','slovakian sign language','1248825600',NULL,'svk','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8032,6,NULL,'swc','congo swahili','1248825600',NULL,'swc','sw',NULL,'sw',NULL,NULL); +INSERT INTO "iana_records" VALUES(8033,6,NULL,'swh','kiswahili','1248825600',NULL,'swh','sw',NULL,'sw',NULL,NULL); +INSERT INTO "iana_records" VALUES(8033,6,NULL,'swh','swahili (individual language)','1248825600',NULL,'swh','sw',NULL,'sw',NULL,NULL); +INSERT INTO "iana_records" VALUES(8034,6,NULL,'swl','swedish sign language','1248825600',NULL,'swl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8035,6,NULL,'syy','al-sayyid bedouin sign language','1248825600',NULL,'syy','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8036,6,NULL,'tmw','temuan','1248825600',NULL,'tmw','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(8037,6,NULL,'tse','tunisian sign language','1248825600',NULL,'tse','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8038,6,NULL,'tsm','turkish sign language','1248825600',NULL,'tsm','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8038,6,NULL,'tsm','türk İşaret dili','1248825600',NULL,'tsm','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8039,6,NULL,'tsq','thai sign language','1248825600',NULL,'tsq','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8040,6,NULL,'tss','taiwan sign language','1248825600',NULL,'tss','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8041,6,NULL,'tsy','tebul sign language','1248825600',NULL,'tsy','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8042,6,NULL,'tza','tanzanian sign language','1248825600',NULL,'tza','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8043,6,NULL,'ugn','ugandan sign language','1248825600',NULL,'ugn','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8044,6,NULL,'ugy','uruguayan sign language','1248825600',NULL,'ugy','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8045,6,NULL,'ukl','ukrainian sign language','1248825600',NULL,'ukl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8046,6,NULL,'uks','kaapor sign language','1248825600',NULL,'uks','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8046,6,NULL,'uks','urubú-kaapor sign language','1248825600',NULL,'uks','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8047,6,NULL,'urk','urak lawoi''','1248825600',NULL,'urk','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(8048,6,NULL,'uzn','northern uzbek','1248825600',NULL,'uzn','uz',NULL,'uz',NULL,NULL); +INSERT INTO "iana_records" VALUES(8049,6,NULL,'uzs','southern uzbek','1248825600',NULL,'uzs','uz',NULL,'uz',NULL,NULL); +INSERT INTO "iana_records" VALUES(8050,6,NULL,'vgt','flemish sign language','1248825600',NULL,'vgt','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8050,6,NULL,'vgt','vlaamse gebarentaal','1248825600',NULL,'vgt','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8051,6,NULL,'vkk','kaur','1248825600',NULL,'vkk','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(8052,6,NULL,'vkt','tenggarong kutai malay','1248825600',NULL,'vkt','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(8053,6,NULL,'vsi','moldova sign language','1248825600',NULL,'vsi','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8054,6,NULL,'vsl','venezuelan sign language','1248825600',NULL,'vsl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8055,6,NULL,'vsv','llengua de signes valenciana','1248825600',NULL,'vsv','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8055,6,NULL,'vsv','valencian sign language','1248825600',NULL,'vsv','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8056,6,NULL,'wuu','wu chinese','1248825600',NULL,'wuu','zh',NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(8057,6,NULL,'xki','kenyan sign language','1248825600',NULL,'xki','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8058,6,NULL,'xml','malaysian sign language','1248825600',NULL,'xml','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8059,6,NULL,'xmm','manado malay','1248825600',NULL,'xmm','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(8060,6,NULL,'xms','moroccan sign language','1248825600',NULL,'xms','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8061,6,NULL,'yds','yiddish sign language','1248825600',NULL,'yds','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8062,6,NULL,'ysl','yugoslavian sign language','1248825600',NULL,'ysl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8063,6,NULL,'yue','yue chinese','1248825600',NULL,'yue','zh',NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(8064,6,NULL,'zib','zimbabwe sign language','1248825600',NULL,'zib','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8065,6,NULL,'zlm','malay (individual language)','1248825600',NULL,'zlm','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(8066,6,NULL,'zmi','negeri sembilan malay','1248825600',NULL,'zmi','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(8067,6,NULL,'zsl','zambian sign language','1248825600',NULL,'zsl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8068,1,NULL,'zsm','standard malay','1248825600',NULL,'zsm','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(8069,1,NULL,'arab','arabic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8070,1,NULL,'armi','imperial aramaic','1196812800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8071,1,NULL,'armn','armenian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8072,1,NULL,'avst','avestan','1185580800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8073,1,NULL,'bali','balinese','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8074,1,NULL,'bamu','bamum','1248912000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8075,1,NULL,'bass','bassa vah','1270857600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8076,1,NULL,'batk','batak','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8077,1,NULL,'beng','bengali','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8078,1,NULL,'blis','blissymbols','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8079,1,NULL,'bopo','bopomofo','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8080,1,NULL,'brah','brahmi','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8081,1,NULL,'brai','braille','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8082,1,NULL,'bugi','buginese','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8083,1,NULL,'buhd','buhid','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8084,1,NULL,'cakm','chakma','1196812800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8085,1,NULL,'cans','unified canadian aboriginal syllabics','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8086,1,NULL,'cari','carian','1153440000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8087,1,NULL,'cham','cham','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8088,1,NULL,'cher','cherokee','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8089,1,NULL,'cirt','cirth','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8090,1,NULL,'copt','coptic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8091,1,NULL,'cprt','cypriot','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8092,1,NULL,'cyrl','cyrillic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8093,1,NULL,'cyrs','cyrillic (old church slavonic variant)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8094,1,NULL,'deva','devanagari','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8094,1,NULL,'deva','nagari','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8095,1,NULL,'dsrt','deseret','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8095,1,NULL,'dsrt','mormon','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8096,1,NULL,'egyd','egyptian demotic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8097,1,NULL,'egyh','egyptian hieratic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8098,1,NULL,'egyp','egyptian hieroglyphs','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8099,1,NULL,'ethi','ethiopic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8099,1,NULL,'ethi','ge''ez','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8099,1,NULL,'ethi','geʻez','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8100,1,NULL,'geok','khutsuri (asomtavruli and nuskhuri)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8101,1,NULL,'geor','georgian (mkhedruli)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8102,1,NULL,'glag','glagolitic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8103,1,NULL,'goth','gothic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8104,1,NULL,'gran','grantha','1260316800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8105,1,NULL,'grek','greek','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8106,1,NULL,'gujr','gujarati','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8107,1,NULL,'guru','gurmukhi','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8108,1,NULL,'hang','hangeul','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8108,1,NULL,'hang','hangul','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8108,1,NULL,'hang','hangŭl','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8109,1,NULL,'hani','han','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8109,1,NULL,'hani','hanja','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8109,1,NULL,'hani','hanzi','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8109,1,NULL,'hani','kanji','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8110,1,NULL,'hano','hanunoo','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8110,1,NULL,'hano','hanunóo','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8111,1,NULL,'hans','han (simplified variant)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8112,1,NULL,'hant','han (traditional variant)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8113,1,NULL,'hebr','hebrew','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8114,1,NULL,'hira','hiragana','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8115,1,NULL,'hmng','pahawh hmong','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8116,1,NULL,'hrkt','(alias for hiragana + katakana)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8117,1,NULL,'hung','old hungarian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8118,1,NULL,'inds','harappan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8118,1,NULL,'inds','indus','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8119,1,NULL,'ital','old italic (etruscan, oscan, etc.)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8120,1,NULL,'java','javanese','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8121,1,NULL,'jpan','japanese (alias for han + hiragana + katakana)','1153440000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8122,1,NULL,'kali','kayah li','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8123,1,NULL,'kana','katakana','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8124,1,NULL,'khar','kharoshthi','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8125,1,NULL,'khmr','khmer','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8126,1,NULL,'knda','kannada','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8127,1,NULL,'kore','korean (alias for hangul + han)','1183593600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8128,1,NULL,'kpel','kpelle','1270857600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8129,1,NULL,'kthi','kaithi','1196812800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8130,1,NULL,'lana','lanna','1153440000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8130,1,NULL,'lana','tai tham','1153440000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8131,1,NULL,'laoo','lao','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8132,1,NULL,'latf','latin (fraktur variant)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8133,1,NULL,'latg','latin (gaelic variant)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8134,1,NULL,'latn','latin','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8135,1,NULL,'lepc','lepcha','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8135,1,NULL,'lepc','róng','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8136,1,NULL,'limb','limbu','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8137,1,NULL,'lina','linear a','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8138,1,NULL,'linb','linear b','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8139,1,NULL,'lisu','fraser','1236902400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8139,1,NULL,'lisu','lisu','1236902400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8140,1,NULL,'loma','loma','1270857600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8141,1,NULL,'lyci','lycian','1153440000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8142,1,NULL,'lydi','lydian','1153440000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8143,1,NULL,'mand','mandaean','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8143,1,NULL,'mand','mandaic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8144,1,NULL,'mani','manichaean','1185580800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8145,1,NULL,'maya','mayan hieroglyphs','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8146,1,NULL,'mend','mende','1270857600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8147,1,NULL,'merc','meroitic cursive','1260316800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8148,1,NULL,'mero','meroitic hieroglyphs','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8149,1,NULL,'mlym','malayalam','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8150,1,NULL,'mong','mongolian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8151,1,NULL,'moon','moon','1169769600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8151,1,NULL,'moon','moon code','1169769600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8151,1,NULL,'moon','moon script','1169769600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8151,1,NULL,'moon','moon type','1169769600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8152,1,NULL,'mtei','meetei','1169769600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8152,1,NULL,'mtei','meitei mayek','1169769600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8152,1,NULL,'mtei','meithei','1169769600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8153,1,NULL,'mymr','burmese','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8153,1,NULL,'mymr','myanmar','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8154,1,NULL,'narb','ancient north arabian','1270857600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8154,1,NULL,'narb','old north arabian','1270857600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8155,1,NULL,'nbat','nabataean','1270857600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8156,1,NULL,'nkgb','''na-''khi ²ggŏ-¹baw','1236902400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8156,1,NULL,'nkgb','nakhi geba','1236902400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8156,1,NULL,'nkgb','naxi geba','1236902400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8157,1,NULL,'nkoo','n''ko','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8157,1,NULL,'nkoo','n’ko','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8158,1,NULL,'ogam','ogham','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8159,1,NULL,'olck','ol','1153440000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8159,1,NULL,'olck','ol cemet''','1153440000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8159,1,NULL,'olck','ol chiki','1153440000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8159,1,NULL,'olck','santali','1153440000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8160,1,NULL,'orkh','old turkic','1248912000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8160,1,NULL,'orkh','orkhon runic','1248912000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8161,1,NULL,'orya','oriya','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8162,1,NULL,'osma','osmanya','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8163,1,NULL,'palm','palmyrene','1270857600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8164,1,NULL,'perm','old permic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8165,1,NULL,'phag','phags-pa','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8166,1,NULL,'phli','inscriptional pahlavi','1196812800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8167,1,NULL,'phlp','psalter pahlavi','1196812800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8168,1,NULL,'phlv','book pahlavi','1185580800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8169,1,NULL,'phnx','phoenician','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8170,1,NULL,'plrd','miao','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8170,1,NULL,'plrd','pollard','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8171,1,NULL,'prti','inscriptional parthian','1196812800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8172,1,NULL,'qaaa..qabx','private use','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8173,1,NULL,'rjng','kaganga','1161043200',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8173,1,NULL,'rjng','redjang','1161043200',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8173,1,NULL,'rjng','rejang','1161043200',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8174,1,NULL,'roro','rongorongo','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8175,1,NULL,'runr','runic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8176,1,NULL,'samr','samaritan','1185580800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8177,1,NULL,'sara','sarati','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8178,1,NULL,'sarb','old south arabian','1248912000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8179,1,NULL,'saur','saurashtra','1153440000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8180,1,NULL,'sgnw','signwriting','1161043200',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8181,1,NULL,'shaw','shavian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8181,1,NULL,'shaw','shaw','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8182,1,NULL,'sinh','sinhala','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8183,1,NULL,'sund','sundanese','1153440000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8184,1,NULL,'sylo','syloti nagri','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8185,1,NULL,'syrc','syriac','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8186,1,NULL,'syre','syriac (estrangelo variant)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8187,1,NULL,'syrj','syriac (western variant)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8188,1,NULL,'syrn','syriac (eastern variant)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8189,1,NULL,'tagb','tagbanwa','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8190,1,NULL,'tale','tai le','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8191,1,NULL,'talu','new tai lue','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8192,1,NULL,'taml','tamil','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8193,1,NULL,'tavt','tai viet','1196812800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8194,1,NULL,'telu','telugu','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8195,1,NULL,'teng','tengwar','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8196,1,NULL,'tfng','berber','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8196,1,NULL,'tfng','tifinagh','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8197,1,NULL,'tglg','alibata','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8197,1,NULL,'tglg','baybayin','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8197,1,NULL,'tglg','tagalog','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8198,1,NULL,'thaa','thaana','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8199,1,NULL,'thai','thai','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8200,1,NULL,'tibt','tibetan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8201,1,NULL,'ugar','ugaritic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8202,1,NULL,'vaii','vai','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8203,1,NULL,'visp','visible speech','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8204,1,NULL,'wara','varang kshiti','1260316800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8204,1,NULL,'wara','warang citi','1260316800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8205,1,NULL,'xpeo','old persian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8206,1,NULL,'xsux','sumero-akkadian cuneiform','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8207,1,NULL,'yiii','yi','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8208,1,NULL,'zinh','code for inherited script','1238716800',NULL,NULL,NULL,NULL,NULL,NULL,'not intended for use as a language subtag'); +INSERT INTO "iana_records" VALUES(8209,1,NULL,'zmth','mathematical notation','1196812800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8210,1,NULL,'zsym','symbols','1196812800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8211,1,NULL,'zxxx','code for unwritten documents','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8212,1,NULL,'zyyy','code for undetermined script','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8213,2,NULL,'zzzz','code for uncoded script','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8214,2,NULL,'aa','private use','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8215,2,NULL,'ac','ascension island','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8216,2,NULL,'ad','andorra','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8217,2,NULL,'ae','united arab emirates','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8218,2,NULL,'af','afghanistan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8219,2,NULL,'ag','antigua and barbuda','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8220,2,NULL,'ai','anguilla','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8221,2,NULL,'al','albania','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8222,2,NULL,'am','armenia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8223,2,NULL,'an','netherlands antilles','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8224,2,NULL,'ao','angola','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8225,2,NULL,'aq','antarctica','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8226,2,NULL,'ar','argentina','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8227,2,NULL,'as','american samoa','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8228,2,NULL,'at','austria','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8229,2,NULL,'au','australia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8230,2,NULL,'aw','aruba','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8231,2,NULL,'ax','Åland islands','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8232,2,NULL,'az','azerbaijan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8233,2,NULL,'ba','bosnia and herzegovina','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8234,2,NULL,'bb','barbados','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8235,2,NULL,'bd','bangladesh','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8236,2,NULL,'be','belgium','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8237,2,NULL,'bf','burkina faso','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8238,2,NULL,'bg','bulgaria','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8239,2,NULL,'bh','bahrain','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8240,2,NULL,'bi','burundi','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8241,2,NULL,'bj','benin','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8242,2,NULL,'bl','saint barthélemy','1193961600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8243,2,NULL,'bm','bermuda','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8244,2,NULL,'bn','brunei darussalam','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8245,2,NULL,'bo','bolivia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8246,2,NULL,'br','brazil','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8247,2,NULL,'bs','bahamas','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8248,2,NULL,'bt','bhutan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8249,2,NULL,'bu','burma','1129420800',628819200,'mm',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8250,2,NULL,'bv','bouvet island','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8251,2,NULL,'bw','botswana','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8252,2,NULL,'by','belarus','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8253,2,NULL,'bz','belize','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8254,2,NULL,'ca','canada','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8255,2,NULL,'cc','cocos (keeling) islands','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8256,2,NULL,'cd','the democratic republic of the congo','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8257,2,NULL,'cf','central african republic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8258,2,NULL,'cg','congo','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8259,2,NULL,'ch','switzerland','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8260,2,NULL,'ci','côte d''ivoire','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8261,2,NULL,'ck','cook islands','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8262,2,NULL,'cl','chile','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8263,2,NULL,'cm','cameroon','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8264,2,NULL,'cn','china','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8265,2,NULL,'co','colombia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8266,2,NULL,'cp','clipperton island','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8267,2,NULL,'cr','costa rica','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8268,2,NULL,'cs','serbia and montenegro','1129420800',1160006400,NULL,NULL,NULL,NULL,NULL,'see rs for serbia or me for montenegro'); +INSERT INTO "iana_records" VALUES(8269,2,NULL,'cu','cuba','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8270,2,NULL,'cv','cape verde','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8271,2,NULL,'cx','christmas island','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8272,2,NULL,'cy','cyprus','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8273,2,NULL,'cz','czech republic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8274,2,NULL,'dd','german democratic republic','1129420800',657244800,'de',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8275,2,NULL,'de','germany','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8276,2,NULL,'dg','diego garcia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8277,2,NULL,'dj','djibouti','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8278,2,NULL,'dk','denmark','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8279,2,NULL,'dm','dominica','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8280,2,NULL,'do','dominican republic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8281,2,NULL,'dz','algeria','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8282,2,NULL,'ea','ceuta, melilla','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8283,2,NULL,'ec','ecuador','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8284,2,NULL,'ee','estonia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8285,2,NULL,'eg','egypt','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8286,2,NULL,'eh','western sahara','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8287,2,NULL,'er','eritrea','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8288,2,NULL,'es','spain','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8289,2,NULL,'et','ethiopia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8290,2,NULL,'eu','european union','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8291,2,NULL,'fi','finland','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8292,2,NULL,'fj','fiji','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8293,2,NULL,'fk','falkland islands (malvinas)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8294,2,NULL,'fm','federated states of micronesia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8295,2,NULL,'fo','faroe islands','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8296,2,NULL,'fr','france','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8297,2,NULL,'fx','metropolitan france','1129420800',868838400,'fr',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8298,2,NULL,'ga','gabon','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8299,2,NULL,'gb','united kingdom','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,'as of 2006-03-29 gb no longer includes the channel islands and isle of man; see gg, je, im'); +INSERT INTO "iana_records" VALUES(8300,2,NULL,'gd','grenada','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8301,2,NULL,'ge','georgia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8302,2,NULL,'gf','french guiana','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8303,2,NULL,'gg','guernsey','1143590400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8304,2,NULL,'gh','ghana','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8305,2,NULL,'gi','gibraltar','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8306,2,NULL,'gl','greenland','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8307,2,NULL,'gm','gambia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8308,2,NULL,'gn','guinea','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8309,2,NULL,'gp','guadeloupe','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8310,2,NULL,'gq','equatorial guinea','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8311,2,NULL,'gr','greece','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8312,2,NULL,'gs','south georgia and the south sandwich islands','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8313,2,NULL,'gt','guatemala','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8314,2,NULL,'gu','guam','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8315,2,NULL,'gw','guinea-bissau','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8316,2,NULL,'gy','guyana','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8317,2,NULL,'hk','hong kong','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8318,2,NULL,'hm','heard island and mcdonald islands','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8319,2,NULL,'hn','honduras','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8320,2,NULL,'hr','croatia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8321,2,NULL,'ht','haiti','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8322,2,NULL,'hu','hungary','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8323,2,NULL,'ic','canary islands','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8324,2,NULL,'id','indonesia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8325,2,NULL,'ie','ireland','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8326,2,NULL,'il','israel','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8327,2,NULL,'im','isle of man','1143590400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8328,2,NULL,'in','india','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8329,2,NULL,'io','british indian ocean territory','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8330,2,NULL,'iq','iraq','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8331,2,NULL,'ir','islamic republic of iran','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8332,2,NULL,'is','iceland','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8333,2,NULL,'it','italy','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8334,2,NULL,'je','jersey','1143590400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8335,2,NULL,'jm','jamaica','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8336,2,NULL,'jo','jordan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8337,2,NULL,'jp','japan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8338,2,NULL,'ke','kenya','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8339,2,NULL,'kg','kyrgyzstan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8340,2,NULL,'kh','cambodia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8341,2,NULL,'ki','kiribati','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8342,2,NULL,'km','comoros','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8343,2,NULL,'kn','saint kitts and nevis','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8344,2,NULL,'kp','democratic people''s republic of korea','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8345,2,NULL,'kr','republic of korea','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8346,2,NULL,'kw','kuwait','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8347,2,NULL,'ky','cayman islands','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8348,2,NULL,'kz','kazakhstan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8349,2,NULL,'la','lao people''s democratic republic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8350,2,NULL,'lb','lebanon','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8351,2,NULL,'lc','saint lucia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8352,2,NULL,'li','liechtenstein','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8353,2,NULL,'lk','sri lanka','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8354,2,NULL,'lr','liberia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8355,2,NULL,'ls','lesotho','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8356,2,NULL,'lt','lithuania','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8357,2,NULL,'lu','luxembourg','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8358,2,NULL,'lv','latvia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8359,2,NULL,'ly','libyan arab jamahiriya','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8360,2,NULL,'ma','morocco','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8361,2,NULL,'mc','monaco','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8362,2,NULL,'md','moldova','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8363,2,NULL,'me','montenegro','1160006400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8364,2,NULL,'mf','saint martin','1193961600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8365,2,NULL,'mg','madagascar','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8366,2,NULL,'mh','marshall islands','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8367,2,NULL,'mk','the former yugoslav republic of macedonia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8368,2,NULL,'ml','mali','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8369,2,NULL,'mm','myanmar','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8370,2,NULL,'mn','mongolia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8371,2,NULL,'mo','macao','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8372,2,NULL,'mp','northern mariana islands','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8373,2,NULL,'mq','martinique','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8374,2,NULL,'mr','mauritania','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8375,2,NULL,'ms','montserrat','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8376,2,NULL,'mt','malta','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8377,2,NULL,'mu','mauritius','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8378,2,NULL,'mv','maldives','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8379,2,NULL,'mw','malawi','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8380,2,NULL,'mx','mexico','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8381,2,NULL,'my','malaysia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8382,2,NULL,'mz','mozambique','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8383,2,NULL,'na','namibia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8384,2,NULL,'nc','new caledonia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8385,2,NULL,'ne','niger','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8386,2,NULL,'nf','norfolk island','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8387,2,NULL,'ng','nigeria','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8388,2,NULL,'ni','nicaragua','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8389,2,NULL,'nl','netherlands','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8390,2,NULL,'no','norway','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8391,2,NULL,'np','nepal','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8392,2,NULL,'nr','nauru','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8393,2,NULL,'nt','neutral zone','1129420800',742435200,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8394,2,NULL,'nu','niue','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8395,2,NULL,'nz','new zealand','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8396,2,NULL,'om','oman','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8397,2,NULL,'pa','panama','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8398,2,NULL,'pe','peru','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8399,2,NULL,'pf','french polynesia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8400,2,NULL,'pg','papua new guinea','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8401,2,NULL,'ph','philippines','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8402,2,NULL,'pk','pakistan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8403,2,NULL,'pl','poland','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8404,2,NULL,'pm','saint pierre and miquelon','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8405,2,NULL,'pn','pitcairn','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8406,2,NULL,'pr','puerto rico','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8407,2,NULL,'ps','occupied palestinian territory','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8408,2,NULL,'pt','portugal','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8409,2,NULL,'pw','palau','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8410,2,NULL,'py','paraguay','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8411,2,NULL,'qa','qatar','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8412,2,NULL,'qm..qz','private use','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8413,2,NULL,'re','réunion','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8414,2,NULL,'ro','romania','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8415,2,NULL,'rs','serbia','1160006400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8416,2,NULL,'ru','russian federation','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8417,2,NULL,'rw','rwanda','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8418,2,NULL,'sa','saudi arabia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8419,2,NULL,'sb','solomon islands','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8420,2,NULL,'sc','seychelles','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8421,2,NULL,'sd','sudan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8422,2,NULL,'se','sweden','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8423,2,NULL,'sg','singapore','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8424,2,NULL,'sh','saint helena, ascension and tristan da cunha','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8425,2,NULL,'si','slovenia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8426,2,NULL,'sj','svalbard and jan mayen','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8427,2,NULL,'sk','slovakia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8428,2,NULL,'sl','sierra leone','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8429,2,NULL,'sm','san marino','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8430,2,NULL,'sn','senegal','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8431,2,NULL,'so','somalia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8432,2,NULL,'sr','suriname','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8433,2,NULL,'st','sao tome and principe','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8434,2,NULL,'su','union of soviet socialist republics','1129420800',715132800,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8435,2,NULL,'sv','el salvador','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8436,2,NULL,'sy','syrian arab republic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8437,2,NULL,'sz','swaziland','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8438,2,NULL,'ta','tristan da cunha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8439,2,NULL,'tc','turks and caicos islands','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8440,2,NULL,'td','chad','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8441,2,NULL,'tf','french southern territories','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8442,2,NULL,'tg','togo','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8443,2,NULL,'th','thailand','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8444,2,NULL,'tj','tajikistan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8445,2,NULL,'tk','tokelau','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8446,2,NULL,'tl','timor-leste','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8447,2,NULL,'tm','turkmenistan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8448,2,NULL,'tn','tunisia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8449,2,NULL,'to','tonga','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8450,2,NULL,'tp','east timor','1129420800',1021852800,'tl',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8451,2,NULL,'tr','turkey','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8452,2,NULL,'tt','trinidad and tobago','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8453,2,NULL,'tv','tuvalu','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8454,2,NULL,'tw','taiwan, province of china','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8455,2,NULL,'tz','united republic of tanzania','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8456,2,NULL,'ua','ukraine','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8457,2,NULL,'ug','uganda','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8458,2,NULL,'um','united states minor outlying islands','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8459,2,NULL,'us','united states','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8460,2,NULL,'uy','uruguay','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8461,2,NULL,'uz','uzbekistan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8462,2,NULL,'va','holy see (vatican city state)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8463,2,NULL,'vc','saint vincent and the grenadines','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8464,2,NULL,'ve','venezuela','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8465,2,NULL,'vg','british virgin islands','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8466,2,NULL,'vi','u.s. virgin islands','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8467,2,NULL,'vn','viet nam','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8468,2,NULL,'vu','vanuatu','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8469,2,NULL,'wf','wallis and futuna','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8470,2,NULL,'ws','samoa','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8471,2,NULL,'xa..xz','private use','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8472,2,NULL,'yd','democratic yemen','1129420800',650592000,'ye',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8473,2,NULL,'ye','yemen','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8474,2,NULL,'yt','mayotte','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8475,2,NULL,'yu','yugoslavia','1129420800',1058918400,NULL,NULL,NULL,NULL,NULL,'see ba, hr, me, mk, rs, or si'); +INSERT INTO "iana_records" VALUES(8476,2,NULL,'za','south africa','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8477,2,NULL,'zm','zambia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8478,2,NULL,'zr','zaire','1129420800',868838400,'cd',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8479,2,NULL,'zw','zimbabwe','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8480,2,NULL,'zz','private use','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8481,2,NULL,'001','world','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8482,2,NULL,'002','africa','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8483,2,NULL,'005','south america','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8484,2,NULL,'009','oceania','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8485,2,NULL,'011','western africa','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8486,2,NULL,'013','central america','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8487,2,NULL,'014','eastern africa','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8488,2,NULL,'015','northern africa','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8489,2,NULL,'017','middle africa','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8490,2,NULL,'018','southern africa','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8491,2,NULL,'019','americas','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8492,2,NULL,'021','northern america','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8493,2,NULL,'029','caribbean','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8494,2,NULL,'030','eastern asia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8495,2,NULL,'034','southern asia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8496,2,NULL,'035','south-eastern asia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8497,2,NULL,'039','southern europe','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8498,2,NULL,'053','australia and new zealand','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8499,2,NULL,'054','melanesia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8500,2,NULL,'057','micronesia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8501,2,NULL,'061','polynesia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8502,2,NULL,'142','asia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8503,2,NULL,'143','central asia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8504,2,NULL,'145','western asia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8505,2,NULL,'150','europe','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8506,2,NULL,'151','eastern europe','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8507,2,NULL,'154','northern europe','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8508,2,NULL,'155','western europe','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8509,3,NULL,'419','latin america and the caribbean','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8510,3,NULL,'1606nict','late middle french (to 1606)','1174348800',NULL,NULL,'frm',NULL,NULL,NULL,'16th century french as in jean nicot, "thresor de la langue francoyse", 1606, but also including some french similar to that of rabelais'); +INSERT INTO "iana_records" VALUES(8511,3,NULL,'1694acad','early modern french','1174348800',NULL,NULL,'fr',NULL,NULL,NULL,'17th century french, as catalogued in the "dictionnaire de l''académie françoise", 4eme ed. 1694; frequently includes elements of middle french, as this is a transitional period'); +INSERT INTO "iana_records" VALUES(8512,3,NULL,'1901','traditional german orthography','1129420800',NULL,NULL,'de',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8513,3,NULL,'1959acad','"academic" ("governmental") variant of belarusian as codified in 1959','1222732800',NULL,NULL,'be',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8514,3,NULL,'1994','standardized resian orthography','1185580800',NULL,NULL,'sl-rozaj',NULL,NULL,NULL,'for standardized resian an orthography was published in 1994.'); +INSERT INTO "iana_records" VALUES(8514,3,NULL,'1994','standardized resian orthography','1185580800',NULL,NULL,'sl-rozaj-biske',NULL,NULL,NULL,'for standardized resian an orthography was published in 1994.'); +INSERT INTO "iana_records" VALUES(8514,3,NULL,'1994','standardized resian orthography','1185580800',NULL,NULL,'sl-rozaj-njiva',NULL,NULL,NULL,'for standardized resian an orthography was published in 1994.'); +INSERT INTO "iana_records" VALUES(8514,3,NULL,'1994','standardized resian orthography','1185580800',NULL,NULL,'sl-rozaj-osojs',NULL,NULL,NULL,'for standardized resian an orthography was published in 1994.'); +INSERT INTO "iana_records" VALUES(8514,3,NULL,'1994','standardized resian orthography','1185580800',NULL,NULL,'sl-rozaj-solba',NULL,NULL,NULL,'for standardized resian an orthography was published in 1994.'); +INSERT INTO "iana_records" VALUES(8515,3,NULL,'1996','german orthography of 1996','1129420800',NULL,NULL,'de',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8516,3,NULL,'alalc97','ala-lc romanization, 1997 edition','1260316800',NULL,NULL,NULL,NULL,NULL,NULL,'romanizations recommended by the american library association and the library of congress, in "ala-lc romanization tables: transliteration schemes for non-roman scripts" (1997), isbn 978-0-8444-0940-5.'); +INSERT INTO "iana_records" VALUES(8517,3,NULL,'aluku','aluku dialect','1252108800',NULL,NULL,'djk',NULL,NULL,NULL,'aluku dialect of the "busi nenge tongo" english-based creole continuum in eastern suriname and western french guiana'); +INSERT INTO "iana_records" VALUES(8517,3,NULL,'aluku','boni dialect','1252108800',NULL,NULL,'djk',NULL,NULL,NULL,'aluku dialect of the "busi nenge tongo" english-based creole continuum in eastern suriname and western french guiana'); +INSERT INTO "iana_records" VALUES(8518,3,NULL,'arevela','eastern armenian','1158537600',NULL,NULL,'hy',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8519,3,NULL,'arevmda','western armenian','1158537600',NULL,NULL,'hy',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8520,3,NULL,'baku1926','unified turkic latin alphabet (historical)','1176854400',NULL,NULL,'az',NULL,NULL,NULL,'denotes alphabet used in turkic republics/regions of the former ussr in late 1920s, and throughout 1930s, which aspired to represent equivalent phonemes in a unified fashion. also known as: new turkic alphabet; birlәşdirilmiş jeni tyrk Әlifbasь (birlesdirilmis jeni tyrk elifbasi); jaŋalif (janalif).'); +INSERT INTO "iana_records" VALUES(8520,3,NULL,'baku1926','unified turkic latin alphabet (historical)','1176854400',NULL,NULL,'ba',NULL,NULL,NULL,'denotes alphabet used in turkic republics/regions of the former ussr in late 1920s, and throughout 1930s, which aspired to represent equivalent phonemes in a unified fashion. also known as: new turkic alphabet; birlәşdirilmiş jeni tyrk Әlifbasь (birlesdirilmis jeni tyrk elifbasi); jaŋalif (janalif).'); +INSERT INTO "iana_records" VALUES(8520,3,NULL,'baku1926','unified turkic latin alphabet (historical)','1176854400',NULL,NULL,'crh',NULL,NULL,NULL,'denotes alphabet used in turkic republics/regions of the former ussr in late 1920s, and throughout 1930s, which aspired to represent equivalent phonemes in a unified fashion. also known as: new turkic alphabet; birlәşdirilmiş jeni tyrk Әlifbasь (birlesdirilmis jeni tyrk elifbasi); jaŋalif (janalif).'); +INSERT INTO "iana_records" VALUES(8520,3,NULL,'baku1926','unified turkic latin alphabet (historical)','1176854400',NULL,NULL,'kk',NULL,NULL,NULL,'denotes alphabet used in turkic republics/regions of the former ussr in late 1920s, and throughout 1930s, which aspired to represent equivalent phonemes in a unified fashion. also known as: new turkic alphabet; birlәşdirilmiş jeni tyrk Әlifbasь (birlesdirilmis jeni tyrk elifbasi); jaŋalif (janalif).'); +INSERT INTO "iana_records" VALUES(8520,3,NULL,'baku1926','unified turkic latin alphabet (historical)','1176854400',NULL,NULL,'krc',NULL,NULL,NULL,'denotes alphabet used in turkic republics/regions of the former ussr in late 1920s, and throughout 1930s, which aspired to represent equivalent phonemes in a unified fashion. also known as: new turkic alphabet; birlәşdirilmiş jeni tyrk Әlifbasь (birlesdirilmis jeni tyrk elifbasi); jaŋalif (janalif).'); +INSERT INTO "iana_records" VALUES(8520,3,NULL,'baku1926','unified turkic latin alphabet (historical)','1176854400',NULL,NULL,'ky',NULL,NULL,NULL,'denotes alphabet used in turkic republics/regions of the former ussr in late 1920s, and throughout 1930s, which aspired to represent equivalent phonemes in a unified fashion. also known as: new turkic alphabet; birlәşdirilmiş jeni tyrk Әlifbasь (birlesdirilmis jeni tyrk elifbasi); jaŋalif (janalif).'); +INSERT INTO "iana_records" VALUES(8520,3,NULL,'baku1926','unified turkic latin alphabet (historical)','1176854400',NULL,NULL,'sah',NULL,NULL,NULL,'denotes alphabet used in turkic republics/regions of the former ussr in late 1920s, and throughout 1930s, which aspired to represent equivalent phonemes in a unified fashion. also known as: new turkic alphabet; birlәşdirilmiş jeni tyrk Әlifbasь (birlesdirilmis jeni tyrk elifbasi); jaŋalif (janalif).'); +INSERT INTO "iana_records" VALUES(8520,3,NULL,'baku1926','unified turkic latin alphabet (historical)','1176854400',NULL,NULL,'tk',NULL,NULL,NULL,'denotes alphabet used in turkic republics/regions of the former ussr in late 1920s, and throughout 1930s, which aspired to represent equivalent phonemes in a unified fashion. also known as: new turkic alphabet; birlәşdirilmiş jeni tyrk Әlifbasь (birlesdirilmis jeni tyrk elifbasi); jaŋalif (janalif).'); +INSERT INTO "iana_records" VALUES(8520,3,NULL,'baku1926','unified turkic latin alphabet (historical)','1176854400',NULL,NULL,'tt',NULL,NULL,NULL,'denotes alphabet used in turkic republics/regions of the former ussr in late 1920s, and throughout 1930s, which aspired to represent equivalent phonemes in a unified fashion. also known as: new turkic alphabet; birlәşdirilmiş jeni tyrk Әlifbasь (birlesdirilmis jeni tyrk elifbasi); jaŋalif (janalif).'); +INSERT INTO "iana_records" VALUES(8520,3,NULL,'baku1926','unified turkic latin alphabet (historical)','1176854400',NULL,NULL,'uz',NULL,NULL,NULL,'denotes alphabet used in turkic republics/regions of the former ussr in late 1920s, and throughout 1930s, which aspired to represent equivalent phonemes in a unified fashion. also known as: new turkic alphabet; birlәşdirilmiş jeni tyrk Әlifbasь (birlesdirilmis jeni tyrk elifbasi); jaŋalif (janalif).'); +INSERT INTO "iana_records" VALUES(8521,3,NULL,'biscayan','biscayan dialect of basque','1271116800',NULL,NULL,'eu',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8522,3,NULL,'biske','the bila dialect of resian','1183593600',NULL,NULL,'sl-rozaj',NULL,NULL,NULL,'the dialect of san giorgio/bila is one of the four major local dialects of resian'); +INSERT INTO "iana_records" VALUES(8522,3,NULL,'biske','the san giorgio dialect of resian','1183593600',NULL,NULL,'sl-rozaj',NULL,NULL,NULL,'the dialect of san giorgio/bila is one of the four major local dialects of resian'); +INSERT INTO "iana_records" VALUES(8523,3,NULL,'boont','boontling','1158537600',NULL,NULL,'en',NULL,NULL,NULL,'jargon embedded in american english'); +INSERT INTO "iana_records" VALUES(8524,3,NULL,'fonipa','international phonetic alphabet','1165795200',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8525,3,NULL,'fonupa','uralic phonetic alphabet','1165795200',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8526,3,NULL,'hepburn','hepburn romanization','1254355200',NULL,NULL,'ja-latn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8527,3,NULL,'heploc','hepburn romanization, library of congress method','1254355200',1265500800,'alalc97','ja-latn-hepburn',NULL,NULL,NULL,'preferred tag is ja-latn-alalc97'); +INSERT INTO "iana_records" VALUES(8528,3,NULL,'hognorsk','norwegian in høgnorsk (high norwegian) orthography','1262390400',NULL,NULL,'nn',NULL,NULL,NULL,'norwegian following ivar aasen''s orthographical principles, including modern usage.'); +INSERT INTO "iana_records" VALUES(8529,3,NULL,'jauer','jauer dialect of romansh','1277769600',NULL,NULL,'rm',NULL,NULL,NULL,'the spoken dialect of the val müstair, which has no written standard.'); +INSERT INTO "iana_records" VALUES(8530,3,NULL,'kkcor','common cornish orthography of revived cornish','1223942400',NULL,NULL,'kw',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8531,3,NULL,'lipaw','the lipovaz dialect of resian','1186790400',NULL,NULL,'sl-rozaj',NULL,NULL,NULL,'the dialect of lipovaz/lipovec is one of the minor local dialects of resian'); +INSERT INTO "iana_records" VALUES(8531,3,NULL,'lipaw','the lipovec dialect of resian','1186790400',NULL,NULL,'sl-rozaj',NULL,NULL,NULL,'the dialect of lipovaz/lipovec is one of the minor local dialects of resian'); +INSERT INTO "iana_records" VALUES(8532,3,NULL,'monoton','monotonic greek','1165795200',NULL,NULL,'el',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8533,3,NULL,'ndyuka','aukan dialect','1252108800',NULL,NULL,'djk',NULL,NULL,NULL,'ndyuka dialect of the "busi nenge tongo" english-based creole continuum in eastern suriname and western french guiana'); +INSERT INTO "iana_records" VALUES(8533,3,NULL,'ndyuka','ndyuka dialect','1252108800',NULL,NULL,'djk',NULL,NULL,NULL,'ndyuka dialect of the "busi nenge tongo" english-based creole continuum in eastern suriname and western french guiana'); +INSERT INTO "iana_records" VALUES(8534,3,NULL,'nedis','nadiza dialect','1129420800',NULL,NULL,'sl',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8534,3,NULL,'nedis','natisone dialect','1129420800',NULL,NULL,'sl',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8535,3,NULL,'njiva','the gniva dialect of resian','1183593600',NULL,NULL,'sl-rozaj',NULL,NULL,NULL,'the dialect of gniva/njiva is one of the four major local dialects of resian'); +INSERT INTO "iana_records" VALUES(8535,3,NULL,'njiva','the njiva dialect of resian','1183593600',NULL,NULL,'sl-rozaj',NULL,NULL,NULL,'the dialect of gniva/njiva is one of the four major local dialects of resian'); +INSERT INTO "iana_records" VALUES(8536,3,NULL,'osojs','the oseacco dialect of resian','1183593600',NULL,NULL,'sl-rozaj',NULL,NULL,NULL,'the dialect of oseacco/osojane is one of the four major local dialects of resian'); +INSERT INTO "iana_records" VALUES(8536,3,NULL,'osojs','the osojane dialect of resian','1183593600',NULL,NULL,'sl-rozaj',NULL,NULL,NULL,'the dialect of oseacco/osojane is one of the four major local dialects of resian'); +INSERT INTO "iana_records" VALUES(8537,3,NULL,'pamaka','pamaka dialect','1252108800',NULL,NULL,'djk',NULL,NULL,NULL,'pamaka dialect of the "busi nenge tongo" english-based creole continuum in eastern suriname and western french guiana'); +INSERT INTO "iana_records" VALUES(8538,3,NULL,'pinyin','pinyin romanization','1223942400',NULL,NULL,'bo-latn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8538,3,NULL,'pinyin','pinyin romanization','1223942400',NULL,NULL,'zh-latn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8539,3,NULL,'polyton','polytonic greek','1165795200',NULL,NULL,'el',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8540,3,NULL,'puter','puter idiom of romansh','1277769600',NULL,NULL,'rm',NULL,NULL,NULL,'puter is one of the five traditional written standards or "idioms" of the romansh language.'); +INSERT INTO "iana_records" VALUES(8541,3,NULL,'rozaj','resian','1129420800',NULL,NULL,'sl',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8541,3,NULL,'rozaj','resianic','1129420800',NULL,NULL,'sl',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8541,3,NULL,'rozaj','rezijan','1129420800',NULL,NULL,'sl',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8542,3,NULL,'rumgr','rumantsch grischun','1277769600',NULL,NULL,'rm',NULL,NULL,NULL,'supraregional romansh written standard'); +INSERT INTO "iana_records" VALUES(8543,3,NULL,'scotland','scottish standard english','1188518400',NULL,NULL,'en',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8544,3,NULL,'scouse','scouse','1158537600',NULL,NULL,'en',NULL,NULL,NULL,'english liverpudlian dialect known as ''scouse'''); +INSERT INTO "iana_records" VALUES(8545,3,NULL,'solba','the solbica dialect of resian','1183593600',NULL,NULL,'sl-rozaj',NULL,NULL,NULL,'the dialect of stolvizza/solbica is one of the four major local dialects of resian'); +INSERT INTO "iana_records" VALUES(8545,3,NULL,'solba','the stolvizza dialect of resian','1183593600',NULL,NULL,'sl-rozaj',NULL,NULL,NULL,'the dialect of stolvizza/solbica is one of the four major local dialects of resian'); +INSERT INTO "iana_records" VALUES(8546,3,NULL,'surmiran','surmiran idiom of romansh','1277769600',NULL,NULL,'rm',NULL,NULL,NULL,'surmiran is one of the five traditional written standards or "idioms" of the romansh language.'); +INSERT INTO "iana_records" VALUES(8547,3,NULL,'sursilv','sursilvan idiom of romansh','1277769600',NULL,NULL,'rm',NULL,NULL,NULL,'sursilvan is one of the five traditional written standards or "idioms" of the romansh language.'); +INSERT INTO "iana_records" VALUES(8548,3,NULL,'sutsilv','sutsilvan idiom of romansh','1277769600',NULL,NULL,'rm',NULL,NULL,NULL,'sutsilvan is one of the five traditional written standards or "idioms" of the romansh language.'); +INSERT INTO "iana_records" VALUES(8549,3,NULL,'tarask','belarusian in taraskievica orthography','1177632000',NULL,NULL,'be',NULL,NULL,NULL,'the subtag represents branislau taraskievic''s belarusian orthography as published in "bielaruski klasycny pravapis" by juras buslakou, vincuk viacorka, zmicier sanko, and zmicier sauka (vilnia- miensk 2005).'); +INSERT INTO "iana_records" VALUES(8550,3,NULL,'uccor','unified cornish orthography of revived cornish','1223942400',NULL,NULL,'kw',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8551,3,NULL,'ucrcor','unified cornish revised orthography of revived cornish','1223942400',NULL,NULL,'kw',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8552,3,NULL,'ulster','ulster dialect of scots','1270857600',NULL,NULL,'sco',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8553,3,NULL,'valencia','valencian','1173139200',NULL,NULL,'ca',NULL,NULL,NULL,'variety spoken in the "comunidad valenciana" region of spain, where it is co-official with spanish.'); +INSERT INTO "iana_records" VALUES(8554,3,NULL,'vallader','vallader idiom of romansh','1277769600',NULL,NULL,'rm',NULL,NULL,NULL,'vallader is one of the five traditional written standards or "idioms" of the romansh language.'); +INSERT INTO "iana_records" VALUES(8555,4,NULL,'wadegile','wade-giles romanization','1222992000',NULL,NULL,'zh-latn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8556,4,'art-lojban',NULL,'lojban','1005436800',1062460800,'jbo',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8557,4,'cel-gaulish',NULL,'gaulish','990748800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8558,4,'en-gb-oed',NULL,'english, oxford english dictionary spelling','1057708800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8559,4,'i-ami',NULL,'amis','927590400',1248825600,'ami',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8560,4,'i-bnn',NULL,'bunun','927590400',1248825600,'bnn',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8561,4,'i-default',NULL,'default language','889488000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8562,4,'i-enochian',NULL,'enochian','1025654400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8563,4,'i-hak',NULL,'hakka','917740800',947462400,'hak',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8564,4,'i-klingon',NULL,'klingon','927676800',1077580800,'tlh',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8565,4,'i-lux',NULL,'luxembourgish','874627200',905299200,'lb',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8566,4,'i-mingo',NULL,'mingo','874627200',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8567,4,'i-navajo',NULL,'navajo','874627200',950832000,'nv',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8568,4,'i-pwn',NULL,'paiwan','927590400',1248825600,'pwn',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8569,4,'i-tao',NULL,'tao','927590400',1248825600,'tao',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8570,4,'i-tay',NULL,'tayal','927590400',1248825600,'tay',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8571,4,'i-tsu',NULL,'tsou','927590400',1248825600,'tsu',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8572,4,'no-bok',NULL,'norwegian bokmal','809136000',950832000,'nb',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8573,4,'no-nyn',NULL,'norwegian nynorsk','809136000',950832000,'nn',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8574,4,'sgn-be-fr',NULL,'belgian-french sign language','1005436800',1248825600,'sfb',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8575,4,'sgn-be-nl',NULL,'belgian-flemish sign language','1005436800',1248825600,'vgt',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8576,4,'sgn-ch-de',NULL,'swiss german sign language','1005436800',1248825600,'sgg',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8577,4,'zh-guoyu',NULL,'mandarin or standard chinese','945475200',1121385600,'cmn',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8578,4,'zh-hakka',NULL,'hakka','945475200',1248825600,'hak',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8579,4,'zh-min',NULL,'min, fuzhou, hokkien, amoy, or taiwanese','945475200',1248825600,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8580,4,'zh-min-nan',NULL,'minnan, hokkien, amoy, taiwanese, southern min, southern fujian, hoklo, southern fukien, ho-lo','985564800',1248825600,'nan',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8581,5,'zh-xiang',NULL,'xiang or hunanese','945475200',1248825600,'hsn',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8582,5,'az-arab',NULL,'azerbaijani in arabic script','1054252800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8583,5,'az-cyrl',NULL,'azerbaijani in cyrillic script','1054252800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8584,5,'az-latn',NULL,'azerbaijani in latin script','1054252800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8585,5,'be-latn',NULL,'belarusian in latin script','1104969600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8586,5,'bs-cyrl',NULL,'bosnian in cyrillic script','1108598400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8587,5,'bs-latn',NULL,'bosnian in latin script','1108598400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8588,5,'de-1901',NULL,'german, traditional orthography','995328000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8589,5,'de-1996',NULL,'german, orthography of 1996','995328000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8590,5,'de-at-1901',NULL,'german, austrian variant, traditional orthography','995328000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8591,5,'de-at-1996',NULL,'german, austrian variant, orthography of 1996','995328000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8592,5,'de-ch-1901',NULL,'german, swiss variant, traditional orthography','995328000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8593,5,'de-ch-1996',NULL,'german, swiss variant, orthography of 1996','995328000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8594,5,'de-de-1901',NULL,'german, german variant, traditional orthography','995328000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8595,5,'de-de-1996',NULL,'german, german variant, orthography of 1996','995328000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8596,5,'en-boont',NULL,'boontling','1045180800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8597,5,'en-scouse',NULL,'scouse','959212800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8598,5,'es-419',NULL,'latin american spanish','1121385600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8599,5,'iu-cans',NULL,'inuktitut in canadian aboriginal syllabic script','1108598400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8600,5,'iu-latn',NULL,'inuktitut in latin script','1108598400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8601,5,'mn-cyrl',NULL,'mongolian in cyrillic script','1108598400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8602,5,'mn-mong',NULL,'mongolian in mongolian script','1108598400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8603,5,'sgn-br',NULL,'brazilian sign language','1005436800',1248825600,'bzs',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8604,5,'sgn-co',NULL,'colombian sign language','1005436800',1248825600,'csn',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8605,5,'sgn-de',NULL,'german sign language','1005436800',1248825600,'gsg',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8606,5,'sgn-dk',NULL,'danish sign language','1005436800',1248825600,'dsl',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8607,5,'sgn-es',NULL,'spanish sign language','1005436800',1248825600,'ssp',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8608,5,'sgn-fr',NULL,'french sign language','1005436800',1248825600,'fsl',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8609,5,'sgn-gb',NULL,'british sign language','983491200',1248825600,'bfi',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8610,5,'sgn-gr',NULL,'greek sign language','1005436800',1248825600,'gss',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8611,5,'sgn-ie',NULL,'irish sign language','983491200',1248825600,'isg',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8612,5,'sgn-it',NULL,'italian sign language','1005436800',1248825600,'ise',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8613,5,'sgn-jp',NULL,'japanese sign language','1005436800',1248825600,'jsl',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8614,5,'sgn-mx',NULL,'mexican sign language','1005436800',1248825600,'mfs',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8615,5,'sgn-ni',NULL,'nicaraguan sign language','983491200',1248825600,'ncs',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8616,5,'sgn-nl',NULL,'dutch sign language','1005436800',1248825600,'dse',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8617,5,'sgn-no',NULL,'norwegian sign language','1005436800',1248825600,'nsl',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8618,5,'sgn-pt',NULL,'portuguese sign language','1005436800',1248825600,'psr',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8619,5,'sgn-se',NULL,'swedish sign language','1005436800',1248825600,'swl',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8620,5,'sgn-us',NULL,'american sign language','983491200',1248825600,'ase',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8621,5,'sgn-za',NULL,'south african sign language','1005436800',1248825600,'sfs',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8622,5,'sl-nedis',NULL,'natisone dialect, nadiza dialect','1086048000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8623,5,'sl-rozaj',NULL,'resian, resianic, rezijan','1065657600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8624,5,'sr-cyrl',NULL,'serbian in cyrillic script','1054252800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8625,5,'sr-latn',NULL,'serbian in latin script','1054252800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8626,5,'tg-arab',NULL,'tajik in arabic script','1108598400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8627,5,'tg-cyrl',NULL,'tajik in cyrillic script','1108598400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8628,5,'uz-cyrl',NULL,'uzbek in cyrillic script','1054252800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8629,5,'uz-latn',NULL,'uzbek in latin script','1054252800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8630,5,'yi-latn',NULL,'yiddish, in latin script','1041897600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8631,5,'zh-cmn',NULL,'mandarin chinese','1121385600',1248825600,'cmn',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8632,5,'zh-cmn-hans',NULL,'mandarin chinese (simplified)','1121385600',1248825600,'cmn-hans',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8633,5,'zh-cmn-hant',NULL,'mandarin chinese (traditional)','1121385600',1248825600,'cmn-hant',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8634,5,'zh-gan',NULL,'kan or gan','945475200',1248825600,'gan',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8635,5,'zh-hans',NULL,'simplified chinese','1054252800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8636,5,'zh-hans-cn',NULL,'prc mainland chinese in simplified script','1113350400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8637,5,'zh-hans-hk',NULL,'hong kong chinese in simplified script','1113177600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8638,5,'zh-hans-mo',NULL,'macao chinese in simplified script','1113177600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8639,5,'zh-hans-sg',NULL,'singapore chinese in simplified script','1113177600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8640,5,'zh-hans-tw',NULL,'taiwan chinese in simplified script','1113177600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8641,5,'zh-hant',NULL,'traditional chinese','1054252800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8642,5,'zh-hant-cn',NULL,'prc mainland chinese in traditional script','1113350400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8643,5,'zh-hant-hk',NULL,'hong kong chinese in traditional script','1113177600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8644,5,'zh-hant-mo',NULL,'macao chinese in traditional script','1113177600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8645,5,'zh-hant-sg',NULL,'singapore chinese in traditional script','1113177600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8646,5,'zh-hant-tw',NULL,'taiwan chinese in traditional script','1113177600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8647,5,'zh-wuu',NULL,'shanghaiese or wu','945475200',1248825600,'wuu',NULL,NULL,NULL,NULL,NULL); +COMMIT; ) diff --git a/modules/widget_dao/orm/orm_generator_wrt.h b/modules/widget_dao/orm/orm_generator_wrt.h new file mode 100644 index 0000000..09ac57e --- /dev/null +++ b/modules/widget_dao/orm/orm_generator_wrt.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ORM_GENERATOR_WRT_H +#define ORM_GENERATOR_WRT_H + +#define ORM_GENERATOR_DATABASE_NAME wrt_db_definitions +#include +#undef ORM_GENERATOR_DATABASE_NAME + +#endif diff --git a/modules/widget_dao/orm/version_db b/modules/widget_dao/orm/version_db new file mode 100644 index 0000000..7e20d8d --- /dev/null +++ b/modules/widget_dao/orm/version_db @@ -0,0 +1,5 @@ +SQL( + BEGIN TRANSACTION; + CREATE TABLE DB_CHECKSUM (version INT); + COMMIT; +) diff --git a/modules/widget_dao/orm/wrt_db b/modules/widget_dao/orm/wrt_db new file mode 100644 index 0000000..dc0f27f --- /dev/null +++ b/modules/widget_dao/orm/wrt_db @@ -0,0 +1,359 @@ +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; +) diff --git a/modules/widget_dao/orm/wrt_db_definitions b/modules/widget_dao/orm/wrt_db_definitions new file mode 100644 index 0000000..1e2200e --- /dev/null +++ b/modules/widget_dao/orm/wrt_db_definitions @@ -0,0 +1,7 @@ +DATABASE_START(wrt) + +#include "wrt_db" +#include "iana_db" +#include "version_db" + +DATABASE_END() diff --git a/modules/widget_dao/orm/wrt_db_sql_generator.h b/modules/widget_dao/orm/wrt_db_sql_generator.h new file mode 100644 index 0000000..a4d7da8 --- /dev/null +++ b/modules/widget_dao/orm/wrt_db_sql_generator.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file wrt_db_sql_generator.h + * @author Bartosz Janiak (b.janiak@samsung.com) + * @version 1.0 + * @brief Macro definitions for generating the SQL input file from database definition. + */ + +//Do not include this file directly! It is used only for SQL code generation. + +#include + +#include "wrt_db_definitions" diff --git a/packaging/dpl.spec b/packaging/dpl.spec new file mode 100644 index 0000000..0b043d7 --- /dev/null +++ b/packaging/dpl.spec @@ -0,0 +1,79 @@ +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 + diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..8453ccb --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,38 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Lukasz Marek (l.marek@samsung.com) +# @version 1.0 +# @brief +# + +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) diff --git a/tests/ace/AttributeSetter.cpp b/tests/ace/AttributeSetter.cpp new file mode 100644 index 0000000..18a31f0 --- /dev/null +++ b/tests/ace/AttributeSetter.cpp @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "AttributeSetter.h" + +#include +IMPLEMENT_SINGLETON(AttributeSetter) diff --git a/tests/ace/AttributeSetter.h b/tests/ace/AttributeSetter.h new file mode 100644 index 0000000..20962ae --- /dev/null +++ b/tests/ace/AttributeSetter.h @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file 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 +#include +#include + +#include +#include +#include + +#include +#include + +class AttributeSetter { +public: + typedef std::list ValueList; + typedef std::map AttributeMap; + typedef std::map CollectionHandlerMap; + + typedef std::list 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(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 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 AttributeSetterSingleton; + +#endif // _TEST_ACE_TESTS_ATTRIBUTE_SETTER_ diff --git a/tests/ace/CMakeLists.txt b/tests/ace/CMakeLists.txt new file mode 100644 index 0000000..b65f6bf --- /dev/null +++ b/tests/ace/CMakeLists.txt @@ -0,0 +1,75 @@ +# +#Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author 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) diff --git a/tests/ace/Interfaces.cpp b/tests/ace/Interfaces.cpp new file mode 100644 index 0000000..78ed1d0 --- /dev/null +++ b/tests/ace/Interfaces.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file Interfaces.cpp + * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) + * @version 1.0 + * @brief Stubs used by PolicyInformationPoint.h + */ +#include "Interfaces.h" + +#include + +#include "AttributeSetter.h" + +int WebRuntimeImp::getAttributesValues( + const Request &request, + std::list *attribute) +{ + LogError("Running stub"); + AttributeSetterSingleton::Instance().get(request, attribute); + return 0; +} + +int ResourceInformationImp::getAttributesValues( + const Request &request, + std::list *attribute) +{ + LogError("Running stub"); + AttributeSetterSingleton::Instance().get(request, attribute); + return 0; +} + +int OperationSystemImp::getAttributesValues( + const Request &request, + std::list *attribute) +{ + LogError("Running stub"); + AttributeSetterSingleton::Instance().get(request, attribute); + return 0; +} + +int FunctionParamImpl::getAttributesValues(const Request & /* request*/, + std::list *attributes) +{ + LogError("Running stub"); + FOREACH(iter, *attributes) + { + std::string attributeName = *(iter->first); + + ParamMap::const_iterator i; + std::pair 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; +} + diff --git a/tests/ace/Interfaces.h b/tests/ace/Interfaces.h new file mode 100644 index 0000000..6d769e5 --- /dev/null +++ b/tests/ace/Interfaces.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 +#include +#include +#include + +class Request; + +class WebRuntimeImp : public IWebRuntime { +public: + int getAttributesValues( + const Request &request, + std::list *attribute); + std::string getSessionId(const Request &) { return std::string(); } +}; + +class ResourceInformationImp : public IResourceInformation { +public: + int getAttributesValues( + const Request &request, + std::list *attribute); +}; + +class OperationSystemImp : public IOperationSystem { +public: + int getAttributesValues( + const Request &request, + std::list *attribute); +}; + +class FunctionParamImpl : public IFunctionParam +{ +public: + virtual int getAttributesValues(const Request & /* request*/, + std::list *attributes); + void addAttribute(const std::string &key, + const std::string &value) + { + paramMap.insert(make_pair(key, value)); + } + virtual ~FunctionParamImpl() {} +private: + typedef std::multimap ParamMap; + ParamMap paramMap; +}; + +#endif // _TEST_ACE_TESTS_INTERFACE_H_ diff --git a/tests/ace/PEPSingleton.cpp b/tests/ace/PEPSingleton.cpp new file mode 100644 index 0000000..9551700 --- /dev/null +++ b/tests/ace/PEPSingleton.cpp @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file Interfaces.h + * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) + * @version 1.0 + * @brief Instance of PEP used in tests. + */ +#include "PEPSingleton.h" + +#include +IMPLEMENT_SINGLETON(PolicyEnforcementPoint) + diff --git a/tests/ace/PEPSingleton.h b/tests/ace/PEPSingleton.h new file mode 100644 index 0000000..1dfb912 --- /dev/null +++ b/tests/ace/PEPSingleton.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 +#include + +typedef DPL::Singleton PEPSingleton; + +#endif // _TEST_ACE_TEST_PEPSINGLETON_H_ + diff --git a/tests/ace/TestSuite01.cpp b/tests/ace/TestSuite01.cpp new file mode 100644 index 0000000..1d169ae --- /dev/null +++ b/tests/ace/TestSuite01.cpp @@ -0,0 +1,986 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 + +#include +#include + +#include +#include +#include +#include + +#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); +} + diff --git a/tests/ace/TestSuite02.cpp b/tests/ace/TestSuite02.cpp new file mode 100644 index 0000000..66d79f5 --- /dev/null +++ b/tests/ace/TestSuite02.cpp @@ -0,0 +1,913 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 + +#include +#include + +#include +#include + +#include + +#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((*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); +} + diff --git a/tests/ace/TestSuite03.cpp b/tests/ace/TestSuite03.cpp new file mode 100644 index 0000000..53c86ca --- /dev/null +++ b/tests/ace/TestSuite03.cpp @@ -0,0 +1,533 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 + +#include +#include + +#include +#include +#include + +#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(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(attr)->addValue(&aValue); + DPL::StaticPointerCast(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(a1)); + con.addAttribute(*DPL::StaticPointerCast(a2)); + con.addAttribute(*DPL::StaticPointerCast(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(a1)); + con.addAttribute(*DPL::StaticPointerCast(a2)); + con.addAttribute(*DPL::StaticPointerCast(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(a1)); + con.addAttribute(*DPL::StaticPointerCast(a2)); + con.addAttribute(*DPL::StaticPointerCast(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(a1)); + con.addAttribute(*DPL::StaticPointerCast(a2)); + con.addAttribute(*DPL::StaticPointerCast(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(a1)); + con.addAttribute(*DPL::StaticPointerCast(a2)); + con.addAttribute(*DPL::StaticPointerCast(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(a1)); + con.addAttribute(*DPL::StaticPointerCast(a2)); + con.addAttribute(*DPL::StaticPointerCast(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(a1)); + con.addAttribute(*DPL::StaticPointerCast(a2)); + con.addAttribute(*DPL::StaticPointerCast(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(a1)); + con.addAttribute(*DPL::StaticPointerCast(a2)); + con.addAttribute(*DPL::StaticPointerCast(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(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(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(a1)); + con.addAttribute(*DPL::StaticPointerCast(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(a1)); + con.addAttribute(*DPL::StaticPointerCast(a2)); + con.addAttribute(*DPL::StaticPointerCast(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(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(a4)); + con.addAttribute(*DPL::StaticPointerCast(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(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(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(a2)); + Condition con3(Condition::OR); + con3.addAttribute(*DPL::StaticPointerCast(a3)); + con3.addAttribute(*DPL::StaticPointerCast(a4)); + + con.addCondition(con2); + con.addCondition(con3); + + con.addAttribute(*DPL::StaticPointerCast(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(a2)); + con2.addAttribute(*DPL::StaticPointerCast(a5)); + Condition con3(Condition::AND); + con3.addAttribute(*DPL::StaticPointerCast(a3)); + con3.addAttribute(*DPL::StaticPointerCast(a4)); + Condition con4(Condition::AND); + con4.addAttribute(*DPL::StaticPointerCast(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(a2)); + con2.addAttribute(*DPL::StaticPointerCast(a5)); + Condition con3(Condition::OR); + con3.addAttribute(*DPL::StaticPointerCast(a3)); + con3.addAttribute(*DPL::StaticPointerCast(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(a2)); + con3.addAttribute(*DPL::StaticPointerCast(a3)); + con4.addAttribute(*DPL::StaticPointerCast(a4)); + con5.addAttribute(*DPL::StaticPointerCast(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)); +} diff --git a/tests/ace/TestSuite04.cpp b/tests/ace/TestSuite04.cpp new file mode 100644 index 0000000..4cbdf1c --- /dev/null +++ b/tests/ace/TestSuite04.cpp @@ -0,0 +1,627 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 +#include + +#include +#include + +#include +#include +#include + +#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 &lst){ + return CombinerImpl::denyOverrides(lst); + } + Effect permitOverrides(std::list &lst){ + return CombinerImpl::permitOverrides(lst); + } + Effect firstApplicable(std::list &lst){ + return CombinerImpl::firstApplicable(lst); + } + Effect firstMatchingTarget(std::list &lst){ + return CombinerImpl::firstMatchingTarget(lst); + } +}; + +Effect denyOverridesTest(std::list &lst) { + WTF impl; + return impl.denyOverrides(lst); +} + +Effect permitOverridesTest(std::list &lst) { + WTF impl; + return impl.permitOverrides(lst); +} + +Effect firstApplicableTest(std::list &lst) { + WTF impl; + return impl.firstApplicable(lst); +} + +Effect firstMatchingTargetTest(std::list &lst) { + WTF impl; + return impl.firstMatchingTarget(lst); +} + +TESTSUITE04(00_denyOverrides){ + std::list * effectList = new std::list (); + 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 * effectList = new std::list (); + 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 * effectList = new std::list (); + 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 * effectList = new std::list (); + + 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 * effectList = new std::list (); + 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 * effectList = new std::list (); + 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 * effectList = new std::list (); + + 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 * effectList = new std::list (); + 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 * effectList = new std::list (); + effectList->push_back(Inapplicable); + + Effect eff = denyOverridesTest(*effectList); + RUNNER_ASSERT(assertEffectEqual(eff, Inapplicable)); +} + +TESTSUITE04(09_denyOverrides){ + std::list * effectList = new std::list (); + Effect eff = denyOverridesTest(*effectList); + RUNNER_ASSERT(assertEffectEqual(eff, Inapplicable)); +} + +TESTSUITE04(10_denyOverrides){ + std::list * effectList = new std::list (); + 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 * effectList = new std::list (); + 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 * effectList = new std::list (); + 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 * effectList = new std::list (); + 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 * effectList = new std::list (); + effectList->push_back(Error); + effectList->push_back(Inapplicable); + + Effect eff = denyOverridesTest(*effectList); + RUNNER_ASSERT(assertEffectEqual(eff, Error)); +} + +TESTSUITE04(15_denyOverrides){ + std::list * effectList = new std::list (); + effectList->push_back(Inapplicable); + effectList->push_back(Error); + + Effect eff = denyOverridesTest(*effectList); + RUNNER_ASSERT(assertEffectEqual(eff, Error)); +} + +TESTSUITE04(16_permitOverrides){ + std::list * effectList = new std::list (); + 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 * effectList = new std::list (); + 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 * effectList = new std::list (); + 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 * effectList = new std::list (); + 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 * effectList = new std::list (); + 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 * effectList = new std::list (); + effectList->push_back(Deny); + effectList->push_back(Inapplicable); + + Effect eff = permitOverridesTest(*effectList); + RUNNER_ASSERT(assertEffectEqual(eff, Deny)); +} + +TESTSUITE04(22_permitOverrides){ + std::list * effectList = new std::list (); + effectList->push_back(Inapplicable); + + Effect eff = permitOverridesTest(*effectList); + RUNNER_ASSERT(assertEffectEqual(eff, Inapplicable)); +} + +TESTSUITE04(23_permitOverrides){ + std::list * effectList = new std::list (); + + Effect eff = permitOverridesTest(*effectList); + RUNNER_ASSERT(assertEffectEqual(eff, Inapplicable)); +} + +TESTSUITE04(24_permitOverrides){ + std::list * effectList = new std::list (); + 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 * effectList = new std::list (); + 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 * effectList = new std::list (); + 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 * effectList = new std::list (); + effectList->push_back(Error); + Effect eff = permitOverridesTest(*effectList); + RUNNER_ASSERT(assertEffectEqual(eff, Error)); +} + +TESTSUITE04(28_firstApplicable){ + std::list * effectList = new std::list (); + 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 * effectList = new std::list (); + 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 * effectList = new std::list (); + 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 * effectList = new std::list (); + 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 * effectList = new std::list (); + 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 * effectList = new std::list (); + 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 * effectList = new std::list (); + + Effect eff = firstApplicableTest(*effectList); + RUNNER_ASSERT(assertEffectEqual(eff, Inapplicable)); +} + +TESTSUITE04(35_firstApplicable){ + std::list * effectList = new std::list (); + 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 * effectList = new std::list (); + 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 * effectList = new std::list (); + effectList->push_back(Error); + + Effect eff = firstApplicableTest(*effectList); + RUNNER_ASSERT(assertEffectEqual(eff, Error)); +} + +TESTSUITE04(38_firstMatching){ + std::list * effectList = new std::list (); + 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 * effectList = new std::list (); + 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 * effectList = new std::list (); + effectList->push_back(Deny); + effectList->push_back(Inapplicable); + + Effect eff = firstMatchingTargetTest(*effectList); + RUNNER_ASSERT(assertEffectEqual(eff, Deny)); +} + +TESTSUITE04(39b_firstMatching){ + std::list * effectList = new std::list (); + effectList->push_back(Permit); + + Effect eff = firstMatchingTargetTest(*effectList); + RUNNER_ASSERT(assertEffectEqual(eff, Permit)); +} + +TESTSUITE04(40_firstMatching){ + std::list * effectList = new std::list (); + 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 * effectList = new std::list (); + + Effect eff = firstMatchingTargetTest(*effectList); + RUNNER_ASSERT(assertEffectEqual(eff, Inapplicable)); +} + +TESTSUITE04(42_firstMatching){ + std::list * effectList = new std::list (); + effectList->push_back(Inapplicable); + + Effect eff = firstMatchingTargetTest(*effectList); + RUNNER_ASSERT(assertEffectEqual(eff, Inapplicable)); +} + +TESTSUITE04(43_firstMatching){ + + std::list * effectList = new std::list (); + 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 * effectList = new std::list (); + 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 * effectList = new std::list (); + 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 * effectList = new std::list (); + effectList->push_back(Error); + + Effect eff = firstMatchingTargetTest(*effectList); + RUNNER_ASSERT(assertEffectEqual(eff, Error)); +} diff --git a/tests/ace/TestSuite05.cpp b/tests/ace/TestSuite05.cpp new file mode 100644 index 0000000..57eb061 --- /dev/null +++ b/tests/ace/TestSuite05.cpp @@ -0,0 +1,620 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 +#include +#include +#include + +#include + +#include +#include + +#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))); +} + diff --git a/tests/ace/TestSuite06.cpp b/tests/ace/TestSuite06.cpp new file mode 100644 index 0000000..7db0139 --- /dev/null +++ b/tests/ace/TestSuite06.cpp @@ -0,0 +1,1610 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 +#include + +#include +#include + +#include +#include +#include +#include + +#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* expected, + std::list* allRules) +{ + if (allRules->empty() && expected->empty()) + { + return true; + } + + std::list::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* 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 > *expected, + std::map* allRules) +{ + std::list< std::pair >::iterator itE; + std::map::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 > * actual, + std::map* 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* rSettings, + std::string res, + Preference pref) +{ + std::map::iterator iter = rSettings->find(res); + + if (iter != rSettings->end() && iter->second ==pref) + { + return true; + } + + return false; +} + + +bool UserSettingEqual(std::list* 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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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 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 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 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 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 permissionsL; + + permissionsL.push_back( + PermissionTriple(suba, resa, Preference::PREFERENCE_DENY)); + permissionsL.push_back( + PermissionTriple(subb, resb, Preference::PREFERENCE_PERMIT)); + + SettingsLogic::setWidgetDevCapSettings(permissionsL); + + std::list 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 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 userSettings; + SettingsLogic::getWidgetDevCapSettings(&userSettings); + RUNNER_ASSERT(UserSettingsAgreed(&permissionsL, &userSettings)); +} + +TESTSUITE06(32){ + CLEANENV; + //empty list -- TODO what is it testing? + std::list permissionsL; + + std::list 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 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 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 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 >* resourcesL = + new std::list< std::pair >(); + + resourcesL->push_back(make_pair(&resa, Preference::PREFERENCE_DENY)); + resourcesL->push_back(make_pair(&resb, Preference::PREFERENCE_PERMIT)); + + SettingsLogic::setAllDevCapSettings (*resourcesL); + + std::map 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(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(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(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(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(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(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(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(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(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(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 resourceSettings; + SettingsLogic::getDevCapSettings(&resourceSettings); + + RUNNER_ASSERT( + ResourceSettingEqual( + &resourceSettings, + res, + Preference::PREFERENCE_PERMIT)); +} + +//void AceDAOTester::test48(){ +// SettingsLogic::setResourceSetting(NULL, PERMIT); +// std::map* 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 > *resourcesL = new + std::list< std::pair >(); + + resourcesL->push_back(make_pair(&resb, Preference::PREFERENCE_PERMIT)); + + SettingsLogic::setAllDevCapSettings (*resourcesL); + + std::map 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 permissionsL; + + permissionsL.push_back(PermissionTriple(subb, resb, Preference::PREFERENCE_PERMIT)); + + SettingsLogic::setWidgetDevCapSettings(permissionsL); + + std::list 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 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 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(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(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(atr)->addValue(&aValue1); +// DPL::StaticPointerCast(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(atr1)->addValue(&aValue1); +// DPL::StaticPointerCast(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(attr)->addValue(&tmpValue); +// return attr; +//} + diff --git a/tests/ace/TestSuite07.cpp b/tests/ace/TestSuite07.cpp new file mode 100644 index 0000000..b276a50 --- /dev/null +++ b/tests/ace/TestSuite07.cpp @@ -0,0 +1,287 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 +#include + +#include +#include + +#include +#include + +#include + +#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 "<::const_iterator it = getPolicyFiles().begin(); it!=getPolicyFiles().end(); ++it){ + if( *it == expected ){ + found = true; + break; + } + } + + LogDebug("assert Policy in a list result: "<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"); +} diff --git a/tests/ace/ace_tests.cpp b/tests/ace/ace_tests.cpp new file mode 100644 index 0000000..8202ac0 --- /dev/null +++ b/tests/ace/ace_tests.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file main.cpp + * @author Bartlomiej Grzelewski + * @version 1.0 + * @brief This file is the implementation file of main + */ +#include + +#include +#include + +#include + +#include + +#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; +} + diff --git a/tests/ace/loop_control.cpp b/tests/ace/loop_control.cpp new file mode 100644 index 0000000..f4cfecf --- /dev/null +++ b/tests/ace/loop_control.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file loop_control.cpp + * @author Jaroslaw Osmanski (j.osmanski@samsung.com) + * @version 1.0 + * @brief This is implementation of EFL version of loop control + */ + +#include + +#include + +#include +#include + +#include + +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 diff --git a/tests/ace/loop_control.h b/tests/ace/loop_control.h new file mode 100644 index 0000000..30aa6e8 --- /dev/null +++ b/tests/ace/loop_control.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file loop_control.cpp + * @author Jaroslaw Osmanski (j.osmanski@samsung.com) + * @version 1.0 + * @brief This file is the definitions of loop controlling utilities + */ + + +#ifndef LOOP_CONTROL_H_ +#define LOOP_CONTROL_H_ + +namespace LoopControl +{ + +void init_loop(int argc, char *argv[]); +void wait_for_wrt_init(); +void finish_wait_for_wrt_init(); +void quit_loop(); + +void wrt_start_loop(); +void wrt_end_loop(); + +void *abstract_window(); + +} + +#endif /* LOOP_CONTROL_H_ */ diff --git a/tests/ace/test-configuration/CMTest/CMakeLists.txt b/tests/ace/test-configuration/CMTest/CMakeLists.txt new file mode 100644 index 0000000..d186839 --- /dev/null +++ b/tests/ace/test-configuration/CMTest/CMakeLists.txt @@ -0,0 +1,26 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +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) + diff --git a/tests/ace/test-configuration/CMTest/active/CMakeLists.txt b/tests/ace/test-configuration/CMTest/active/CMakeLists.txt new file mode 100644 index 0000000..baefacf --- /dev/null +++ b/tests/ace/test-configuration/CMTest/active/CMakeLists.txt @@ -0,0 +1,21 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +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 + ) + diff --git a/tests/ace/test-configuration/CMTest/active/bondixml.dtd b/tests/ace/test-configuration/CMTest/active/bondixml.dtd new file mode 100644 index 0000000..42a6c7b --- /dev/null +++ b/tests/ace/test-configuration/CMTest/active/bondixml.dtd @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/ace/test-configuration/CMTest/active/pms_general-test.xml b/tests/ace/test-configuration/CMTest/active/pms_general-test.xml new file mode 100644 index 0000000..ac55f33 --- /dev/null +++ b/tests/ace/test-configuration/CMTest/active/pms_general-test.xml @@ -0,0 +1,2510 @@ + + + + + + + + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + asdfkjlhxvczxnbcvnjahfjhsdfklahfdas + + + +

PValue

QValue Gvalue laj? +
+ + + modulus + + + exponent + + +
+ + Subject name + SKI + +
+
+ + + + + + + + + subject + + + + + + + + + + + + + + + + resource + + + + + + + + + + + + + + + resource + + + + + + + + + + subject3 + + + + + + + + + + + resource2 + + + + + + + + + resource2 + + + + + + + + + subject4 + + + + + + + + resource4 + + + + + + + + + + + + + + + + + + + subject5 + + + + + + + resource5 + + + + + + + + + + resource6 + + + + + + + + + + + + + + + + + + resource7 + + + + + + + + + + + + + + + + resource7 + + + + + + + + + + + + + + + + resource7 + + + + + + + + + + + + + + + + + s8a + + + + + + r8 + + + + + + + + r8 + + + + + + + + + + s8b + + + + + + r8 + + + + + + + + r8 + + + + + + + + + + s8c + + + + + + r8 + + + + + + + + + + + + + + s9a + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9b + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9c + + + + + + r9 + + + + + + + + + r9 + + + + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9d + + + + + + r9 + + + + + + + + r9 + + + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9e + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9f + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9g + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9h + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s10a + + + + + + r10 + + + + + + + + r10 + + + + + + + + + + s10b + + + + + + r10 + + + + + + + + r10 + + + + + + + + + + s10c + + + + + + r10 + + + + + + + + r10 + + + + + + + + + + + + + + + + s13 + + + + + + device:pim.contacts.read + + + + + + + + + + + + + s14 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s16 + + + + + + + + + + + + + + + + + + + + + subject4 + + + + + + + + resource4 + + + + + + + + + + + subject5 + + + + + + + + resource4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s19.1 + + + + + + + + resource4 + + + + + + + + + + s19.2 + + + + + + + + resource4 + + + + + + + + + + + + + s20.1 + + + + + + + + resource4 + + + + + + + + + + s20.2 + + + + + + + + resource4 + + + + + + + + + + + + + + s21 + + + + + + + + + + + + + + + + + + s23 + + + + + + + + + + + + + + + + + + + + s24 + + + + + + + + + + + + + + + + + + s25.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + s25.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + s25.3 + + + + + + + + + + + + + + + + + + + + + + + + + + + s25.4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s26.1 + + + + + + + + + + + + + + + + + + + + + + + + + + s26.2 + + + + + + + + + + + + + + + + + + + + + + + + + + s26.3 + + + + + + + + + + + + + + + + + + + + + + + + + + s26.4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + s27.1 + + + + + + + + + + + + + + + + + + + + + + + + + s27.2 + + + + + + + + + + + + + + + + + + + + + + + + + s27.3 + + + + + + + + + + + + + + + + + + + + + + + + + + + s27.4 + + + + + + + + + + + + + + + + + + + + + + + + + + + s28 + + + + + + + + + + + + + + + + + + + + + + + + + + s29 + + + + + + + + + + + + + + + + + + + + + + + + + s30.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s30.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s30.3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s30.4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s31.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s31.2.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s31.2.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s31.3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s32.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s32.2.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s32.2.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s32.3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s33.1 + + + + + + + + + + + + + + + + + + + + + + + + + + s33.2 + + + + + + + + + + + + + + + + + + + + + + + + + + s33.3 + + + + + + + + + + + + + + + + + + + + + + + + + + s34.1 + + + + + + + + + + + + + + + + + + + + + + + + s34.2 + + + + + + + + + + + + + + + + + + + + + + + + + + s35.1 + + + + + + + + + + + + + + + + + + + + + + + + + + s35.2 + + + + + + + + + + + + + + + + + + + + + + + + org.tizen.widget.analogclock + + + + + + + + + + + + + + + + + s36 + + + + + + + + + + + + + + + + + + + + + + + s37 + + + + + + device:pim.contacts.read + + + + + + + + + + + + + s38 + + + + + + device:pim.contacts.read + + + + + + + + + s38.4 + + + + + + device:pim.contacts.read + + + + + + + + + + + + s39 + + + + + + device:pim.contacts.read + + + + + + + + + s39.4 + + + + + + device:pim.contacts.read + + + + + + + + + + + + + + + s40 + + + + + + r40 + + + + + + + r40 + + + + + + + + + + + + s41 + + + + + + r41 + + + + + r41.2 + + + + + + + + + + + + + s42.1 + + + + + + r42.1 + + + + + r42.1 + + + + + + + + + + + + + s42.2 + + + + + + r42.2 + + + + + r42.2 + + + + + + + + + + + + s43.1 + + + + + + r43.1 + + + + + + + r43.1 + + + + + + + + + + + s43.2 + + + + + + r43.2 + + + + + + + r43.2 + + + + + + + + + + + s44.1 + + + + + + r44.1 + + + + + + + r44.1 + + + + + + + + + + + s44.2 + + + + + + r44.2 + + + + + + + r44.2 + + + + + + + + + + + + + s45.1 + + + + + + r45.1 + + + + + r45.1 + + + + + + + + + + + + s45.2 + + + + + + r45.2 + + + + + r45.2 + + + + + + + + + + + + + s46.1 + + + + + + r46.1 + + + + + r46.1 + + + + + + + + + + + + s46.2 + + + + + + r46.2 + + + + + r46.2 + + + + + + + + + + + + + s47.1 + + + + + + r47.1 + + + + + r47.1 + + + + + + + + + + + s47.2 + + + + + + r47.2 + + + + + r47.2 + + + + + + + + + + + +s48 + + + + + + + + + + + + + + + + +
diff --git a/tests/ace/test-configuration/CMTest/pms_config.xml b/tests/ace/test-configuration/CMTest/pms_config.xml new file mode 100644 index 0000000..fc9b0dc --- /dev/null +++ b/tests/ace/test-configuration/CMTest/pms_config.xml @@ -0,0 +1,10 @@ + + + + /usr/etc/ace/CMTest/active + + pms_general-test.xml + + + + diff --git a/tests/ace/test-configuration/CMTest/pms_general-test.xml b/tests/ace/test-configuration/CMTest/pms_general-test.xml new file mode 100644 index 0000000..ac55f33 --- /dev/null +++ b/tests/ace/test-configuration/CMTest/pms_general-test.xml @@ -0,0 +1,2510 @@ + + + + + + + + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + asdfkjlhxvczxnbcvnjahfjhsdfklahfdas + + + +

PValue

QValue Gvalue laj? +
+ + + modulus + + + exponent + + +
+ + Subject name + SKI + +
+
+ + + + + + + + + subject + + + + + + + + + + + + + + + + resource + + + + + + + + + + + + + + + resource + + + + + + + + + + subject3 + + + + + + + + + + + resource2 + + + + + + + + + resource2 + + + + + + + + + subject4 + + + + + + + + resource4 + + + + + + + + + + + + + + + + + + + subject5 + + + + + + + resource5 + + + + + + + + + + resource6 + + + + + + + + + + + + + + + + + + resource7 + + + + + + + + + + + + + + + + resource7 + + + + + + + + + + + + + + + + resource7 + + + + + + + + + + + + + + + + + s8a + + + + + + r8 + + + + + + + + r8 + + + + + + + + + + s8b + + + + + + r8 + + + + + + + + r8 + + + + + + + + + + s8c + + + + + + r8 + + + + + + + + + + + + + + s9a + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9b + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9c + + + + + + r9 + + + + + + + + + r9 + + + + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9d + + + + + + r9 + + + + + + + + r9 + + + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9e + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9f + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9g + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9h + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s10a + + + + + + r10 + + + + + + + + r10 + + + + + + + + + + s10b + + + + + + r10 + + + + + + + + r10 + + + + + + + + + + s10c + + + + + + r10 + + + + + + + + r10 + + + + + + + + + + + + + + + + s13 + + + + + + device:pim.contacts.read + + + + + + + + + + + + + s14 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s16 + + + + + + + + + + + + + + + + + + + + + subject4 + + + + + + + + resource4 + + + + + + + + + + + subject5 + + + + + + + + resource4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s19.1 + + + + + + + + resource4 + + + + + + + + + + s19.2 + + + + + + + + resource4 + + + + + + + + + + + + + s20.1 + + + + + + + + resource4 + + + + + + + + + + s20.2 + + + + + + + + resource4 + + + + + + + + + + + + + + s21 + + + + + + + + + + + + + + + + + + s23 + + + + + + + + + + + + + + + + + + + + s24 + + + + + + + + + + + + + + + + + + s25.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + s25.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + s25.3 + + + + + + + + + + + + + + + + + + + + + + + + + + + s25.4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s26.1 + + + + + + + + + + + + + + + + + + + + + + + + + + s26.2 + + + + + + + + + + + + + + + + + + + + + + + + + + s26.3 + + + + + + + + + + + + + + + + + + + + + + + + + + s26.4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + s27.1 + + + + + + + + + + + + + + + + + + + + + + + + + s27.2 + + + + + + + + + + + + + + + + + + + + + + + + + s27.3 + + + + + + + + + + + + + + + + + + + + + + + + + + + s27.4 + + + + + + + + + + + + + + + + + + + + + + + + + + + s28 + + + + + + + + + + + + + + + + + + + + + + + + + + s29 + + + + + + + + + + + + + + + + + + + + + + + + + s30.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s30.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s30.3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s30.4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s31.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s31.2.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s31.2.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s31.3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s32.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s32.2.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s32.2.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s32.3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s33.1 + + + + + + + + + + + + + + + + + + + + + + + + + + s33.2 + + + + + + + + + + + + + + + + + + + + + + + + + + s33.3 + + + + + + + + + + + + + + + + + + + + + + + + + + s34.1 + + + + + + + + + + + + + + + + + + + + + + + + s34.2 + + + + + + + + + + + + + + + + + + + + + + + + + + s35.1 + + + + + + + + + + + + + + + + + + + + + + + + + + s35.2 + + + + + + + + + + + + + + + + + + + + + + + + org.tizen.widget.analogclock + + + + + + + + + + + + + + + + + s36 + + + + + + + + + + + + + + + + + + + + + + + s37 + + + + + + device:pim.contacts.read + + + + + + + + + + + + + s38 + + + + + + device:pim.contacts.read + + + + + + + + + s38.4 + + + + + + device:pim.contacts.read + + + + + + + + + + + + s39 + + + + + + device:pim.contacts.read + + + + + + + + + s39.4 + + + + + + device:pim.contacts.read + + + + + + + + + + + + + + + s40 + + + + + + r40 + + + + + + + r40 + + + + + + + + + + + + s41 + + + + + + r41 + + + + + r41.2 + + + + + + + + + + + + + s42.1 + + + + + + r42.1 + + + + + r42.1 + + + + + + + + + + + + + s42.2 + + + + + + r42.2 + + + + + r42.2 + + + + + + + + + + + + s43.1 + + + + + + r43.1 + + + + + + + r43.1 + + + + + + + + + + + s43.2 + + + + + + r43.2 + + + + + + + r43.2 + + + + + + + + + + + s44.1 + + + + + + r44.1 + + + + + + + r44.1 + + + + + + + + + + + s44.2 + + + + + + r44.2 + + + + + + + r44.2 + + + + + + + + + + + + + s45.1 + + + + + + r45.1 + + + + + r45.1 + + + + + + + + + + + + s45.2 + + + + + + r45.2 + + + + + r45.2 + + + + + + + + + + + + + s46.1 + + + + + + r46.1 + + + + + r46.1 + + + + + + + + + + + + s46.2 + + + + + + r46.2 + + + + + r46.2 + + + + + + + + + + + + + s47.1 + + + + + + r47.1 + + + + + r47.1 + + + + + + + + + + + s47.2 + + + + + + r47.2 + + + + + r47.2 + + + + + + + + + + + +s48 + + + + + + + + + + + + + + + + +
diff --git a/tests/ace/test-configuration/CMTest/policyTest1.xml b/tests/ace/test-configuration/CMTest/policyTest1.xml new file mode 100644 index 0000000..ac55f33 --- /dev/null +++ b/tests/ace/test-configuration/CMTest/policyTest1.xml @@ -0,0 +1,2510 @@ + + + + + + + + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + asdfkjlhxvczxnbcvnjahfjhsdfklahfdas + + + +

PValue

QValue Gvalue laj? +
+ + + modulus + + + exponent + + +
+ + Subject name + SKI + +
+
+ + + + + + + + + subject + + + + + + + + + + + + + + + + resource + + + + + + + + + + + + + + + resource + + + + + + + + + + subject3 + + + + + + + + + + + resource2 + + + + + + + + + resource2 + + + + + + + + + subject4 + + + + + + + + resource4 + + + + + + + + + + + + + + + + + + + subject5 + + + + + + + resource5 + + + + + + + + + + resource6 + + + + + + + + + + + + + + + + + + resource7 + + + + + + + + + + + + + + + + resource7 + + + + + + + + + + + + + + + + resource7 + + + + + + + + + + + + + + + + + s8a + + + + + + r8 + + + + + + + + r8 + + + + + + + + + + s8b + + + + + + r8 + + + + + + + + r8 + + + + + + + + + + s8c + + + + + + r8 + + + + + + + + + + + + + + s9a + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9b + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9c + + + + + + r9 + + + + + + + + + r9 + + + + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9d + + + + + + r9 + + + + + + + + r9 + + + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9e + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9f + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9g + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9h + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s10a + + + + + + r10 + + + + + + + + r10 + + + + + + + + + + s10b + + + + + + r10 + + + + + + + + r10 + + + + + + + + + + s10c + + + + + + r10 + + + + + + + + r10 + + + + + + + + + + + + + + + + s13 + + + + + + device:pim.contacts.read + + + + + + + + + + + + + s14 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s16 + + + + + + + + + + + + + + + + + + + + + subject4 + + + + + + + + resource4 + + + + + + + + + + + subject5 + + + + + + + + resource4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s19.1 + + + + + + + + resource4 + + + + + + + + + + s19.2 + + + + + + + + resource4 + + + + + + + + + + + + + s20.1 + + + + + + + + resource4 + + + + + + + + + + s20.2 + + + + + + + + resource4 + + + + + + + + + + + + + + s21 + + + + + + + + + + + + + + + + + + s23 + + + + + + + + + + + + + + + + + + + + s24 + + + + + + + + + + + + + + + + + + s25.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + s25.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + s25.3 + + + + + + + + + + + + + + + + + + + + + + + + + + + s25.4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s26.1 + + + + + + + + + + + + + + + + + + + + + + + + + + s26.2 + + + + + + + + + + + + + + + + + + + + + + + + + + s26.3 + + + + + + + + + + + + + + + + + + + + + + + + + + s26.4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + s27.1 + + + + + + + + + + + + + + + + + + + + + + + + + s27.2 + + + + + + + + + + + + + + + + + + + + + + + + + s27.3 + + + + + + + + + + + + + + + + + + + + + + + + + + + s27.4 + + + + + + + + + + + + + + + + + + + + + + + + + + + s28 + + + + + + + + + + + + + + + + + + + + + + + + + + s29 + + + + + + + + + + + + + + + + + + + + + + + + + s30.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s30.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s30.3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s30.4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s31.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s31.2.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s31.2.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s31.3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s32.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s32.2.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s32.2.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s32.3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s33.1 + + + + + + + + + + + + + + + + + + + + + + + + + + s33.2 + + + + + + + + + + + + + + + + + + + + + + + + + + s33.3 + + + + + + + + + + + + + + + + + + + + + + + + + + s34.1 + + + + + + + + + + + + + + + + + + + + + + + + s34.2 + + + + + + + + + + + + + + + + + + + + + + + + + + s35.1 + + + + + + + + + + + + + + + + + + + + + + + + + + s35.2 + + + + + + + + + + + + + + + + + + + + + + + + org.tizen.widget.analogclock + + + + + + + + + + + + + + + + + s36 + + + + + + + + + + + + + + + + + + + + + + + s37 + + + + + + device:pim.contacts.read + + + + + + + + + + + + + s38 + + + + + + device:pim.contacts.read + + + + + + + + + s38.4 + + + + + + device:pim.contacts.read + + + + + + + + + + + + s39 + + + + + + device:pim.contacts.read + + + + + + + + + s39.4 + + + + + + device:pim.contacts.read + + + + + + + + + + + + + + + s40 + + + + + + r40 + + + + + + + r40 + + + + + + + + + + + + s41 + + + + + + r41 + + + + + r41.2 + + + + + + + + + + + + + s42.1 + + + + + + r42.1 + + + + + r42.1 + + + + + + + + + + + + + s42.2 + + + + + + r42.2 + + + + + r42.2 + + + + + + + + + + + + s43.1 + + + + + + r43.1 + + + + + + + r43.1 + + + + + + + + + + + s43.2 + + + + + + r43.2 + + + + + + + r43.2 + + + + + + + + + + + s44.1 + + + + + + r44.1 + + + + + + + r44.1 + + + + + + + + + + + s44.2 + + + + + + r44.2 + + + + + + + r44.2 + + + + + + + + + + + + + s45.1 + + + + + + r45.1 + + + + + r45.1 + + + + + + + + + + + + s45.2 + + + + + + r45.2 + + + + + r45.2 + + + + + + + + + + + + + s46.1 + + + + + + r46.1 + + + + + r46.1 + + + + + + + + + + + + s46.2 + + + + + + r46.2 + + + + + r46.2 + + + + + + + + + + + + + s47.1 + + + + + + r47.1 + + + + + r47.1 + + + + + + + + + + + s47.2 + + + + + + r47.2 + + + + + r47.2 + + + + + + + + + + + +s48 + + + + + + + + + + + + + + + + +
diff --git a/tests/ace/test-configuration/CMTest/policyTest2.xml b/tests/ace/test-configuration/CMTest/policyTest2.xml new file mode 100644 index 0000000..ac55f33 --- /dev/null +++ b/tests/ace/test-configuration/CMTest/policyTest2.xml @@ -0,0 +1,2510 @@ + + + + + + + + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + asdfkjlhxvczxnbcvnjahfjhsdfklahfdas + + + +

PValue

QValue Gvalue laj? +
+ + + modulus + + + exponent + + +
+ + Subject name + SKI + +
+
+ + + + + + + + + subject + + + + + + + + + + + + + + + + resource + + + + + + + + + + + + + + + resource + + + + + + + + + + subject3 + + + + + + + + + + + resource2 + + + + + + + + + resource2 + + + + + + + + + subject4 + + + + + + + + resource4 + + + + + + + + + + + + + + + + + + + subject5 + + + + + + + resource5 + + + + + + + + + + resource6 + + + + + + + + + + + + + + + + + + resource7 + + + + + + + + + + + + + + + + resource7 + + + + + + + + + + + + + + + + resource7 + + + + + + + + + + + + + + + + + s8a + + + + + + r8 + + + + + + + + r8 + + + + + + + + + + s8b + + + + + + r8 + + + + + + + + r8 + + + + + + + + + + s8c + + + + + + r8 + + + + + + + + + + + + + + s9a + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9b + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9c + + + + + + r9 + + + + + + + + + r9 + + + + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9d + + + + + + r9 + + + + + + + + r9 + + + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9e + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9f + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9g + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9h + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s10a + + + + + + r10 + + + + + + + + r10 + + + + + + + + + + s10b + + + + + + r10 + + + + + + + + r10 + + + + + + + + + + s10c + + + + + + r10 + + + + + + + + r10 + + + + + + + + + + + + + + + + s13 + + + + + + device:pim.contacts.read + + + + + + + + + + + + + s14 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s16 + + + + + + + + + + + + + + + + + + + + + subject4 + + + + + + + + resource4 + + + + + + + + + + + subject5 + + + + + + + + resource4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s19.1 + + + + + + + + resource4 + + + + + + + + + + s19.2 + + + + + + + + resource4 + + + + + + + + + + + + + s20.1 + + + + + + + + resource4 + + + + + + + + + + s20.2 + + + + + + + + resource4 + + + + + + + + + + + + + + s21 + + + + + + + + + + + + + + + + + + s23 + + + + + + + + + + + + + + + + + + + + s24 + + + + + + + + + + + + + + + + + + s25.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + s25.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + s25.3 + + + + + + + + + + + + + + + + + + + + + + + + + + + s25.4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s26.1 + + + + + + + + + + + + + + + + + + + + + + + + + + s26.2 + + + + + + + + + + + + + + + + + + + + + + + + + + s26.3 + + + + + + + + + + + + + + + + + + + + + + + + + + s26.4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + s27.1 + + + + + + + + + + + + + + + + + + + + + + + + + s27.2 + + + + + + + + + + + + + + + + + + + + + + + + + s27.3 + + + + + + + + + + + + + + + + + + + + + + + + + + + s27.4 + + + + + + + + + + + + + + + + + + + + + + + + + + + s28 + + + + + + + + + + + + + + + + + + + + + + + + + + s29 + + + + + + + + + + + + + + + + + + + + + + + + + s30.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s30.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s30.3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s30.4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s31.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s31.2.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s31.2.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s31.3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s32.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s32.2.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s32.2.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s32.3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s33.1 + + + + + + + + + + + + + + + + + + + + + + + + + + s33.2 + + + + + + + + + + + + + + + + + + + + + + + + + + s33.3 + + + + + + + + + + + + + + + + + + + + + + + + + + s34.1 + + + + + + + + + + + + + + + + + + + + + + + + s34.2 + + + + + + + + + + + + + + + + + + + + + + + + + + s35.1 + + + + + + + + + + + + + + + + + + + + + + + + + + s35.2 + + + + + + + + + + + + + + + + + + + + + + + + org.tizen.widget.analogclock + + + + + + + + + + + + + + + + + s36 + + + + + + + + + + + + + + + + + + + + + + + s37 + + + + + + device:pim.contacts.read + + + + + + + + + + + + + s38 + + + + + + device:pim.contacts.read + + + + + + + + + s38.4 + + + + + + device:pim.contacts.read + + + + + + + + + + + + s39 + + + + + + device:pim.contacts.read + + + + + + + + + s39.4 + + + + + + device:pim.contacts.read + + + + + + + + + + + + + + + s40 + + + + + + r40 + + + + + + + r40 + + + + + + + + + + + + s41 + + + + + + r41 + + + + + r41.2 + + + + + + + + + + + + + s42.1 + + + + + + r42.1 + + + + + r42.1 + + + + + + + + + + + + + s42.2 + + + + + + r42.2 + + + + + r42.2 + + + + + + + + + + + + s43.1 + + + + + + r43.1 + + + + + + + r43.1 + + + + + + + + + + + s43.2 + + + + + + r43.2 + + + + + + + r43.2 + + + + + + + + + + + s44.1 + + + + + + r44.1 + + + + + + + r44.1 + + + + + + + + + + + s44.2 + + + + + + r44.2 + + + + + + + r44.2 + + + + + + + + + + + + + s45.1 + + + + + + r45.1 + + + + + r45.1 + + + + + + + + + + + + s45.2 + + + + + + r45.2 + + + + + r45.2 + + + + + + + + + + + + + s46.1 + + + + + + r46.1 + + + + + r46.1 + + + + + + + + + + + + s46.2 + + + + + + r46.2 + + + + + r46.2 + + + + + + + + + + + + + s47.1 + + + + + + r47.1 + + + + + r47.1 + + + + + + + + + + + s47.2 + + + + + + r47.2 + + + + + r47.2 + + + + + + + + + + + +s48 + + + + + + + + + + + + + + + + +
diff --git a/tests/ace/test-configuration/CMTest/policyTest3.xml b/tests/ace/test-configuration/CMTest/policyTest3.xml new file mode 100644 index 0000000..ac55f33 --- /dev/null +++ b/tests/ace/test-configuration/CMTest/policyTest3.xml @@ -0,0 +1,2510 @@ + + + + + + + + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + + dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK... + + + asdfkjlhxvczxnbcvnjahfjhsdfklahfdas + + + +

PValue

QValue Gvalue laj? +
+ + + modulus + + + exponent + + +
+ + Subject name + SKI + +
+
+ + + + + + + + + subject + + + + + + + + + + + + + + + + resource + + + + + + + + + + + + + + + resource + + + + + + + + + + subject3 + + + + + + + + + + + resource2 + + + + + + + + + resource2 + + + + + + + + + subject4 + + + + + + + + resource4 + + + + + + + + + + + + + + + + + + + subject5 + + + + + + + resource5 + + + + + + + + + + resource6 + + + + + + + + + + + + + + + + + + resource7 + + + + + + + + + + + + + + + + resource7 + + + + + + + + + + + + + + + + resource7 + + + + + + + + + + + + + + + + + s8a + + + + + + r8 + + + + + + + + r8 + + + + + + + + + + s8b + + + + + + r8 + + + + + + + + r8 + + + + + + + + + + s8c + + + + + + r8 + + + + + + + + + + + + + + s9a + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9b + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9c + + + + + + r9 + + + + + + + + + r9 + + + + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9d + + + + + + r9 + + + + + + + + r9 + + + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9e + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9f + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9g + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9h + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s10a + + + + + + r10 + + + + + + + + r10 + + + + + + + + + + s10b + + + + + + r10 + + + + + + + + r10 + + + + + + + + + + s10c + + + + + + r10 + + + + + + + + r10 + + + + + + + + + + + + + + + + s13 + + + + + + device:pim.contacts.read + + + + + + + + + + + + + s14 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s16 + + + + + + + + + + + + + + + + + + + + + subject4 + + + + + + + + resource4 + + + + + + + + + + + subject5 + + + + + + + + resource4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s19.1 + + + + + + + + resource4 + + + + + + + + + + s19.2 + + + + + + + + resource4 + + + + + + + + + + + + + s20.1 + + + + + + + + resource4 + + + + + + + + + + s20.2 + + + + + + + + resource4 + + + + + + + + + + + + + + s21 + + + + + + + + + + + + + + + + + + s23 + + + + + + + + + + + + + + + + + + + + s24 + + + + + + + + + + + + + + + + + + s25.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + s25.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + s25.3 + + + + + + + + + + + + + + + + + + + + + + + + + + + s25.4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s26.1 + + + + + + + + + + + + + + + + + + + + + + + + + + s26.2 + + + + + + + + + + + + + + + + + + + + + + + + + + s26.3 + + + + + + + + + + + + + + + + + + + + + + + + + + s26.4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + s27.1 + + + + + + + + + + + + + + + + + + + + + + + + + s27.2 + + + + + + + + + + + + + + + + + + + + + + + + + s27.3 + + + + + + + + + + + + + + + + + + + + + + + + + + + s27.4 + + + + + + + + + + + + + + + + + + + + + + + + + + + s28 + + + + + + + + + + + + + + + + + + + + + + + + + + s29 + + + + + + + + + + + + + + + + + + + + + + + + + s30.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s30.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s30.3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s30.4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s31.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s31.2.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s31.2.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s31.3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s32.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s32.2.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s32.2.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s32.3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s33.1 + + + + + + + + + + + + + + + + + + + + + + + + + + s33.2 + + + + + + + + + + + + + + + + + + + + + + + + + + s33.3 + + + + + + + + + + + + + + + + + + + + + + + + + + s34.1 + + + + + + + + + + + + + + + + + + + + + + + + s34.2 + + + + + + + + + + + + + + + + + + + + + + + + + + s35.1 + + + + + + + + + + + + + + + + + + + + + + + + + + s35.2 + + + + + + + + + + + + + + + + + + + + + + + + org.tizen.widget.analogclock + + + + + + + + + + + + + + + + + s36 + + + + + + + + + + + + + + + + + + + + + + + s37 + + + + + + device:pim.contacts.read + + + + + + + + + + + + + s38 + + + + + + device:pim.contacts.read + + + + + + + + + s38.4 + + + + + + device:pim.contacts.read + + + + + + + + + + + + s39 + + + + + + device:pim.contacts.read + + + + + + + + + s39.4 + + + + + + device:pim.contacts.read + + + + + + + + + + + + + + + s40 + + + + + + r40 + + + + + + + r40 + + + + + + + + + + + + s41 + + + + + + r41 + + + + + r41.2 + + + + + + + + + + + + + s42.1 + + + + + + r42.1 + + + + + r42.1 + + + + + + + + + + + + + s42.2 + + + + + + r42.2 + + + + + r42.2 + + + + + + + + + + + + s43.1 + + + + + + r43.1 + + + + + + + r43.1 + + + + + + + + + + + s43.2 + + + + + + r43.2 + + + + + + + r43.2 + + + + + + + + + + + s44.1 + + + + + + r44.1 + + + + + + + r44.1 + + + + + + + + + + + s44.2 + + + + + + r44.2 + + + + + + + r44.2 + + + + + + + + + + + + + s45.1 + + + + + + r45.1 + + + + + r45.1 + + + + + + + + + + + + s45.2 + + + + + + r45.2 + + + + + r45.2 + + + + + + + + + + + + + s46.1 + + + + + + r46.1 + + + + + r46.1 + + + + + + + + + + + + s46.2 + + + + + + r46.2 + + + + + r46.2 + + + + + + + + + + + + + s47.1 + + + + + + r47.1 + + + + + r47.1 + + + + + + + + + + + s47.2 + + + + + + r47.2 + + + + + r47.2 + + + + + + + + + + + +s48 + + + + + + + + + + + + + + + + +
diff --git a/tests/ace/test-configuration/CMakeLists.txt b/tests/ace/test-configuration/CMakeLists.txt new file mode 100644 index 0000000..756c13e --- /dev/null +++ b/tests/ace/test-configuration/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +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) diff --git a/tests/ace/test-configuration/attr_policy-example.xml b/tests/ace/test-configuration/attr_policy-example.xml new file mode 100644 index 0000000..8f0687f --- /dev/null +++ b/tests/ace/test-configuration/attr_policy-example.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + device.simcard + + + + + + + + + + + + + + + file.write + + + + + + + + + + + + + + + + pim.contact + + + + + + + \ No newline at end of file diff --git a/tests/ace/test-configuration/attr_policy-example1.xml b/tests/ace/test-configuration/attr_policy-example1.xml new file mode 100644 index 0000000..a4869c5 --- /dev/null +++ b/tests/ace/test-configuration/attr_policy-example1.xml @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/ace/test-configuration/attr_policy-example2.xml b/tests/ace/test-configuration/attr_policy-example2.xml new file mode 100644 index 0000000..e7a85be --- /dev/null +++ b/tests/ace/test-configuration/attr_policy-example2.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + resource7 + + + + + + + + + + + + + + + + resource7 + + + + + + + + + + + + + + + + resource7 + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/ace/test-configuration/attr_policy-example3.xml b/tests/ace/test-configuration/attr_policy-example3.xml new file mode 100644 index 0000000..4d15108 --- /dev/null +++ b/tests/ace/test-configuration/attr_policy-example3.xml @@ -0,0 +1,128 @@ + + + + + + subject + + + + + + + + + + + + + + + + resource + + + + + + + + + + + + + + + resource + + + + + + + + + + subject3 + + + + + + + + + + + resource2 + + + + + + + + + resource2 + + + + + + + + + subject4 + + + + + + + + resource4 + + + + + + + + + + + + + + + + + + + + subject5 + + + + + + + resource5 + + + + + + + + + + resource6 + + + + + + + \ No newline at end of file diff --git a/tests/ace/test-configuration/attr_policy-example4.xml b/tests/ace/test-configuration/attr_policy-example4.xml new file mode 100644 index 0000000..f709233 --- /dev/null +++ b/tests/ace/test-configuration/attr_policy-example4.xml @@ -0,0 +1,102 @@ + + + + + + + + + + + resource7 + + + + + + + + + + + + + + resource7 + + + + + + + + + + + + + + + + + + resource7 + + + + + + + + + + + + + + resource7 + + + + + + + + + + + + + + + + + + + resource7 + + + + + + + + + + + + + + resource7 + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/ace/test-configuration/attr_policy-example5.xml b/tests/ace/test-configuration/attr_policy-example5.xml new file mode 100644 index 0000000..f9c837e --- /dev/null +++ b/tests/ace/test-configuration/attr_policy-example5.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + device.simcard + + + + + + + device.simcard + + + + + + + device.simcard + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/ace/test-configuration/attr_policy-example6.xml b/tests/ace/test-configuration/attr_policy-example6.xml new file mode 100644 index 0000000..7a4c709 --- /dev/null +++ b/tests/ace/test-configuration/attr_policy-example6.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + device.simcard + + + + + + + device.simcard + + + + + + + device.simcard + + + + + + + + + + + \ No newline at end of file diff --git a/tests/ace/test-configuration/attr_policy-example7.xml b/tests/ace/test-configuration/attr_policy-example7.xml new file mode 100644 index 0000000..15907f9 --- /dev/null +++ b/tests/ace/test-configuration/attr_policy-example7.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + device.simcard + + + + + + + + + + + + device.simcard + + + + + + + + + + + device.simcard + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/ace/test-configuration/attr_policy-example8.xml b/tests/ace/test-configuration/attr_policy-example8.xml new file mode 100644 index 0000000..c73be53 --- /dev/null +++ b/tests/ace/test-configuration/attr_policy-example8.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + resource7 + + + + + + + + + + + + + + + + resource7 + + + + + + + + + + + + + + + + resource7 + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/ace/test-configuration/attre_config.xml b/tests/ace/test-configuration/attre_config.xml new file mode 100644 index 0000000..bd52527 --- /dev/null +++ b/tests/ace/test-configuration/attre_config.xml @@ -0,0 +1,17 @@ + + + + false + /usr/etc/ace/ + + attr_policy-example.xml + + + samsung + + + nokia + + + + diff --git a/tests/ace/test-configuration/general-test.xml b/tests/ace/test-configuration/general-test.xml new file mode 100644 index 0000000..c67eaa6 --- /dev/null +++ b/tests/ace/test-configuration/general-test.xml @@ -0,0 +1,2621 @@ + + + + + + subject + + + + + + + + + + + + + + + + resource + + + + + + + + + + + + + + + resource + + + + + + + + + + subject3 + + + + + + + + + + + resource2 + + + + + + + + + resource2 + + + + + + + + + subject4 + + + + + + + + resource4 + + + + + + + + + + + + + + + + + + + subject5 + + + + + + + resource5 + + + + + + + + + + resource6 + + + + + + + + + + + + + + + + + + resource7 + + + + + + + + + + + + + + + + resource7 + + + + + + + + + + + + + + + + resource7 + + + + + + + + + + + + + + + + + s8a + + + + + + r8 + + + + + + + + r8 + + + + + + + + + + s8b + + + + + + r8 + + + + + + + + r8 + + + + + + + + + + s8c + + + + + + r8 + + + + + + + + + + + + + + s9a + + + + + + r9 + + + + + + r9 + + + + + + + + + + s9b + + + + + + r9 + + + + + + r9 + + + + + + + + + + s9c + + + + + + r9 + + + + + + r9 + + + + + + r9 + + + + + + r9 + + + + + + + + + + s9d + + + + + + r9 + + + + + + r9 + + + + + + r9 + + + + + + r9 + + + + + + + + + + s9e + + + + + + r9 + + + + + + r9 + + + + + + + + + + s9f + + + + + + r9 + + + + + + r9 + + + + + + + + + + s9g + + + + + + r9 + + + + + + r9 + + + + + + + + + + s9h + + + + + + r9 + + + + + + r9 + + + + + + + + + + s10a + + + + + + r10 + + + + + + + + r10 + + + + + + + + + + s10b + + + + + + r10 + + + + + + + + r10 + + + + + + + + + + s10c + + + + + + r10 + + + + + + r10 + + + + + + + + + + + + + + + + s13 + + + + + + device:pim.contacts.read + + + + + + + + + + + + + + + + + + + + + + + + + + s16 + + + + + + + + + + + + + + + + + + + + + s17a + + + + + + + + resource4 + + + + + + + + + + + s17b + + + + + + + + resource4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s19.1 + + + + + + + + resource4 + + + + + + + + + + s19.2 + + + + + + + + resource4 + + + + + + + + + + + + + s20.1 + + + + + + + + resource4 + + + + + + + + + + s20.2 + + + + + + + + resource4 + + + + + + + + + + + + + + s21 + + + + + + + + + + + + + + + + s21a + + + + + + + + + + + + + + + + + s23 + + + + + + + + + + + + + + + + + + + + s24 + + + + + + + + + + + + + + + + + + s25.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + s25.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + s25.3 + + + + + + + + + + + + + + + + + + + + + + + + + s25.4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s26.1 + + + + + + + + + + + + + + + + + + + + + + + + + + s26.2 + + + + + + + + + + + + + + + + + + + + + + + + + + s26.3 + + + + + + + + + + + + + + + + + + + + + + + + + + s26.4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + s27.1 + + + + + + + + + + + + + + + + + + + + + + + + + s27.2 + + + + + + + + + + + + + + + + + + + + + + + + + s27.3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + s27.4 + + + + + + + + + + + + + + + + + + + + + + + + + + + s28 + + + + + + + + + + + + + + + + + + + + + + + + + + s29 + + + + + + + + + + + + + + + + + + + + + + + + + s30.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s30.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s30.3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s30.4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s31.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s31.2.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s31.2.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s31.3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s32.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s32.2.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s32.2.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s32.3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s33.1 + + + + + + + + + + + + + + + + + + + + + + + + + + s33.2 + + + + + + + + + + + + + + + + + + + + + + + + + + s33.3 + + + + + + + + + + + + + + + + + + + + + + + + + + s34.1 + + + + + + + + + + + + + + + + + + + + + + + + s34.2 + + + + + + + + + + + + + + + + + + + + + + + + + + s35.1 + + + + + + + + + + + + + + + + + + + + + + + + + + s35.2 + + + + + + + + + + + + + + + + + + + + + + + + org.tizen.widget.analogclock + + + + + + + + + + + + + + + + + s36 + + + + + + + + + + + + + + + + + + + + + + + s37 + + + + + + device:pim.contacts.read + + + + + + + + + + + + + s38 + + + + + + device:pim.contacts.read + + + + + + + + + s38.4 + + + + + + device:pim.contacts.read + + + + + + + + + + + + s39 + + + + + + device:pim.contacts.read + + + + + + + + + s39.4 + + + + + + device:pim.contacts.read + + + + + + + + + + + + + + + s40 + + + + + + r40 + + + + + + + r40 + + + + + + + + + + + + s41 + + + + + + r41 + + + + + r41.2 + + + + + + + + + + + + + s42.1 + + + + + + r42.1 + + + + + r42.1 + + + + + + + + + + + + + s42.2 + + + + + + r42.2 + + + + + r42.2 + + + + + + + + + + + + s43.1 + + + + + + r43.1 + + + + + + + r43.1 + + + + + + + + + + + s43.2 + + + + + + r43.2 + + + + + + + r43.2 + + + + + + + + + + + s44.1 + + + + + + r44.1 + + + + + + + r44.1 + + + + + + + + + + + s44.2 + + + + + + r44.2 + + + + + + + r44.2 + + + + + + + + + + + + + s45.1 + + + + + + r45.1 + + + + + r45.1 + + + + + + + + + + + + s45.2 + + + + + + r45.2 + + + + + r45.2 + + + + + + + + + + + + + s46.1 + + + + + + r46.1 + + + + + r46.1 + + + + + + + + + + + + s46.2 + + + + + + r46.2 + + + + + r46.2 + + + + + + + + + + + + + s47.1 + + + + + + r47.1 + + + + + r47.1 + + + + + + + + + + + s47.2 + + + + + + r47.2 + + + + + r47.2 + + + + + + + + + + + + s48 + + + + + + + + + + + + + + + + + + + BF00 + + + + + + + + + + + + + + + + + + + + + + + + BF01 + + + + + + + + + + + + + + + + + + + + + + + + + BF02 + + + + + + + + + + + + + + + + + + + + + + + + BF03 + + + + + + + + + + + + + + + + + + + + + + + + + BF04 + + + + + + BFR04 + + + + + BFR04 + + + + + + + + + + + s61a + + + + + + r61a + type + + + + + r61a + + + + + + + + + s61b + + + + + + r61b + type + + + + + r61b + + + + + + + + + + s61c + + + + + + r61c + type + port + + + + + r61c + + + + + + + + + s61d + + + + + + r61d + type + port + + + + + r61d + + + + + + + + + + paramTestSubject + + + + + + messaging + +4409* + + + + + messaging + +4408* + + + + + messaging + +48* + + + + + camera + high + + + + + camera + low + + + + + + + + diff --git a/tests/ace/test-configuration/interceptpolicy.xml b/tests/ace/test-configuration/interceptpolicy.xml new file mode 100644 index 0000000..ab055ce --- /dev/null +++ b/tests/ace/test-configuration/interceptpolicy.xml @@ -0,0 +1,495 @@ + + + + + + + Unidentified + + + + + + + + http://jil.org/jil/api/1.1/device + + + getAvailableApplications + + + + + + + http://jil.org/jil/api/1.1/addressbookitem.AddressBookItem.update + + + http://jil.org/jil/api/1.1/multimedia.Camera.captureImage + + + http://jil.org/jil/api/1.1/device.Device.launchApplication + + + DeviceStateInfo.requestPositionInfo + + + http://jil.org/jil/api/1.1/messaging.Messaging.sendMessage + + + + + + + http://jil.org/jil/api/1.1.1/pim.PIM.findAddressBookItems + + + http://jil.org/jil/api/1.1.1/pim.PIM.getAddressBookItem + + + http://jil.org/jil/api/1.1.1/pim.PIM.getAddressBookItemsCount + + + + + + + + Device.PositionInfo + + + http://jil.org/jil/api/1.1/addressbookitem.AddressBookItem.getAttributeValue + + + http://jil.org/jil/api/1.1/addressbookitem.AddressBookItem.getAvailableAttributes + + + http://jil.org/jil/api/1.1/addressbookitem.AddressBookItem.setAttributeValue + + + http://jil.org/jil/api/1.1/multimedia.AudioPlayer.open + + + http://jil.org/jil/api/1.1/multimedia.AudioPlayer.play + + + http://jil.org/jil/api/1.1/multimedia.AudioPlayer.pause + + + http://jil.org/jil/api/1.1/multimedia.AudioPlayer.resume + + + http://jil.org/jil/api/1.1/multimedia.AudioPlayer.stop + + + AudioPlayer.onStateChange + + + http://jil.org/jil/api/1.1/multimedia.Camera.onCameraCaptured + + + http://jil.org/jil/api/1.1/multimedia.Camera.setWindow + + + Device.PositionInfo + + + Device.DeviceStateInfo + + + DeviceStateInfo.onPositionRetrieved + + + http://jil.org/jil/api/1.1/messaging.Messaging.createMessage + + + Messaging.onMessageSendingFailure + + + Multimedia.getVolume + + + Multimedia.stopAll + + + Multimedia.isAudioPlaying + + + http://jil.org/jil/api/1.1.1/pim.PIM.createAddressBookItem + + + PIM.onAddressBookItemFound + + + + + + http://jil.org/jil/api/1.1/accelerometerinfo + + + http://jil.org/jil/api/1.1/addressbookitem + + + http://jil.org/jil/api/1.1.5/applicationtypes + + + http://jil.org/jil/api/1.1.2/camera + + + http://jil.org/jil/api/1.1/device + + + http://jil.org/jil/api/1.1/devicestateinfo + + + http://jil.org/jil/api/1.1.5/exception + + + http://jil.org/jil/api/1.1.5/exceptiontypes + + + http://jil.org/jil/api/1.1/message + + + http://jil.org/jil/api/1.1/messagetypes + + + http://jil.org/jil/api/1.1/messaging + + + http://jil.org/jil/api/1.1/multimedia + + + http://jil.org/jil/api/1.1.1/pim + + + http://jil.org/jil/api/1.1/positioninfo + + + http://jil.org/jil/api/1.1/widget + + + + + + + + + + + + Identified + + + + + + + + http://jil.org/jil/api/1.1/addressbookitem.AddressBookItem.update + + + DeviceStateInfo.requestPositionInfo + + + + + + + http://jil.org/jil/api/1.1/device.Device.launchApplication + + + http://jil.org/jil/api/1.1/multimedia.Camera.captureImage + + + http://jil.org/jil/api/1.1/messaging.Messaging.sendMessage + + + http://jil.org/jil/api/1.1.1/pim.PIM.findAddressBookItems + + + http://jil.org/jil/api/1.1.1/pim.PIM.getAddressBookItem + + + http://jil.org/jil/api/1.1.1/pim.PIM.getAddressBookItemsCount + + + + + + + + http://jil.org/jil/api/1.1/device.Device.getAvailableApplications + + + http://jil.org/jil/api/1.1/addressbookitem.AddressBookItem.getAttributeValue + + + http://jil.org/jil/api/1.1/addressbookitem.AddressBookItem.getAvailableAttributes + + + http://jil.org/jil/api/1.1/addressbookitem.AddressBookItem.setAttributeValue + + + http://jil.org/jil/api/1.1/multimedia.AudioPlayer.open + + + http://jil.org/jil/api/1.1/multimedia.AudioPlayer.play + + + http://jil.org/jil/api/1.1/multimedia.AudioPlayer.pause + + + http://jil.org/jil/api/1.1/multimedia.AudioPlayer.resume + + + http://jil.org/jil/api/1.1/multimedia.AudioPlayer.stop + + + AudioPlayer.onStateChange + + + http://jil.org/jil/api/1.1/multimedia.Camera.onCameraCaptured + + + http://jil.org/jil/api/1.1/multimedia.Camera.setWindow + + + Device.PositionInfo + + + Device.DeviceStateInfo + + + DeviceStateInfo.onPositionRetrieved + + + http://jil.org/jil/api/1.1/messaging.Messaging.createMessage + + + Messaging.onMessageSendingFailure + + + Multimedia.getVolume + + + Multimedia.stopAll + + + Multimedia.isAudioPlaying + + + http://jil.org/jil/api/1.1.1/pim.PIM.createAddressBookItem + + + PIM.onAddressBookItemFound + + + + + + http://jil.org/jil/api/1.1/accelerometerinfo + + + http://jil.org/jil/api/1.1/addressbookitem + + + http://jil.org/jil/api/1.1.5/applicationtypes + + + http://jil.org/jil/api/1.1.2/camera + + + http://jil.org/jil/api/1.1/device + + + http://jil.org/jil/api/1.1/devicestateinfo + + + http://jil.org/jil/api/1.1.5/exception + + + http://jil.org/jil/api/1.1.5/exceptiontypes + + + http://jil.org/jil/api/1.1/message + + + http://jil.org/jil/api/1.1/messagetypes + + + http://jil.org/jil/api/1.1/messaging + + + http://jil.org/jil/api/1.1/multimedia + + + http://jil.org/jil/api/1.1.1/pim + + + http://jil.org/jil/api/1.1/positioninfo + + + http://jil.org/jil/api/1.1/widget + + + + + + + + + + + + Operator + + + + + + + + http://jil.org/jil/api/1.1/device.Device.launchApplication + + + DeviceStateInfo.requestPositionInfo + + + http://jil.org/jil/api/1.1/addressbookitem.AddressBookItem.update + + + http://jil.org/jil/api/1.1/device.Device.getAvailableApplications + + + http://jil.org/jil/api/1.1/addressbookitem.AddressBookItem.getAttributeValue + + + http://jil.org/jil/api/1.1/addressbookitem.AddressBookItem.getAvailableAttributes + + + http://jil.org/jil/api/1.1/addressbookitem.AddressBookItem.setAttributeValue + + + http://jil.org/jil/api/1.1/multimedia.AudioPlayer.open + + + http://jil.org/jil/api/1.1/multimedia.AudioPlayer.play + + + http://jil.org/jil/api/1.1/multimedia.AudioPlayer.pause + + + http://jil.org/jil/api/1.1/multimedia.AudioPlayer.resume + + + http://jil.org/jil/api/1.1/multimedia.AudioPlayer.stop + + + AudioPlayer.onStateChange + + + http://jil.org/jil/api/1.1/multimedia.Camera.onCameraCaptured + + + http://jil.org/jil/api/1.1/multimedia.Camera.setWindow + + + http://jil.org/jil/api/1.1/multimedia.Camera.captureImage + + + Device.PositionInfo + + + Device.DeviceStateInfo + + + DeviceStateInfo.onPositionRetrieved + + + http://jil.org/jil/api/1.1/messaging.Messaging.createMessage + + + http://jil.org/jil/api/1.1/messaging.Messaging.sendMessage + + + Messaging.onMessageSendingFailure + + + Multimedia.getVolume + + + Multimedia.stopAll + + + Multimedia.isAudioPlaying + + + http://jil.org/jil/api/1.1.1/pim.PIM.createAddressBookItem + + + PIM.onAddressBookItemFound + + + http://jil.org/jil/api/1.1.1/pim.PIM.findAddressBookItems + + + http://jil.org/jil/api/1.1.1/pim.PIM.getAddressBookItem + + + http://jil.org/jil/api/1.1.1/pim.PIM.getAddressBookItemsCount + + + + + + http://jil.org/jil/api/1.1/accelerometerinfo + + + http://jil.org/jil/api/1.1/addressbookitem + + + http://jil.org/jil/api/1.1.5/applicationtypes + + + http://jil.org/jil/api/1.1.2/camera + + + http://jil.org/jil/api/1.1/device + + + http://jil.org/jil/api/1.1/devicestateinfo + + + http://jil.org/jil/api/1.1.5/exception + + + http://jil.org/jil/api/1.1.5/exceptiontypes + + + http://jil.org/jil/api/1.1/message + + + http://jil.org/jil/api/1.1/messagetypes + + + http://jil.org/jil/api/1.1/messaging + + + http://jil.org/jil/api/1.1/multimedia + + + http://jil.org/jil/api/1.1.1/pim + + + http://jil.org/jil/api/1.1/positioninfo + + + http://jil.org/jil/api/1.1/widget + + + + + + + diff --git a/tests/ace/test-configuration/old_policy-example.xml b/tests/ace/test-configuration/old_policy-example.xml new file mode 100644 index 0000000..d7ce388 --- /dev/null +++ b/tests/ace/test-configuration/old_policy-example.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + device.simcard + + + + + + + + + + + + + + + file.write + + + + + + + + + + + + + + + + pim.contact + + + + + + + diff --git a/tests/ace/test-configuration/policy-example.xml b/tests/ace/test-configuration/policy-example.xml new file mode 100644 index 0000000..c0e0857 --- /dev/null +++ b/tests/ace/test-configuration/policy-example.xml @@ -0,0 +1,95 @@ + + + + + + + + + + + + devicestatus + + + + + + + + + + + + + + + + devicestatus + + + + + + + + + + + + + + + http://bondi.omtp.org/api.appconfig + + + + + + + + + + + + + + + + + + + + + file.write + + + + + + + + + + + + + + + + pim.contact + + + + + + + \ No newline at end of file diff --git a/tests/ace/test-configuration/policy-example2.xml b/tests/ace/test-configuration/policy-example2.xml new file mode 100644 index 0000000..dded65c --- /dev/null +++ b/tests/ace/test-configuration/policy-example2.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + device.simcard + + + + + + + + + + + + + + + file.write + + + + + + + + + + + + + + + + pim.contact + + + + + + + \ No newline at end of file diff --git a/tests/ace/test-configuration/policy-example3.xml b/tests/ace/test-configuration/policy-example3.xml new file mode 100644 index 0000000..ef0fddc --- /dev/null +++ b/tests/ace/test-configuration/policy-example3.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + device.simcard + + + + + + + + + + + + + + + file.write + + + + + + + + + + + + + + + + pim.contact + + + + + + + \ No newline at end of file diff --git a/tests/ace/test-configuration/policy-test-gsettings.xml b/tests/ace/test-configuration/policy-test-gsettings.xml new file mode 100644 index 0000000..2a242f6 --- /dev/null +++ b/tests/ace/test-configuration/policy-test-gsettings.xml @@ -0,0 +1,41 @@ + + + + + a1 + + + + + + d3 + + + + + + + aa2 + + + + + + bb2 + + + + + + + + c3 + + + + + d3 + + + + \ No newline at end of file diff --git a/tests/ace/test-configuration/policy-test.xml b/tests/ace/test-configuration/policy-test.xml new file mode 100644 index 0000000..9094ee4 --- /dev/null +++ b/tests/ace/test-configuration/policy-test.xml @@ -0,0 +1,41 @@ + + + + + a1 + + + + + + b1 + + + + + + + aa2 + + + + + + bb2 + + + + + + + + c3 + + + + + d3 + + + + \ No newline at end of file diff --git a/tests/ace/test-configuration/policy-wac-2.0.xml b/tests/ace/test-configuration/policy-wac-2.0.xml new file mode 100644 index 0000000..cf59001 --- /dev/null +++ b/tests/ace/test-configuration/policy-wac-2.0.xml @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/ace/test-configuration/policy_example.xml b/tests/ace/test-configuration/policy_example.xml new file mode 100644 index 0000000..333422d --- /dev/null +++ b/tests/ace/test-configuration/policy_example.xml @@ -0,0 +1,2407 @@ + + + + + + subject + + + + + + + + + + + + + + + + resource + + + + + + + + + + + + + + + resource + + + + + + + + + + subject3 + + + + + + + + + + + resource2 + + + + + + + + + resource2 + + + + + + + + + subject4 + + + + + + + + resource4 + + + + + + + + + + + + + + + + + + + subject5 + + + + + + + resource5 + + + + + + + + + + resource6 + + + + + + + + + + + + + + + + + + resource7 + + + + + + + + + + + + + + + + resource7 + + + + + + + + + + + + + + + + resource7 + + + + + + + + + + + + + + + + + s8a + + + + + + r8 + + + + + + + + r8 + + + + + + + + + + s8b + + + + + + r8 + + + + + + + + r8 + + + + + + + + + + s8c + + + + + + r8 + + + + + + + + + + + + + + s9a + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9b + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9c + + + + + + r9 + + + + + + + + + r9 + + + + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9d + + + + + + r9 + + + + + + + + r9 + + + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9e + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9f + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9g + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s9h + + + + + + r9 + + + + + + + + r9 + + + + + + + + + + s10a + + + + + + r10 + + + + + + + + r10 + + + + + + + + + + s10b + + + + + + r10 + + + + + + + + r10 + + + + + + + + + + s10c + + + + + + r10 + + + + + + + + r10 + + + + + + + + + + + + + + + + s13 + + + + + + device:pim.contacts.read + + + + + + + + + + + + + s14 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s16 + + + + + + + + + + + + + + + + + + + + + subject4 + + + + + + + + resource4 + + + + + + + + + + + subject5 + + + + + + + + resource4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s19.1 + + + + + + + + resource4 + + + + + + + + + + s19.2 + + + + + + + + resource4 + + + + + + + + + + + + + s20.1 + + + + + + + + resource4 + + + + + + + + + + s20.2 + + + + + + + + resource4 + + + + + + + + + + + + + + s21 + + + + + + + + + + + + + + + + + + s23 + + + + + + + + + + + + + + + + + + + + s24 + + + + + + + + + + + + + + + + + + s25.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + s25.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + s25.3 + + + + + + + + + + + + + + + + + + + + + + + + + + + s25.4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s26.1 + + + + + + + + + + + + + + + + + + + + + + + + + + s26.2 + + + + + + + + + + + + + + + + + + + + + + + + + + s26.3 + + + + + + + + + + + + + + + + + + + + + + + + + + s26.4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + s27.1 + + + + + + + + + + + + + + + + + + + + + + + + + s27.2 + + + + + + + + + + + + + + + + + + + + + + + + + s27.3 + + + + + + + + + + + + + + + + + + + + + + + + + + + s27.4 + + + + + + + + + + + + + + + + + + + + + + + + + + + s28 + + + + + + + + + + + + + + + + + + + + + + + + + + s29 + + + + + + + + + + + + + + + + + + + + + + + + + s30.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s30.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s30.3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s30.4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s31.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s31.2.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s31.2.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s31.3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s32.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s32.2.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s32.2.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s32.3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s33.1 + + + + + + + + + + + + + + + + + + + + + + + + + + s33.2 + + + + + + + + + + + + + + + + + + + + + + + + + + s33.3 + + + + + + + + + + + + + + + + + + + + + + + + + + s34.1 + + + + + + + + + + + + + + + + + + + + + + + + s34.2 + + + + + + + + + + + + + + + + + + + + + + + + + + s35.1 + + + + + + + + + + + + + + + + + + + + + + + + + + s35.2 + + + + + + + + + + + + + + + + + + + + + + + + org.tizen.widget.analogclock + + + + + + + + + + + + + + + + + s36 + + + + + + + + + + + + + + + + + + + + + + + s37 + + + + + + device:pim.contacts.read + + + + + + + + + + + + + s38 + + + + + + device:pim.contacts.read + + + + + + + + + s38.4 + + + + + + device:pim.contacts.read + + + + + + + + + + + + s39 + + + + + + device:pim.contacts.read + + + + + + + + + s39.4 + + + + + + device:pim.contacts.read + + + + + + + + + + + + + + + s40 + + + + + + r40 + + + + + + + r40 + + + + + + + + + + + + s41 + + + + + + r41 + + + + + r41.2 + + + + + + + + + + + + + s42.1 + + + + + + r42.1 + + + + + r42.1 + + + + + + + + + + + + + s42.2 + + + + + + r42.2 + + + + + r42.2 + + + + + + + + + + + + s43.1 + + + + + + r43.1 + + + + + + + r43.1 + + + + + + + + + + + s43.2 + + + + + + r43.2 + + + + + + + r43.2 + + + + + + + + + + + s44.1 + + + + + + r44.1 + + + + + + + r44.1 + + + + + + + + + + + s44.2 + + + + + + r44.2 + + + + + + + r44.2 + + + + + + + + + + + + + s45.1 + + + + + + r45.1 + + + + + r45.1 + + + + + + + + + + + + s45.2 + + + + + + r45.2 + + + + + r45.2 + + + + + + + + + + + + + s46.1 + + + + + + r46.1 + + + + + r46.1 + + + + + + + + + + + + s46.2 + + + + + + r46.2 + + + + + r46.2 + + + + + + + + + + + + + s47.1 + + + + + + r47.1 + + + + + r47.1 + + + + + + + + + + + s47.2 + + + + + + r47.2 + + + + + r47.2 + + + + + + + + + + + +s48 + + + + + + + + + + + + + + + diff --git a/tests/ace/test-configuration/reproduce-abort-test.xml b/tests/ace/test-configuration/reproduce-abort-test.xml new file mode 100644 index 0000000..ee2de20 --- /dev/null +++ b/tests/ace/test-configuration/reproduce-abort-test.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/ace/test-configuration/undefined-test.xml b/tests/ace/test-configuration/undefined-test.xml new file mode 100644 index 0000000..3da1b1c --- /dev/null +++ b/tests/ace/test-configuration/undefined-test.xml @@ -0,0 +1,1075 @@ + + + + + s25.2 + + + + + + + + + + + + + + + + + + + + + + s25.3 + + + + + + + + + + + + + + + + + + + + + + + + + s25.4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s26.1 + + + + + + + + + + + + + + + + + + + + + + + + + + s26.2 + + + + + + + + + + + + + + + + + + + + + + + + + + s26.3 + + + + + + + + + + + + + + + + + + + + + + + + + + s26.4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + s27.1 + + + + + + + + + + + + + + + + + + + + + + + + + s27.2 + + + + + + + + + + + + + + + + + + + + + + + + + s27.3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + s27.4 + + + + + + + + + + + + + + + + + + + + + + + + + + + s28 + + + + + + + + + + + + + + + + + + + + + + + + + + s29 + + + + + + + + + + + + + + + + + + + + + + + + + s30.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s30.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s30.3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s30.4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s31.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s31.2.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s31.2.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s31.3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s32.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s32.2.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s32.2.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s32.3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s33.1 + + + + + + + + + + + + + + + + + + + + + + + + + + s33.2 + + + + + + + + + + + + + + + + + + + + + + + + + + s33.3 + + + + + + + + + + + + + + + + + + + + + + + + + + s34.1 + + + + + + + + + + + + + + + + + + + + + + + + s34.2 + + + + + + + + + + + + + + + + + + + + + + + + + + s35.1 + + + + + + + + + + + + + + + + + + + + + + + + + + s35.2 + + + + + + + + + + + + + + + + + + + + + + + + org.tizen.widget.analogclock + + + + + + + + + + + + + + + + + s36 + + + + + + + + + + + + + + diff --git a/tests/core/CMakeLists.txt b/tests/core/CMakeLists.txt new file mode 100644 index 0000000..c1fbd82 --- /dev/null +++ b/tests/core/CMakeLists.txt @@ -0,0 +1,90 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file 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 diff --git a/tests/core/DESCRIPTION b/tests/core/DESCRIPTION new file mode 100644 index 0000000..48e5394 --- /dev/null +++ b/tests/core/DESCRIPTION @@ -0,0 +1,2 @@ +!!!options!!! stop +Test code diff --git a/tests/core/data/sample.zip b/tests/core/data/sample.zip new file mode 100644 index 0000000..02417d8 Binary files /dev/null and b/tests/core/data/sample.zip differ diff --git a/tests/core/main.cpp b/tests/core/main.cpp new file mode 100644 index 0000000..42ffe3a --- /dev/null +++ b/tests/core/main.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file main.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of main + */ +#include + +int main(int argc, char *argv[]) +{ + return DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv); +} + diff --git a/tests/core/test_address.cpp b/tests/core/test_address.cpp new file mode 100644 index 0000000..7aff2df --- /dev/null +++ b/tests/core/test_address.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_address.cpp + * @author Tomasz Swierczek (t.swierczek@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of test address + */ +#include +#include + +RUNNER_TEST_GROUP_INIT(DPL) + +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); +} diff --git a/tests/core/test_binary_queue.cpp b/tests/core/test_binary_queue.cpp new file mode 100644 index 0000000..d955aab --- /dev/null +++ b/tests/core/test_binary_queue.cpp @@ -0,0 +1,357 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_binary_queue.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of test binary queue + */ +#include +#include +RUNNER_TEST_GROUP_INIT(DPL) + +inline std::string BinaryQueueToString(const DPL::BinaryQueue &queue) +{ + char *buffer = new char[queue.Size()]; + queue.Flatten(buffer, queue.Size()); + std::string result = std::string(buffer, buffer + queue.Size()); + delete [] buffer; + return result; +} + +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(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"); +} diff --git a/tests/core/test_fast_delegate.cpp b/tests/core/test_fast_delegate.cpp new file mode 100644 index 0000000..947cbe5 --- /dev/null +++ b/tests/core/test_fast_delegate.cpp @@ -0,0 +1,248 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 +#include +#include + +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 MyDelegate; + + // If you want to have a non-void return value, put it at the end. + typedef DPL::FastDelegate2 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); + } + } +} diff --git a/tests/core/test_foreach.cpp b/tests/core/test_foreach.cpp new file mode 100644 index 0000000..f698081 --- /dev/null +++ b/tests/core/test_foreach.cpp @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_foreach.cpp + * @author Bartosz Janiak (b.janiak@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of foreach tests. + */ + +#include +#include +#include +#include +#include + +RUNNER_TEST_GROUP_INIT(DPL) + +static const size_t testContainerSize = 1024; + +template +void VerifyForeach(Container& container) +{ + size_t i = 0; + FOREACH(it, container) + { + RUNNER_ASSERT(*it == i); + i++; + } + RUNNER_ASSERT(i == container.size()); +} + +#define VERIFY_FOREACH(container) \ + { \ + size_t i = 0; \ + FOREACH(it, container) \ + { \ + RUNNER_ASSERT(*it == i); \ + i++; \ + } \ + } + +static size_t numberOfCallsToTemporaryList = 0; +std::list temporaryList(); +std::list temporaryList() +{ + ++numberOfCallsToTemporaryList; + std::list list; + for (size_t i = 0 ; i < testContainerSize ; i++) + { + list.push_back(i); + } + return list; +} + +static size_t numberOfCallsToTemporaryVector = 0; +std::vector temporaryVector(); +std::vector temporaryVector() +{ + ++numberOfCallsToTemporaryVector; + std::vector vector; + for (size_t i = 0 ; i < testContainerSize ; i++) + { + vector.push_back(i); + } + return vector; +} + +static size_t numberOfCallsToTemporarySet = 0; +std::set temporarySet(); +std::set temporarySet() +{ + ++numberOfCallsToTemporarySet; + std::set set; + for (size_t i = 0 ; i < testContainerSize ; i++) + { + set.insert(i); + } + return set; +} + +RUNNER_TEST(Foreach_std_containers) +{ + std::vector vector; + std::list list; + std::set set; + + for (size_t i = 0 ; i < testContainerSize ; i++) + { + vector.push_back(i); + list.push_back(i); + set.insert(i); + } + + VerifyForeach(vector); + VerifyForeach(list); + VerifyForeach(set); + + VERIFY_FOREACH(temporaryList()); + VERIFY_FOREACH(temporaryVector()); + VERIFY_FOREACH(temporarySet()); + + RUNNER_ASSERT(numberOfCallsToTemporaryList == 1); + RUNNER_ASSERT(numberOfCallsToTemporaryVector == 1); + RUNNER_ASSERT(numberOfCallsToTemporarySet == 1); +} diff --git a/tests/core/test_log_unhandled_exception.cpp b/tests/core/test_log_unhandled_exception.cpp new file mode 100644 index 0000000..0403c28 --- /dev/null +++ b/tests/core/test_log_unhandled_exception.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_log_unhandled_exception.cpp + * @author Pawel Sikorski (p.marcinkiew@samsung.com) + * @version 1.0 + * @brief + */ +#include +#include +#include + +RUNNER_TEST_GROUP_INIT(DPL) + +class MyException +{ +}; + +class MyDPLException +{ +public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, MyException) +}; + +class MySTDException + : public std::exception +{ +public: + virtual const char* what()const throw() { return "my std exception occurred";} +}; + +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); +} diff --git a/tests/core/test_once.cpp b/tests/core/test_once.cpp new file mode 100644 index 0000000..e65ea9b --- /dev/null +++ b/tests/core/test_once.cpp @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_once.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of once tests + */ +#include +#include +#include +#include +#include +#include +#include + +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 ThreadPtr; + + ThreadPtr threads[NUM_THREADS]; + DPL::WaitableEvent event; + DPL::Once once; + DPL::Atomic atom; + + for (size_t i = 0; i< NUM_THREADS; ++i) + { + (threads[i] = ThreadPtr(new MyThread(&event, &once, &atom)))->Run(); + } + + event.Signal(); + + for (size_t i = 0; i< NUM_THREADS; ++i) + threads[i]->Quit(); + + RUNNER_ASSERT_MSG(atom == 1, "Atom value is: " << atom); +} diff --git a/tests/core/test_scoped_array.cpp b/tests/core/test_scoped_array.cpp new file mode 100644 index 0000000..58b0603 --- /dev/null +++ b/tests/core/test_scoped_array.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_scoped_array.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of test scoped array + */ +#include +#include + +RUNNER_TEST_GROUP_INIT(DPL) + +RUNNER_TEST(ScopedArray_Zero) +{ + DPL::ScopedArray array; + + RUNNER_ASSERT(!array); + RUNNER_ASSERT(!!!array); +} + +RUNNER_TEST(ScopedArray_NonZero) +{ + DPL::ScopedArray array(new char[7]); + + RUNNER_ASSERT(array); + RUNNER_ASSERT(!!array); +} + +RUNNER_TEST(ScopedArray_Reset) +{ + DPL::ScopedArray array(new char[7]); + array.Reset(); + + RUNNER_ASSERT(!array); + + array.Reset(new char); + RUNNER_ASSERT(array); +} + +RUNNER_TEST(ScopedArray_ArrayOperator) +{ + DPL::ScopedArray array(new char[7]); + + array[1] = array[2] = 3; + + RUNNER_ASSERT(array[1] == 3); + RUNNER_ASSERT(array[2] == 3); +} diff --git a/tests/core/test_scoped_close.cpp b/tests/core/test_scoped_close.cpp new file mode 100644 index 0000000..3549fed --- /dev/null +++ b/tests/core/test_scoped_close.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_scoped_close.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of test scoped close + */ +#include +#include + +RUNNER_TEST_GROUP_INIT(DPL) + +// DUNNO diff --git a/tests/core/test_scoped_fclose.cpp b/tests/core/test_scoped_fclose.cpp new file mode 100644 index 0000000..dbdff95 --- /dev/null +++ b/tests/core/test_scoped_fclose.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*! + * @file test_scoped_fclose.cpp + * @author Piotr Marcinkiewicz (p.marcinkiew@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of test scoped fclose + */ + +#include +#include + +#include +#include + +RUNNER_TEST_GROUP_INIT(DPL) + +namespace +{ +FILE* MakeTmp() +{ + FILE* result = NULL; + do + { + result = tmpfile(); + } while (NULL != result && EINTR == errno); + return result; +} +}//anonymous namespace + +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); +} + diff --git a/tests/core/test_scoped_free.cpp b/tests/core/test_scoped_free.cpp new file mode 100644 index 0000000..bc41a5a --- /dev/null +++ b/tests/core/test_scoped_free.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_scoped_free.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of test scoped free + */ +#include +#include +#include + +RUNNER_TEST_GROUP_INIT(DPL) + +RUNNER_TEST(ScopedFree_Zero) +{ + DPL::ScopedFree free; + + RUNNER_ASSERT(!free); + RUNNER_ASSERT(!!!free); +} + +RUNNER_TEST(ScopedFree_NonZero) +{ + DPL::ScopedFree free(malloc(7)); + + RUNNER_ASSERT(free); + RUNNER_ASSERT(!!free); +} + +RUNNER_TEST(ScopedFree_Reset) +{ + DPL::ScopedFree free(malloc(7)); + free.Reset(); + + RUNNER_ASSERT(!free); + + free.Reset(malloc(8)); + RUNNER_ASSERT(free); +} diff --git a/tests/core/test_scoped_ptr.cpp b/tests/core/test_scoped_ptr.cpp new file mode 100644 index 0000000..f3a7237 --- /dev/null +++ b/tests/core/test_scoped_ptr.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_scoped_ptr.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of test scoped ptr + */ +#include +#include + +RUNNER_TEST_GROUP_INIT(DPL) + +RUNNER_TEST(ScopedPtr_Zero) +{ + DPL::ScopedPtr ptr; + + RUNNER_ASSERT(!ptr); + RUNNER_ASSERT(!!!ptr); +} + +RUNNER_TEST(ScopedPtr_NonZero) +{ + DPL::ScopedPtr ptr(new char(7)); + + RUNNER_ASSERT(ptr); + RUNNER_ASSERT(!!ptr); +} + +RUNNER_TEST(ScopedPtr_Reset) +{ + DPL::ScopedPtr ptr(new char(7)); + ptr.Reset(); + + RUNNER_ASSERT(!ptr); + + ptr.Reset(new char); + RUNNER_ASSERT(ptr); +} + +RUNNER_TEST(ScopedPtr_Operators) +{ + DPL::ScopedPtr ptr(new char(7)); + + RUNNER_ASSERT(*ptr == *ptr.Get()); +} diff --git a/tests/core/test_semaphore.cpp b/tests/core/test_semaphore.cpp new file mode 100644 index 0000000..854978e --- /dev/null +++ b/tests/core/test_semaphore.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_semaphore.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of semaphore tests + */ +#include +#include +#include +#include +#include +#include +#include + +RUNNER_TEST_GROUP_INIT(DPL) + +class SemaphoreThread + : public DPL::Thread +{ + int m_delta; + int m_times; + int *m_value; + std::string m_semaphoreName; + +public: + SemaphoreThread(int delta, + int times, + int *value, + const std::string &semaphoreName) + : m_delta(delta), + m_times(times), + m_value(value), + m_semaphoreName(semaphoreName) + { + } + +protected: + virtual int ThreadEntry() + { + DPL::Semaphore semaphore(m_semaphoreName); + + for (int i = 0; i < m_times; ++i) + { + // Take scoped semaphore lock + DPL::Semaphore::ScopedLock lock(&semaphore); + *m_value += m_delta; + } + + return 0; + } +}; + +RUNNER_TEST(Semaphore_NamedIncrementDecrement) +{ + std::string semaphoreName = + "dpl_test_semaphore_" + + DPL::lexical_cast(std::time(NULL)); + + int value = 0; + SemaphoreThread threadA(-1, 10000, &value, semaphoreName); + SemaphoreThread threadB(+1, 10000, &value, semaphoreName); + + threadA.Run(); + threadB.Run(); + + threadA.Quit(); + threadB.Quit(); + + RUNNER_ASSERT_MSG(value == 0, "Final value is: " << value); +} diff --git a/tests/core/test_serialization.cpp b/tests/core/test_serialization.cpp new file mode 100644 index 0000000..8776fc8 --- /dev/null +++ b/tests/core/test_serialization.cpp @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_address.cpp + * @author Tomasz Swierczek (t.swierczek@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of serialization tests + */ + +#include +#include +#include +#include + +#include +#include + +RUNNER_TEST_GROUP_INIT(DPL) + +// test stream class +class BinaryStream : public DPL::IStream { + public: + virtual void Read(size_t num, void * bytes) + { + for (unsigned i = 0; i < num; ++i) { + ((unsigned char*)bytes)[i] = data[i + readPosition]; + } + readPosition += num; + } + virtual void Write(size_t num, const void * bytes) + { + for (unsigned i = 0; i < num; ++i) { + data.push_back(((unsigned char*)bytes)[i]); + } + } + BinaryStream() + { + readPosition = 0; + } + virtual ~BinaryStream(){}; + + private: + std::vector data; + unsigned readPosition; +}; + +//test ISerializable class +class TestClass : public DPL::ISerializable { + public: + TestClass(int val, std::string str1, std::string str2) + { + a = val; + b = str1; + c.push_back(str1); + c.push_back(str2); + c.push_back(str1 + str2); + }; + TestClass(DPL::IStream& stream) + { + DPL::Deserialization::Deserialize(stream,a); + DPL::Deserialization::Deserialize(stream,b); + DPL::Deserialization::Deserialize(stream,c); + }; + virtual void Serialize(DPL::IStream& stream) const + { + DPL::Serialization::Serialize(stream,a); + DPL::Serialization::Serialize(stream,b); + DPL::Serialization::Serialize(stream,c); + } + virtual ~TestClass(){} + virtual bool operator==(const TestClass& other) + { + return (a == other.a && + b == other.b && + c.size() == other.c.size() && + c[0] == other.c[0] && + c[1] == other.c[1] && + c[2] == other.c[2]); + } + private: + int a; + std::string b; + std::vector c; +}; + +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 vec; + vec.push_back(134); + vec.push_back(265); + std::list list; + list.push_back(true); + list.push_back(false); + std::pair pair; + pair.first = -23; + pair.second = 1234; + std::map map; + map.insert(std::pair(45, "ALA MA CZARNEGO KOTA")); + map.insert(std::pair(-78, "...A MOZE\nMA\nWIELE LINIJEK")); + BinaryStream stream; + DPL::Serialization::Serialize(stream,vec); + DPL::Serialization::Serialize(stream,list); + DPL::Serialization::Serialize(stream,pair); + DPL::Serialization::Serialize(stream,map); + std::vector test_vec; + DPL::Deserialization::Deserialize(stream,test_vec); + RUNNER_ASSERT(test_vec.size() == vec.size() && + test_vec[0] == vec[0] && test_vec[1] == vec[1]); + std::list test_list; + DPL::Deserialization::Deserialize(stream,test_list); + RUNNER_ASSERT(test_list.size() == list.size() && + test_list.front() == list.front() && + test_list.back() == test_list.back()); + std::pair test_pair; + DPL::Deserialization::Deserialize(stream,test_pair); + RUNNER_ASSERT(test_pair.first == pair.first && + test_pair.second == pair.second); + std::map test_map; + DPL::Deserialization::Deserialize(stream,test_map); + RUNNER_ASSERT(test_map.size() == map.size() && + test_map.at(45) == map.at(45) && + test_map.at(-78) == map.at(-78)); +} + +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 > map; + std::vector vec; + vec.push_back(new TestClass(123,"ASDGHUADB\n\n5679b^^()*","TEST_STRING")); + vec.push_back(new TestClass(679,"HUSPIDNSAHDPA","\nASDSADASD\naDSADASD8")); + map.insert(std::pair >("KEY1",vec)); + map.insert(std::pair >("KEY2",vec)); + BinaryStream stream; + + DPL::Serialization::Serialize(stream, map); + + std::map > test_map; + DPL::Deserialization::Deserialize(stream,test_map); + RUNNER_ASSERT(map.size() == test_map.size()); + std::vector test_vec1,test_vec2; + test_vec1 = map.at("KEY1"); + test_vec2 = test_map.at("KEY1"); + RUNNER_ASSERT(test_vec1.size() == test_vec2.size()); + unsigned i; + for (i = 0; i < test_vec1.size(); ++i) + { + RUNNER_ASSERT((*test_vec1[i]) == (*test_vec2[i])); + } + test_vec1 = map.at("KEY2"); + test_vec2 = test_map.at("KEY2"); + RUNNER_ASSERT(test_vec1.size() == test_vec2.size()); + for (i = 0; i < test_vec1.size(); ++i) + { + RUNNER_ASSERT((*test_vec1[i]) == (*test_vec2[i])); + } +} + diff --git a/tests/core/test_shared_ptr.cpp b/tests/core/test_shared_ptr.cpp new file mode 100644 index 0000000..541a333 --- /dev/null +++ b/tests/core/test_shared_ptr.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_shared_ptr.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of test shared ptr + */ +#include +#include + +RUNNER_TEST_GROUP_INIT(DPL) + +RUNNER_TEST(SharedPtr_Zero) +{ + DPL::SharedPtr ptr; + + RUNNER_ASSERT(!ptr); + RUNNER_ASSERT(!!!ptr); + RUNNER_ASSERT(ptr == DPL::SharedPtr()); +} + +RUNNER_TEST(SharedPtr_NonZero) +{ + DPL::SharedPtr ptr(new char(7)); + + RUNNER_ASSERT(ptr); + RUNNER_ASSERT(!!ptr); + RUNNER_ASSERT(ptr != DPL::SharedPtr()); +} + +RUNNER_TEST(SharedPtr_Copy) +{ + DPL::SharedPtr ptr1(new char(7)); + DPL::SharedPtr ptr2(new char(7)); + + RUNNER_ASSERT(ptr1 != ptr2); + + ptr2 = ptr1; + + RUNNER_ASSERT(ptr1 == ptr2); +} + +RUNNER_TEST(SharedPtr_Reset) +{ + DPL::SharedPtr ptr(new char(7)); + ptr.Reset(); + + RUNNER_ASSERT(!ptr); + + ptr.Reset(new char); + RUNNER_ASSERT(ptr); +} + +RUNNER_TEST(SharedPtr_RefCounting) +{ + DPL::SharedPtr ptr1(new char(7)); + DPL::SharedPtr ptr2; + + ptr2 = ptr1; + + RUNNER_ASSERT(ptr1 == ptr2); + RUNNER_ASSERT(ptr1.GetUseCount() == ptr2.GetUseCount()); + RUNNER_ASSERT(ptr1.GetUseCount() == 2); +} + +RUNNER_TEST(SharedPtr_Operators) +{ + DPL::SharedPtr ptr(new char(7)); + + RUNNER_ASSERT(*ptr == *ptr.Get()); +} diff --git a/tests/core/test_string.cpp b/tests/core/test_string.cpp new file mode 100644 index 0000000..dea0a22 --- /dev/null +++ b/tests/core/test_string.cpp @@ -0,0 +1,384 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_string.cpp + * @author Piotr Marcinkiewicz (p.marcinkiew@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of string tests + */ +#include +#include +#include +#include +#include +#include +#include + +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(&inStr)); + RUNNER_ASSERT(inSize > 0); + RUNNER_ASSERT(NULL != inStr); + char* outStr = NULL; + int outSize = wbxml_base64_decode(utf8Encoded, &outStr); + RUNNER_ASSERT(outSize > 0); + RUNNER_ASSERT(NULL != outStr); + outStr[outSize] = '\0'; + { + DPL::String utfString = DPL::FromUTF32String(inStr); + std::string result = DPL::ToUTF8String(utfString); + + RUNNER_ASSERT(strlen(outStr) == result.size()); + RUNNER_ASSERT(0 == memcmp(outStr, result.c_str(), result.size())); + + + RUNNER_ASSERT(inSize / sizeof(wchar_t) - 1 == utfString.size()); + RUNNER_ASSERT(0 == memcmp(inStr, &(utfString[0]), utfString.size() * sizeof(wchar_t))); + + } + + free(inStr); +} + +template +void String_TokenizeReal(const DelimiterType& delimiter) +{ + DPL::String str(L".##..abc.#."); + std::vector tokens; + DPL::Tokenize(str, delimiter, std::back_inserter(tokens)); + + std::vector expectedTokens; + for ( int i = 0 ; i < 5 ; i++ ) + expectedTokens.push_back(L""); + expectedTokens.push_back(L"abc"); + for ( int i = 0 ; i < 3 ; i++ ) + expectedTokens.push_back(L""); + + RUNNER_ASSERT(expectedTokens == tokens); + tokens.clear(); + expectedTokens.clear(); + + DPL::Tokenize(str, delimiter, std::back_inserter(tokens), true); + expectedTokens.push_back(L"abc"); + RUNNER_ASSERT(expectedTokens == tokens); +} + +RUNNER_TEST(String_Tokenize) +{ + String_TokenizeReal(L"#."); + String_TokenizeReal(L".#"); + String_TokenizeReal(L".....####.###.."); + String_TokenizeReal(DPL::String(L".#")); + + std::vector tokens; + DPL::Tokenize(std::string("abc.def"), '.', std::back_inserter(tokens)); + std::vector expectedTokens; + expectedTokens.push_back("abc"); + expectedTokens.push_back("def"); + + RUNNER_ASSERT(tokens == expectedTokens); +} + +template +void TestInStreams( + std::basic_string argumentInString, + std::basic_string argumentResultString) +{ + typedef std::basic_string + String; + std::basic_istringstream + istream(argumentInString); + int intValue = 0; + double doubleValue = 0.0; + float floatValue = 0.0; + String stringValue; + + istream >> intValue; + RUNNER_ASSERT(!istream.fail()); + istream >> doubleValue; + RUNNER_ASSERT(!istream.fail()); + istream >> floatValue; + RUNNER_ASSERT(!istream.fail()); + istream >> stringValue; + RUNNER_ASSERT(!istream.fail()); + + RUNNER_ASSERT(1 == intValue); + RUNNER_ASSERT(fabs(1.1f - doubleValue) < 0.00001); + RUNNER_ASSERT(fabs(1.1f - floatValue) < 0.00001); + RUNNER_ASSERT(argumentResultString == stringValue); +} + +template +void TestOutStreams( + std::basic_string argumentInString, + std::basic_string argumentResultString) +{ + typedef std::basic_string + String; + + std::basic_ostringstream + ostream; + + int intValue = 1; + double doubleValue = 1.1; + float floatValue = 1.1f; + String stringValue = argumentInString; + + ostream << intValue; + RUNNER_ASSERT(!ostream.fail()); + ostream << doubleValue; + RUNNER_ASSERT(!ostream.fail()); + ostream << floatValue; + RUNNER_ASSERT(!ostream.fail()); + ostream << stringValue; + RUNNER_ASSERT(!ostream.fail()); + + RUNNER_ASSERT(ostream.str() == argumentResultString); +} + +RUNNER_TEST(String_Streams) +{ + TestInStreams >("1 1.1 1.1 test", "test"); + TestInStreams >(L"1 1.1 1.1 test", L"test"); + TestInStreams(L"1 1.1 1.1 test", L"test"); + TestOutStreams >("test", "11.11.1test"); + TestOutStreams >(L"test", L"11.11.1test"); + TestOutStreams(L"test", L"11.11.1test"); +} + +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); +} + diff --git a/tests/core/test_task.cpp b/tests/core/test_task.cpp new file mode 100644 index 0000000..4ad00c3 --- /dev/null +++ b/tests/core/test_task.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_task.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of task tests + */ +#include +#include +#include + +RUNNER_TEST_GROUP_INIT(DPL) + +class MySingleTask + : public DPL::TaskDecl +{ +protected: + void StepOne() + { + } + +public: + MySingleTask() + : DPL::TaskDecl(this) + { + AddStep(&MySingleTask::StepOne); + } +}; + +class MyMultiTask + : public DPL::MultiTaskDecl +{ +protected: + typedef DPL::MultiTaskDecl BaseType; + + void StepOne() + { + 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()); +} diff --git a/tests/core/test_thread.cpp b/tests/core/test_thread.cpp new file mode 100644 index 0000000..202d468 --- /dev/null +++ b/tests/core/test_thread.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_thread.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of thread tests + */ +#include +#include +#include + +RUNNER_TEST_GROUP_INIT(DPL) + +bool g_wasFooDeleted; + +class Foo +{ +public: + int id; + Foo(int i=0): id(i) + { + LogInfo("Foo: ctor: " << id); + } + + ~Foo() + { + LogInfo("Foo: dtor: " << id); + g_wasFooDeleted = true; + } + + void Bar() + { + LogInfo("Foo: bar"); + } +}; + +typedef DPL::ThreadLocalVariable 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()); +} diff --git a/tests/core/test_type_list.cpp b/tests/core/test_type_list.cpp new file mode 100644 index 0000000..98167f3 --- /dev/null +++ b/tests/core/test_type_list.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file test_type_list.cpp + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 0.1 + * @brief + */ + +#include +#include + +RUNNER_TEST_GROUP_INIT(DPL) + +RUNNER_TEST(TypeList_TypeCount) +{ + typedef DPL::TypeListDecl::Type TestTypeList1; + typedef DPL::TypeListDecl::Type TestTypeList2; + typedef DPL::TypeListDecl<>::Type TestTypeList3; + typedef DPL::TypeList TestTypeList4; + + RUNNER_ASSERT(TestTypeList1::Size == 3); + RUNNER_ASSERT(TestTypeList2::Size == 1); + RUNNER_ASSERT(TestTypeList3::Size == 0); + RUNNER_ASSERT(TestTypeList4::Size == 4); + + RUNNER_ASSERT(TestTypeList4::Tail::Tail::Size == 2); +} diff --git a/tests/core/test_zip_input.cpp b/tests/core/test_zip_input.cpp new file mode 100644 index 0000000..9498e76 --- /dev/null +++ b/tests/core/test_zip_input.cpp @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_zip_input.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of zip input tests + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace { +const char* PATH_NO_FILE = "/opt/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 data(new char[buffer.Size() + 1]); + buffer.Flatten(data.Get(), buffer.Size()); + data[buffer.Size()] = '\0'; + + RUNNER_ASSERT(std::string(data.Get()) == "test"); +} diff --git a/tests/db/CMakeLists.txt b/tests/db/CMakeLists.txt new file mode 100644 index 0000000..5276c06 --- /dev/null +++ b/tests/db/CMakeLists.txt @@ -0,0 +1,76 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 diff --git a/tests/db/main.cpp b/tests/db/main.cpp new file mode 100644 index 0000000..4ed6191 --- /dev/null +++ b/tests/db/main.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file main.cpp + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of main. + */ + +#include + +int main(int argc, char *argv[]) +{ + return DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv); +} diff --git a/tests/db/orm/CMakeLists.txt b/tests/db/orm/CMakeLists.txt new file mode 100644 index 0000000..5526a76 --- /dev/null +++ b/tests/db/orm/CMakeLists.txt @@ -0,0 +1,9 @@ + +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 ) diff --git a/tests/db/orm/dpl_orm_test.db b/tests/db/orm/dpl_orm_test.db new file mode 100644 index 0000000..6c3d768 Binary files /dev/null and b/tests/db/orm/dpl_orm_test.db differ diff --git a/tests/db/orm/dpl_orm_test_db b/tests/db/orm/dpl_orm_test_db new file mode 100644 index 0000000..43e0c77 --- /dev/null +++ b/tests/db/orm/dpl_orm_test_db @@ -0,0 +1,38 @@ + +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"); +) diff --git a/tests/db/orm/dpl_orm_test_db.sql b/tests/db/orm/dpl_orm_test_db.sql new file mode 100644 index 0000000..ff143bb --- /dev/null +++ b/tests/db/orm/dpl_orm_test_db.sql @@ -0,0 +1,38 @@ + + + + +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"); + + diff --git a/tests/db/orm/dpl_orm_test_db_definitions b/tests/db/orm/dpl_orm_test_db_definitions new file mode 100644 index 0000000..da79427 --- /dev/null +++ b/tests/db/orm/dpl_orm_test_db_definitions @@ -0,0 +1,5 @@ +DATABASE_START(dpl_orm_test) + +#include "dpl_orm_test_db" + +DATABASE_END() diff --git a/tests/db/orm/dpl_orm_test_db_sql_generator.h b/tests/db/orm/dpl_orm_test_db_sql_generator.h new file mode 100644 index 0000000..d045a39 --- /dev/null +++ b/tests/db/orm/dpl_orm_test_db_sql_generator.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file dpl_orm_test_db_sql_generator.h + * @author Lukasz Marek (l.marek@samsung.com) + * @version 1.0 + * @brief Macro definitions for generating the SQL input file from database definition. + */ + +//Do not include this file directly! It is used only for SQL code generation. + +#include + +#include "dpl_orm_test_db_definitions" diff --git a/tests/db/orm/generator_dpl_orm_test.h b/tests/db/orm/generator_dpl_orm_test.h new file mode 100644 index 0000000..39bb1b7 --- /dev/null +++ b/tests/db/orm/generator_dpl_orm_test.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ORM_GENERATOR_DPL_ORM_TEST_H +#define ORM_GENERATOR_DPL_ORM_TEST_H + +#define ORM_GENERATOR_DATABASE_NAME dpl_orm_test_db_definitions +#include +#undef ORM_GENERATOR_DATABASE_NAME + +#endif diff --git a/tests/db/test_orm.cpp b/tests/db/test_orm.cpp new file mode 100644 index 0000000..ddcbe79 --- /dev/null +++ b/tests/db/test_orm.cpp @@ -0,0 +1,712 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include + +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 +bool ContainerContentsEqual(const ContainerType1& container1, const ContainerType2& container2) +{ + using namespace DPL::DB::ORM::dpl_orm_test::TestTableInsert; + typedef std::set Set1; + typedef std::set Set2; + Set1 set1(container1.begin(), container1.end()); + Set2 set2(container2.begin(), container2.end()); + + for (typename Set1::iterator it = set1.begin(); + it != set1.end(); + it++) + { + LogDebug("Set1 element: " << *it); + } + + for (typename Set2::iterator it = set2.begin(); it != set2.end(); it++) + { + LogDebug("Set2 element: " << *it); + } + + return set1 == set2; +} + +template +std::list makeList(const T& a, const T& b) +{ + std::list list; + list.push_back(a); + list.push_back(b); + return list; +} + +//tests + +RUNNER_TEST_GROUP_INIT(DPL) + +RUNNER_TEST(ORM_SelectSingleValue) +{ + SmartAttach interface; + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::dpl_orm_test; + //Getting each column + { + TestTable::Select select(interface.get()); + select.Where(Equals(8)); + int result; + RUNNER_ASSERT_MSG((result = *select.GetSingleValue()) == 6, "Got " << result); + } + { + TestTable::Select select(interface.get()); + select.Where(Equals(8)); + DPL::String result; + RUNNER_ASSERT_MSG((result = *select.GetSingleValue()) == L"seven", "Got " << result); + } + { + TestTable::Select select(interface.get()); + select.Where(Equals(8)); + int result; + RUNNER_ASSERT_MSG((result = select.GetSingleValue()) == 8, "Got " << result); + } + { + TestTable::Select select(interface.get()); + select.Where(Equals(8)); + int result; + RUNNER_ASSERT_MSG((result = select.GetSingleValue()) == 9, "Got " << result); + } + { + TestTable::Select select(interface.get()); + select.Where(Equals(8)); + DPL::String result; + RUNNER_ASSERT_MSG((result = select.GetSingleValue()) == L"ten", "Got " << result); + } + + //Where on each column + { + TestTable::Select select(interface.get()); + select.Where(Equals(6)); + int result; + RUNNER_ASSERT_MSG((result = *select.GetSingleValue()) == 6, "Got " << result); + } + { + TestTable::Select select(interface.get()); + select.Where(Equals(DPL::String(L"seven"))); + DPL::String result; + RUNNER_ASSERT_MSG((result = *select.GetSingleValue()) == L"seven", "Got " << result); + } + { + TestTable::Select select(interface.get()); + select.Where(Equals(8)); + int result; + RUNNER_ASSERT_MSG((result = select.GetSingleValue()) == 8, "Got " << result); + } + { + TestTable::Select select(interface.get()); + select.Where(Equals(9)); + int result; + RUNNER_ASSERT_MSG((result = select.GetSingleValue()) == 9, "Got " << result); + } + { + TestTable::Select select(interface.get()); + select.Where(Equals(L"ten")); + DPL::String result; + RUNNER_ASSERT_MSG((result = select.GetSingleValue()) == L"ten", "Got " << result); + } +} + +RUNNER_TEST(ORM_SelectSingleRow) +{ + SmartAttach interface; + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::dpl_orm_test; + { + TestTable::Select select(interface.get()); + select.Where(Equals(3)); + TestTable::Row result = select.GetSingleRow(); + TestTable::Row expected; + expected.Set_ColumnOptInt(1); + expected.Set_ColumnOptText(DPL::String(L"two")); + expected.Set_ColumnInt(3); + expected.Set_ColumnInt2(4); + expected.Set_ColumnText(L"five"); + RUNNER_ASSERT_MSG(result == expected, "Got " << result); + } + + { + TestTable::Select select(interface.get()); + select.Where(Equals(DPL::String(L"seven"))); + TestTable::Row result = select.GetSingleRow(); + TestTable::Row expected; + expected.Set_ColumnOptInt(6); + expected.Set_ColumnOptText(DPL::String(L"seven")); + expected.Set_ColumnInt(8); + expected.Set_ColumnInt2(9); + expected.Set_ColumnText(L"ten"); + RUNNER_ASSERT_MSG(result == expected, "Got " << result); + } +} + +RUNNER_TEST(ORM_SelectRowList) +{ + SmartAttach interface; + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::dpl_orm_test; + { + TestTable::Select select(interface.get()); + select.Where(Equals(3)); + std::list result = select.GetRowList(); + RUNNER_ASSERT_MSG(result.size() == 1, "Got " << result.size()); + + TestTable::Row expected; + expected.Set_ColumnOptInt(1); + expected.Set_ColumnOptText(DPL::String(L"two")); + expected.Set_ColumnInt(3); + expected.Set_ColumnInt2(4); + expected.Set_ColumnText(L"five"); + RUNNER_ASSERT_MSG(*(result.begin()) == expected, "Got " << *(result.begin()) ); + } + + { + TestTable::Select select(interface.get()); + select.Where(Equals(DPL::String(L"seven"))); + std::list result = select.GetRowList(); + RUNNER_ASSERT_MSG(result.size() == 1, "Got " << result.size()); + + TestTable::Row expected; + expected.Set_ColumnOptInt(6); + expected.Set_ColumnOptText(DPL::String(L"seven")); + expected.Set_ColumnInt(8); + expected.Set_ColumnInt2(9); + expected.Set_ColumnText(L"ten"); + RUNNER_ASSERT_MSG(*(result.begin()) == expected, "Got " << *(result.begin()) ); + } + + { + TestTable::Select select(interface.get()); + select.Where(Equals(99)); + std::list result = select.GetRowList(); + + TestTable::Row expected1; + expected1.Set_ColumnInt(99); + expected1.Set_ColumnInt2(11); + expected1.Set_ColumnText(L"twelve"); + + TestTable::Row expected2; + expected2.Set_ColumnInt(99); + expected2.Set_ColumnInt2(13); + expected2.Set_ColumnText(L"fourteen"); + + RUNNER_ASSERT(ContainerContentsEqual(makeList(expected1, expected2), result)); + } +} + +RUNNER_TEST(ORM_SelectValueList) +{ + SmartAttach interface; + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::dpl_orm_test; + //Getting each column + { + TestTable::Select select(interface.get()); + select.Where(Is(DPL::Optional::Null)); + RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList(), + makeList(99, 99))); + } + { + TestTable::Select select(interface.get()); + select.Where(Is(DPL::Optional::Null)); + RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList(), + makeList(11, 13))); + } + { + TestTable::Select select(interface.get()); + select.Where(Is(DPL::Optional::Null)); + RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList(), + makeList(DPL::String(L"twelve"), DPL::String(L"fourteen")))); + } + { + TestTable::Select select(interface.get()); + select.Where(Is(DPL::Optional::Null)); + RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList(), + makeList(DPL::Optional::Null,DPL::Optional::Null))); + } + + //Where on each column + { + TestTable::Select select(interface.get()); + select.Where(Is(DPL::Optional::Null)); + RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList(), + makeList(11, 13))); + } + { + TestTable::Select select(interface.get()); + select.Where(Is(DPL::Optional::Null)); + RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList(), + makeList(11, 13))); + } + { + TestTable::Select select(interface.get()); + select.Where(Is(99)); + RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList(), + makeList(11, 13))); + } +} + +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 resultList = select1.GetValueList(); + RUNNER_ASSERT_MSG(resultList.size() == 0, "Returned list has wrong size: " << resultList.size()); + std::list list; + + TestTableInsert::Insert insert(interface.get()); + TestTableInsert::Row row; + row.Set_ColumnOptInt(1); + row.Set_ColumnInt2(2); + row.Set_ColumnText(L"three"); + insert.Values(row); + insert.Execute(); + + row.Set_ColumnInt(99); + list.push_back(row); + { + TestTableInsert::Select select2(interface.get()); + RUNNER_ASSERT_MSG(ContainerContentsEqual(select2.GetRowList(), list), "Returned list doesn't match."); + } + + TestTableInsert::Insert insert2(interface.get()); + TestTableInsert::Row row2; + row2.Set_ColumnInt(4); + row2.Set_ColumnInt2(5); + row2.Set_ColumnText(L"six"); + insert2.Values(row2); + insert2.Execute(); + + list.push_back(row2); + { + TestTableInsert::Select select(interface.get()); + RUNNER_ASSERT_MSG(ContainerContentsEqual(select.GetRowList(), list), "Returned list doesn't match."); + } + + TestTableInsert::Insert insert3(interface.get()); + TestTableInsert::Row row3; + row3.Set_ColumnOptInt(1); + row3.Set_ColumnInt2(7); + row3.Set_ColumnText(L"eight"); + insert3.Values(row3); + insert3.Execute(); + + row3.Set_ColumnInt(99); + list.push_back(row3); + { + TestTableInsert::Select select3(interface.get()); + RUNNER_ASSERT_MSG(ContainerContentsEqual(select3.GetRowList(), list), "Returned list doesn't match."); + } + + TestTableInsert::Insert insert4(interface.get()); + TestTableInsert::Row row4; + row4.Set_ColumnOptInt(9); + row4.Set_ColumnInt2(10); + row4.Set_ColumnText(L"eleven"); + insert4.Values(row4); + insert4.Execute(); + + row4.Set_ColumnInt(99); + list.push_back(row4); + { + TestTableInsert::Select select4(interface.get()); + RUNNER_ASSERT_MSG(ContainerContentsEqual(select4.GetRowList(), list), "Returned list doesn't match."); + } + + // restore original table state + { + TestTableInsert::Delete del(interface.get()); + del.Execute(); + + TestTableInsert::Select select(interface.get()); + RUNNER_ASSERT(select.GetRowList().size() == 0); + } +} + +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 list = selectStart.GetRowList(); + std::list originalList = list; + + std::vector vector(list.begin(), list.end()); + RUNNER_ASSERT_MSG(list.size() == 4, "Returned list has wrong size: " << list.size()); + + typedef DPL::String S; + + //no-act deletes + { + TestTableDelete::Delete del(interface.get()); + del.Where(And(Equals(1), Equals(S(L"seven")))); + del.Execute(); + + TestTableDelete::Select select(interface.get()); + RUNNER_ASSERT_MSG(ContainerContentsEqual(select.GetRowList(), list), "Returned list doesn't match."); + } + + { + TestTableDelete::Delete del(interface.get()); + del.Where(And(Equals(6), Equals(S(L"two")))); + del.Execute(); + + TestTableDelete::Select select(interface.get()); + RUNNER_ASSERT_MSG(ContainerContentsEqual(select.GetRowList(), list), "Returned list doesn't match."); + } + + { + TestTableDelete::Delete del(interface.get()); + del.Where(Equals(10)); + del.Execute(); + + TestTableDelete::Select select(interface.get()); + RUNNER_ASSERT_MSG(ContainerContentsEqual(select.GetRowList(), list), "Returned list doesn't match."); + } + + //act deletes + { + list.remove(vector[1]); + + TestTableDelete::Delete del(interface.get()); + del.Where(And(Equals(6), Equals(L"ten"))); + del.Execute(); + + TestTableDelete::Select select(interface.get()); + RUNNER_ASSERT_MSG(ContainerContentsEqual(select.GetRowList(), list), "Returned list doesn't match."); + } + + { + list.remove(vector[2]); + list.remove(vector[3]); + + TestTableDelete::Delete del(interface.get()); + del.Where(Is(DPL::Optional::Null)); + del.Execute(); + + TestTableDelete::Select select(interface.get()); + RUNNER_ASSERT_MSG(ContainerContentsEqual(select.GetRowList(), list), "Returned list doesn't match."); + } + + { + TestTableDelete::Delete del(interface.get()); + del.Execute(); + + TestTableDelete::Select select(interface.get()); + RUNNER_ASSERT_MSG(select.GetRowList().size() == 0, "Returned list is not empty"); + } + + // Restore original table state + // This also tests if multiple different binds for Insert are working properly + for (std::list::iterator i = originalList.begin(); i != originalList.end(); i++) + { + TestTableDelete::Insert insert(interface.get()); + insert.Values(*i); + insert.Execute(); + } + + { + TestTableDelete::Select select(interface.get()); + RUNNER_ASSERT_MSG(ContainerContentsEqual(select.GetRowList(), originalList), "Returned list doesn't match."); + } + +} + +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(8)); + RUNNER_ASSERT_MSG((result = *select.GetSingleValue()) == 6, "Got " << result); + + select.Where(Equals(3)); + RUNNER_ASSERT_MSG((result = *select.GetSingleValue()) == 1, "Got " << result); + + select.Where(Equals(8)); + RUNNER_ASSERT_MSG((result = *select.GetSingleValue()) == 6, "Got " << result); + + select.Where(Equals(3)); + RUNNER_ASSERT_MSG((result = *select.GetSingleValue()) == 1, "Got " << result); + } + + { + TestTable::Select select(interface.get()); + int result; + select.Where(And(Equals(99), + Equals(L"fourteen"))); + RUNNER_ASSERT_MSG((result = select.GetSingleValue()) == 13, "Got " << result); + + select.Where(And(Equals(99), + Equals(L"twelve"))); + RUNNER_ASSERT_MSG((result = select.GetSingleValue()) == 11, "Got " << result); + + select.Where(And(Equals(99), + Equals(L"fourteen"))); + RUNNER_ASSERT_MSG((result = select.GetSingleValue()) == 13, "Got " << result); + + select.Where(And(Equals(99), + Equals(L"twelve"))); + RUNNER_ASSERT_MSG((result = select.GetSingleValue()) == 11, "Got " << result); + } + + { + TestTable::Select select(interface.get()); + int result; + select.Where(And(Equals(L"fourteen"), + Equals(99))); + RUNNER_ASSERT_MSG((result = select.GetSingleValue()) == 13, "Got " << result); + + select.Where(And(Equals(L"twelve"), + Equals(99))); + RUNNER_ASSERT_MSG((result = select.GetSingleValue()) == 11, "Got " << result); + + select.Where(And(Equals(L"fourteen"), + Equals(99))); + RUNNER_ASSERT_MSG((result = select.GetSingleValue()) == 13, "Got " << result); + + select.Where(And(Equals(L"twelve"), + Equals(99))); + RUNNER_ASSERT_MSG((result = select.GetSingleValue()) == 11, "Got " << result); + + } + +} + +RUNNER_TEST(ORM_Update) +{ + SmartAttach interface; + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::dpl_orm_test; + + std::list list; + + TestTableInsert::Delete del(interface.get()); + del.Execute(); + + // INSERT + { + TestTableInsert::Insert insert(interface.get()); + TestTableInsert::Row row; + row.Set_ColumnOptInt(5); + row.Set_ColumnInt2(2); + row.Set_ColumnText(L"two"); + insert.Values(row); + insert.Execute(); + + row.Set_ColumnInt(99); + list.push_back(row); + } + { + TestTableInsert::Insert insert(interface.get()); + TestTableInsert::Row row; + row.Set_ColumnOptInt(1); + row.Set_ColumnInt2(2); + row.Set_ColumnText(L"three"); + insert.Values(row); + insert.Execute(); + + row.Set_ColumnInt(99); + list.push_back(row); + } + { + TestTableInsert::Insert insert(interface.get()); + TestTableInsert::Row row; + row.Set_ColumnOptInt(2); + row.Set_ColumnInt2(3); + row.Set_ColumnText(L"three"); + insert.Values(row); + insert.Execute(); + + row.Set_ColumnInt(99); + list.push_back(row); + + // CHECK + TestTableInsert::Select select(interface.get()); + RUNNER_ASSERT_MSG(ContainerContentsEqual(select.GetRowList(), list), "Returned list doesn't match."); + } + { + // UPDATE - no rows + TestTableInsert::Update update(interface.get()); + TestTableInsert::Row row; + row.Set_ColumnInt2(4); + row.Set_ColumnText(L"four"); + update.Values(row); + update.Where(Equals(12)); + update.Execute(); + + // CHECK + TestTableInsert::Select select(interface.get()); + RUNNER_ASSERT_MSG(ContainerContentsEqual(select.GetRowList(), list), "Returned list doesn't match."); + } + { + // UPDATE - one row + TestTableInsert::Update update(interface.get()); + TestTableInsert::Row row; + row.Set_ColumnInt2(2); + row.Set_ColumnText(L"four"); + update.Values(row); + update.Where(Equals(3)); + update.Execute(); + + list.back().Set_ColumnInt2(2); + list.back().Set_ColumnText(L"four"); + + // CHECK + TestTableInsert::Select select(interface.get()); + RUNNER_ASSERT_MSG(ContainerContentsEqual(select.GetRowList(), list), "Returned list doesn't match."); + } + + { + // UPDATE - multiple rows + TestTableInsert::Update update(interface.get()); + TestTableInsert::Row row; + row.Set_ColumnText(L"dup"); + update.Values(row); + update.Where(Equals(2)); + update.Execute(); + + FOREACH(it, list) + { + it->Set_ColumnText(L"dup"); + } + + // CHECK + TestTableInsert::Select select(interface.get()); + RUNNER_ASSERT_MSG(ContainerContentsEqual(select.GetRowList(), list), "Returned list doesn't match."); + } + + // restore original table state + { + TestTableInsert::Delete del2(interface.get()); + del2.Execute(); + + TestTableInsert::Select select(interface.get()); + RUNNER_ASSERT(select.GetRowList().size() == 0); + } +} + +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."); +} diff --git a/tests/db/test_sql_connection.cpp b/tests/db/test_sql_connection.cpp new file mode 100644 index 0000000..8dd3316 --- /dev/null +++ b/tests/db/test_sql_connection.cpp @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_sql_connection.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of sql connection tests + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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(m_prefix); + valueStream << "_"; + valueStream << static_cast(i); + + std::string value = valueStream.str(); + + connection.ExecCommand( + "INSERT INTO test VALUES ('%s');", + value.c_str()); + + countCommand->BindString(1, value.c_str()); + + RUNNER_ASSERT(countCommand->Step()); + + RUNNER_ASSERT(countCommand->GetColumnString(0) == "1"); + + countCommand->Reset(); + } + + countCommand.reset(); + + return 0; + } + +public: + StressGenerator(size_t prefix, + const std::string &dbFileName, + AbstractSynchronizationObjectGenerator *generator) + : m_prefix(prefix), + m_dbFileName(dbFileName), + m_generator(generator) + { + } +}; + +typedef DPL::SharedPtr 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); +} diff --git a/tests/dbus/CMakeLists.txt b/tests/dbus/CMakeLists.txt new file mode 100644 index 0000000..accd45a --- /dev/null +++ b/tests/dbus/CMakeLists.txt @@ -0,0 +1,98 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file 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 +) diff --git a/tests/dbus/data/org.tizen.DBusTestService.service b/tests/dbus/data/org.tizen.DBusTestService.service new file mode 100644 index 0000000..f024543 --- /dev/null +++ b/tests/dbus/data/org.tizen.DBusTestService.service @@ -0,0 +1,3 @@ +[D-BUS Service] +Name=org.tizen.DBusTestService +Exec=/usr/bin/dpl-dbus-test-service diff --git a/tests/dbus/dbus_test.cpp b/tests/dbus/dbus_test.cpp new file mode 100644 index 0000000..6071f9f --- /dev/null +++ b/tests/dbus/dbus_test.cpp @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file dbus_test.cpp + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @brief Implementation file for DBusTest and DBusTestManager. + */ + +#include +#include "loop_control.h" +#include "dbus_test.h" + +DBusTest::DBusTest(const std::string& name) + : m_name(name), + m_status(Status::NONE) +{ +} + +void DBusTest::run(unsigned int timeout) +{ + DPL::Event::ControllerEventHandler::Touch(); + DPL::Event::ControllerEventHandler::Touch(); + + DPL::Event::ControllerEventHandler::PostTimedEvent( + TimeoutEvent(), timeout); + + LoopControl::wrt_start_loop(); + + switch (m_status) + { + case Status::FAILED: + throw DPL::Test::TestRunner::TestFailed(m_name.c_str(), + __FILE__, + __LINE__, + m_message); + + default: + break; + } +} + +void DBusTest::quit() +{ + DPL::Event::ControllerEventHandler::PostEvent(QuitEvent()); +} + +void DBusTest::setStatus(Status status) +{ + m_status = status; +} + +void DBusTest::setMessage(const std::string& message) +{ + m_message = message; +} + +void DBusTest::success() +{ + m_status = Status::SUCCESS; +} + +void DBusTest::fail(const std::string& message) +{ + m_status = Status::FAILED; + m_message = message; +} + +void DBusTest::OnEventReceived(const TimeoutEvent& /*event*/) +{ + fail("Test timed out."); + + // Saving one event dispatch since Quit and Timeout work on the same thread. + LoopControl::wrt_end_loop(); +} + +void DBusTest::OnEventReceived(const QuitEvent& /*event*/) +{ + LoopControl::wrt_end_loop(); +} + +DBusTestManager& DBusTestManager::getInstance() +{ + static DBusTestManager instance; + return instance; +} + +DBusTestManager::DBusTestManager() : m_test(NULL) { } + +DBusTest& DBusTestManager::getCurrentTest() const +{ + Assert(NULL != m_test && "Test not set."); + + return *m_test; +} + +void DBusTestManager::setCurrentTest(DBusTest& test) +{ + m_test = &test; +} + +void DBusTestManager::clear() +{ + m_test = NULL; +} diff --git a/tests/dbus/dbus_test.h b/tests/dbus/dbus_test.h new file mode 100644 index 0000000..9b5061e --- /dev/null +++ b/tests/dbus/dbus_test.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file dbus_test.h + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @brief Header file for DBusTest and DBusTestManager. + */ + +#ifndef WRT_TESTS_DBUS_TESTS_DBUS_TEST_H +#define WRT_TESTS_DBUS_TESTS_DBUS_TEST_H + +#include +#include +#include + +DECLARE_GENERIC_EVENT_0(QuitEvent) +DECLARE_GENERIC_EVENT_0(TimeoutEvent) + +class DBusTest : + private DPL::Event::Controller::Type> +{ +public: + enum class Status + { + NONE, + SUCCESS, + FAILED + }; + + explicit DBusTest(const std::string& name); + + void run(unsigned int timeout); + void quit(); + + void setStatus(Status status); + void setMessage(const std::string& message); + + void success(); + void fail(const std::string& message = std::string()); + +private: + void OnEventReceived(const TimeoutEvent& event); + void OnEventReceived(const QuitEvent& event); + + std::string m_name; + Status m_status; + std::string m_message; +}; + +class DBusTestManager : private DPL::Noncopyable +{ +public: + static DBusTestManager& getInstance(); + + DBusTest& getCurrentTest() const; + void setCurrentTest(DBusTest& test); + + void clear(); + +private: + DBusTestManager(); + + DBusTest* m_test; +}; + +#define DBUS_TEST(TestProc) \ + void DBus##TestProc(); \ + RUNNER_TEST(TestProc) \ + { \ + DBusTest test(#TestProc); \ + DBusTestManager::getInstance().setCurrentTest(test); \ + DBus##TestProc(); \ + DBusTestManager::getInstance().clear(); \ + } \ + void DBus##TestProc() + +#endif diff --git a/tests/dbus/loop_control.cpp b/tests/dbus/loop_control.cpp new file mode 100644 index 0000000..c6c250e --- /dev/null +++ b/tests/dbus/loop_control.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 + +#include + +#include +#include + + +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 diff --git a/tests/dbus/loop_control.h b/tests/dbus/loop_control.h new file mode 100644 index 0000000..30aa6e8 --- /dev/null +++ b/tests/dbus/loop_control.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file loop_control.cpp + * @author Jaroslaw Osmanski (j.osmanski@samsung.com) + * @version 1.0 + * @brief This file is the definitions of loop controlling utilities + */ + + +#ifndef LOOP_CONTROL_H_ +#define LOOP_CONTROL_H_ + +namespace LoopControl +{ + +void init_loop(int argc, char *argv[]); +void wait_for_wrt_init(); +void finish_wait_for_wrt_init(); +void quit_loop(); + +void wrt_start_loop(); +void wrt_end_loop(); + +void *abstract_window(); + +} + +#endif /* LOOP_CONTROL_H_ */ diff --git a/tests/dbus/main.cpp b/tests/dbus/main.cpp new file mode 100644 index 0000000..b6bd681 --- /dev/null +++ b/tests/dbus/main.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file main.cpp + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of main. + */ + +#include "loop_control.h" +#include +#include + +int main(int argc, char *argv[]) +{ + LoopControl::init_loop(argc, argv); + + LogInfo("Running tests..."); + int status = DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv); + + return status; +} diff --git a/tests/dbus/test_cases.cpp b/tests/dbus/test_cases.cpp new file mode 100644 index 0000000..fe0f9c1 --- /dev/null +++ b/tests/dbus/test_cases.cpp @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file TestCases.cpp + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief Implementation file for test cases for DBus internal tests. + */ + +#include +#include +#include +#include +#include +#include +#include "dbus_test.h" + +namespace { +const std::string dbusServiceName = "org.freedesktop.DBus"; +const std::string dbusObjectPath = "/"; +const std::string dbusInterfaceName = "org.freedesktop.DBus"; +const std::string dbusMethodGetId = "GetId"; + +const std::string serviceName = "org.tizen.DBusTestService"; +const std::string objectPath = "/org/tizen/DBusTestService"; +const std::string interfaceName = "org.tizen.DBusTestService"; +const std::string methodNameEcho = "echo"; +const std::string methodNameQuit = "quit"; +const std::string nodeInfo = + "" + "" + " " + " " + " " + " " + " " + " " + " " + " " + ""; + +const std::string challenge = "Hello world!"; + +const int DEFAULT_TIMEOUT = 2; // in seconds +} + +RUNNER_TEST(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 + (dbusInterfaceName, dbusMethodGetId); + RUNNER_ASSERT(!getId().empty()); + } + catch (const DPL::DBus::Exception& ex) + { + RUNNER_ASSERT_MSG(false, ex.DumpToString()); + } +} + +class RegisterServiceListener : + public DPL::Event::EventListener +{ +public: + void OnEventReceived( + const DPL::DBus::ConnectionEvents::ServiceNameAcquiredEvent& event) + { + DBusTest& test = DBusTestManager::getInstance().getCurrentTest(); + + auto name = event.GetArg0(); + if (serviceName == name) + { + test.success(); + } + else + { + test.fail("Acquired service name: " + name); + } + test.quit(); + } +}; + +DBUS_TEST(RegisterService) +{ + try + { + RegisterServiceListener listener; + + auto connection = DPL::DBus::Connection::sessionBus(); + connection->DPL::Event::EventSupport::AddListener(&listener); + connection->registerService(serviceName); + + DBusTestManager::getInstance().getCurrentTest().run(DEFAULT_TIMEOUT); + } + catch (const DPL::DBus::Exception& ex) + { + RUNNER_ASSERT_MSG(false, ex.DumpToString()); + } +} + +/** + * This test checks: + * - object registration (done on the wrt-dbus-test-service side) + * - service registration (done on the wrt-dbus-test-service side) + * - dispatching method calls (done on the wrt-dbus-test-service side) + * - launching dbus service on demand + * - invoking remote method(s) + */ +DBUS_TEST(InvokeTestService) +{ + try + { + auto connection = DPL::DBus::Connection::sessionBus(); + auto testService = connection->createObjectProxy(serviceName, + objectPath); + auto echo = testService->createMethodProxy + (interfaceName, methodNameEcho); + auto response = echo(challenge); + + testService->createMethodProxy(interfaceName, methodNameQuit)(); + + RUNNER_ASSERT_MSG(response == challenge, + "[challenge = " << challenge << + ", response = " << response << "]"); + } + catch (const DPL::DBus::Exception& ex) + { + RUNNER_ASSERT_MSG(false, ex.DumpToString()); + } +} diff --git a/tests/dbus/test_service.cpp b/tests/dbus/test_service.cpp new file mode 100644 index 0000000..63e32fb --- /dev/null +++ b/tests/dbus/test_service.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file test_service.cpp + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @brief Implementation file for wrt-dbus-test-service. + */ + +#include +#include +#include +#include +#include +#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 = + "" + "" + " " + " " + " " + " " + " " + " " + " " + " " + ""; +} + +class TestServiceDispatcher : public DPL::DBus::Dispatcher +{ +private: + void onMethodCall(GDBusConnection* /*connection*/, + const gchar* /*sender*/, + const gchar* /*objectPath*/, + const gchar* /*interfaceName*/, + const gchar* methodName, + GVariant* parameters, + GDBusMethodInvocation* invocation) + { + if (methodNameEcho == methodName) + { + LogDebug("Echo"); + g_dbus_method_invocation_return_value(invocation, + parameters); + } + else if (methodNameQuit == methodName) + { + LogDebug("Quit"); + g_dbus_method_invocation_return_value(invocation, NULL); + LoopControl::wrt_end_loop(); + } + } +}; + +int main(int argc, char* argv[]) +{ + LoopControl::init_loop(argc, argv); + + TestServiceDispatcher dispatcher; + + auto iface = DPL::DBus::Interface::fromXMLString(nodeInfo).at(0); + iface->setDispatcher(&dispatcher); + + auto object = DPL::DBus::Object::create(objectPath, iface); + + auto connection = DPL::DBus::Connection::sessionBus(); + connection->registerObject(object); + connection->registerService(serviceName); + + LoopControl::wrt_start_loop(); + + return 0; +} diff --git a/tests/event/CMakeLists.txt b/tests/event/CMakeLists.txt new file mode 100644 index 0000000..5be052c --- /dev/null +++ b/tests/event/CMakeLists.txt @@ -0,0 +1,70 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Lukasz Marek (l.marek@samsung.com) +# @version 1.0 +# @brief +# + +# +# 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 diff --git a/tests/event/main.cpp b/tests/event/main.cpp new file mode 100644 index 0000000..4ed6191 --- /dev/null +++ b/tests/event/main.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file main.cpp + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of main. + */ + +#include + +int main(int argc, char *argv[]) +{ + return DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv); +} diff --git a/tests/event/test_controller.cpp b/tests/event/test_controller.cpp new file mode 100644 index 0000000..33bb631 --- /dev/null +++ b/tests/event/test_controller.cpp @@ -0,0 +1,331 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_controller.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of test controller + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +RUNNER_TEST_GROUP_INIT(DPL) + +class IntController + : public DPL::Event::Controller::Type> +{ +private: + int m_value; + +protected: + virtual void OnEventReceived(const int &event) + { + m_value = event; + } + +public: + IntController() + : m_value(-1) + { + } + + int Value() const + { + return m_value; + } +}; + +DECLARE_GENERIC_EVENT_1(DoneSignalEvent, DPL::WaitableEvent *) + +class ThreadController + : public DPL::Event::Controller::Type> +{ +private: + DPL::Thread *m_value; + +protected: + virtual void OnEventReceived(const DoneSignalEvent &event) + { + m_value = DPL::Thread::GetCurrentThread(); + event.GetArg0()->Signal(); + } + +public: + ThreadController() + : m_value(NULL) + { + } + + DPL::Thread *Value() const + { + return m_value; + } +}; + +struct StrangeStruct +{ + int a; + float b; + double c; +}; + +class StrangeController + : public DPL::Event::Controller::Type> +{ +protected: + virtual void OnEventReceived(const char &event) { (void)event; } + virtual void OnEventReceived(const short &event) { (void)event; } + virtual void OnEventReceived(const int &event) { (void)event; } + virtual void OnEventReceived(const long &event) { (void)event; } + virtual void OnEventReceived(const unsigned char &event) { (void)event; } + virtual void OnEventReceived(const unsigned short &event) { (void)event; } + virtual void OnEventReceived(const unsigned int &event) { (void)event; } + virtual void OnEventReceived(const unsigned long &event) { (void)event; } + virtual void OnEventReceived(const float &event) { (void)event; } + virtual void OnEventReceived(const double &event) { (void)event; } + virtual void OnEventReceived(const StrangeStruct &event) { (void)event; } +}; + +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::Type>, + private DPL::Event::Controller::Type> +{ +public: + typedef DPL::Event::Controller::Type> PublicController; + typedef DPL::Event::Controller::Type> PrivateController; + + virtual void OnEventReceived(const TouchInThread &event) + { + // Touch controller in thread + PrivateController::Touch(); + + // Post signal + PrivateController::PostEvent(TouchedControllerSignal(event.GetArg0(), event.GetArg1())); + } + + virtual void OnEventReceived(const TouchedControllerSignal &event) + { + // Return touched thread + *event.GetArg1() = DPL::Thread::GetCurrentThread(); + + // Signal waitable event + event.GetArg0()->Signal(); + } +}; + +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 ControllerPtr; +typedef DPL::SharedPtr ThreadPtr; +typedef std::vector ControllerList; +typedef std::list ThreadList; + +DECLARE_GENERIC_EVENT_0(QuitEvent) +class QuitController + : public DPL::Event::Controller::Type>, + public DPL::ApplicationExt +{ +public: + explicit QuitController( ) : DPL::ApplicationExt(1, NULL, "test-app") { Touch(); } +protected: + virtual void OnEventReceived(const QuitEvent &) { Quit(); } +}; + +struct TestContext +{ + ControllerList controllers; + ThreadList threads; + QuitController quitter; + DPL::Atomic g_ReceivedCounter; + DPL::Atomic g_SentCounter; +}; +typedef DPL::ScopedPtr TestContextPtr; +TestContextPtr testContextPtr; + +DECLARE_GENERIC_EVENT_0(StartSendEvent) +DECLARE_GENERIC_EVENT_0(RandomEvent) +class TestController + : public DPL::Event::Controller::Type> +{ +public: + explicit TestController() { Touch(); } +protected: + virtual void OnEventReceived(const RandomEvent &) + { + ++testContextPtr->g_ReceivedCounter; + if(testContextPtr->g_ReceivedCounter == MaxEvents) + { + testContextPtr->quitter.DPL::Event::ControllerEventHandler::PostEvent(QuitEvent()); + return; + } + } + virtual void OnEventReceived(const StartSendEvent &) + { + for (int i=0 ; ig_SentCounter > MaxEvents) + { + return; + } + ++testContextPtr->g_SentCounter; + int id = rand() % static_cast(testContextPtr->controllers.size()); + testContextPtr->controllers.at(id)->DPL::Event::ControllerEventHandler::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::PostEvent(StartSendEvent()); + } + testContextPtr->quitter.Exec(); + RUNNER_ASSERT(testContextPtr->g_SentCounter == testContextPtr->g_ReceivedCounter); + testContextPtr.Reset(); +} diff --git a/tests/event/test_event_support.cpp b/tests/event/test_event_support.cpp new file mode 100644 index 0000000..af303f0 --- /dev/null +++ b/tests/event/test_event_support.cpp @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_event_support.cpp + * @author Piotr Marcinkiewicz (p.marcinkiew@samsung.com) + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @version 1.0 + * @brief This file contains test for event support + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GENERIC_EVENT_0(TestEvent) + +class TestListener: public DPL::Event::EventListener +{ +public: + explicit TestListener() : m_dummyVar(0) { } + void OnEventReceived(const TestEvent &) { m_dummyVar = 1; } + int GetDummyVar() const { return m_dummyVar; } + void ZeroDummyVar() { m_dummyVar = 0; } + +private: + int m_dummyVar; +}; + +class TestEventSupport + : public DPL::Event::EventSupport +{ +public: + void TestEmitEvent() { EmitEvent(TestEvent()); } +}; + +DECLARE_GENERIC_EVENT_0(QuitEvent) + +class QuitController + : public DPL::Event::Controller::Type>, + public DPL::ApplicationExt +{ +public: + QuitController() : DPL::ApplicationExt(1, NULL, "test-app") { Touch(); } + +protected: + virtual void OnEventReceived(const QuitEvent &) { Quit(); } +}; + +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 +{ +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); +} diff --git a/tests/event/test_ic_delegate.cpp b/tests/event/test_ic_delegate.cpp new file mode 100644 index 0000000..60a5686 --- /dev/null +++ b/tests/event/test_ic_delegate.cpp @@ -0,0 +1,568 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_ic_delegate.cpp + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of fast delegate tests. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +RUNNER_TEST_GROUP_INIT(DPL) + +const int IntVal = 123; +const std::string StringVal = "someString"; + +typedef DPL::Event::ICDelegate<> GetNothingDlpType; +typedef DPL::Event::ICDelegate GetIntDlgType; +typedef DPL::Event::ICDelegate GetIntAndStringDlgType; +DECLARE_GENERIC_EVENT_1(GetNothingEvent, GetNothingDlpType) +DECLARE_GENERIC_EVENT_1(GetIntEvent, GetIntDlgType) +DECLARE_GENERIC_EVENT_1(GetIntAndStringEvent, GetIntAndStringDlgType) + +class ICTestController +: public DPL::Event::Controller::Type> +{ + public: + ICTestController() { } + + protected: + virtual void OnEventReceived(const GetNothingEvent& event) + { + event.GetArg0()(); //calling intercontext delegate + } + virtual void OnEventReceived(const GetIntEvent& event) + { + event.GetArg0()(IntVal); //calling intercontext delegate + } + + virtual void OnEventReceived(const GetIntAndStringEvent& event) + { + event.GetArg0()(IntVal, StringVal); //calling intercontext delegate + } +}; + +struct TestResult +{ + TestResult() : + m_correctThread0(false), + m_correctThread1(false), + m_correctThread2(false), + m_int(-1), + m_int2(-1), + m_string("") + { + } + + void TestEventsPassed() + { + RUNNER_ASSERT(m_correctThread0); + RUNNER_ASSERT(m_correctThread1); + RUNNER_ASSERT(m_int == IntVal); + RUNNER_ASSERT(m_correctThread2); + RUNNER_ASSERT(m_int2 == IntVal); + RUNNER_ASSERT(m_string == StringVal); + } + + void TestEventsDidNotPass() + { + RUNNER_ASSERT(!m_correctThread0); + RUNNER_ASSERT(!m_correctThread1); + RUNNER_ASSERT(m_int == -1); + RUNNER_ASSERT(!m_correctThread2); + RUNNER_ASSERT(m_int2 == -1); + RUNNER_ASSERT(m_string == ""); + } + + bool m_correctThread0; + bool m_correctThread1; + bool m_correctThread2; + int m_int; + int m_int2; + std::string m_string; +}; + +class TestContextFreeClass : + protected DPL::Thread, + public DPL::Event::ICDelegateSupport +{ + public: + TestContextFreeClass(ICTestController* controller, TestResult* result) : + Thread(), + m_testResult(result), + m_controller(controller) + { + LogDebug("Context thread id = " << this); + } + + void Run() + { + LogDebug("Running Context Free thread"); + Thread::Run(); + } + + void Quit() + { + LogDebug("Exiting Context Free thread"); + Thread::Quit(); + } + + + void Wait() + { + LogDebug("Waiting for thread"); + DPL::WaitForSingleHandle(m_waitable.GetHandle()); + } + + protected: + void OnNothing() + { + LogDebug("Received nothing in thread = " << GetCurrentThread()); + m_testResult->m_correctThread0 = (GetCurrentThread() == this); + } + + void OnIntReceive(int val) + { + LogDebug("Received int in thread = " << GetCurrentThread()); + m_testResult->m_correctThread1 = (GetCurrentThread() == this); + m_testResult->m_int = val; + } + + void OnIntAndStringReceive(int val, std::string stringval) + { + LogDebug("Received int and string in thread = " << GetCurrentThread()); + m_testResult->m_correctThread2 = (GetCurrentThread() == this); + m_testResult->m_int2 = val; + m_testResult->m_string = stringval; + m_waitable.Signal(); + } + + virtual int ThreadEntry() + { + GetNothingEvent getNothingEvent( + makeICDelegate( + &TestContextFreeClass::OnNothing)); + m_controller->DPL::Event::ControllerEventHandler::PostEvent( + getNothingEvent); + + GetIntEvent getIntEvent( + makeICDelegate( + &TestContextFreeClass::OnIntReceive)); + m_controller->DPL::Event::ControllerEventHandler::PostEvent( + getIntEvent); + + GetIntAndStringEvent getIntAndStringEvent( + makeICDelegate( + &TestContextFreeClass::OnIntAndStringReceive)); + m_controller->DPL::Event::ControllerEventHandler::PostEvent( + getIntAndStringEvent); + + return Thread::ThreadEntry(); + } + + private: + TestResult* m_testResult; + DPL::WaitableEvent m_waitable; + ICTestController* m_controller; +}; + +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 ICTestControllerPtr; +typedef DPL::SharedPtr TestContextFreePtr; +typedef DPL::SharedPtr TestRunnerInThreadPtr; +typedef DPL::SharedPtr ThreadPtr; + +DPL::Mutex mutex; +std::list frees; +std::list ctrls; +std::list frees_threads; +std::list ctrls_threads; + +} + +class TestContextFree : public DPL::Event::ICDelegateSupport +{ + public: + TestContextFree(ICTestController* controller, + int eventsCount) : + m_controller(controller), + m_eventsCount(eventsCount) + { + } + + void Wait() + { + LogDebug("Waiting for thread"); + DPL::WaitForSingleHandle(m_waitable.GetHandle()); + } + + + void OnNothing() + { + LogDebug("Got"); + m_eventsCount--; + if (m_eventsCount > 0) { + LogDebug("posting next event"); + GetIntAndStringEvent getIntAndStringEvent( + makeICDelegate( + &TestContextFree::OnIntAndStringReceive)); + LogDebug("posting next event ..."); + m_controller->DPL::Event::ControllerEventHandler::PostEvent( + getIntAndStringEvent); + LogDebug("posting next event done"); + } else { + LogDebug("test finished"); + m_waitable.Signal(); + } + } + + void OnIntReceive(int) + { + LogDebug("Got"); + m_eventsCount--; + if (m_eventsCount > 0) { + LogDebug("posting next event"); + GetNothingEvent getNothingEvent( + makeICDelegate( + &TestContextFree::OnNothing)); + LogDebug("posting next event ..."); + m_controller->DPL::Event::ControllerEventHandler::PostEvent( + getNothingEvent); + LogDebug("posting next event done"); + } else { + LogDebug("test finished"); + m_waitable.Signal(); + } + } + + void OnIntAndStringReceive(int, std::string) + { + LogDebug("Got"); + m_eventsCount--; + if (m_eventsCount > 0) { + LogDebug("posting next event"); + + GetIntEvent getIntEvent( + makeICDelegate( + &TestContextFree::OnIntReceive)); + LogDebug("posting next event ..."); + m_controller->DPL::Event::ControllerEventHandler::PostEvent( + getIntEvent); + LogDebug("posting next event done"); + } else { + LogDebug("test finished"); + m_waitable.Signal(); + } + } + + void StartTestOnNothing() + { + GetNothingEvent getNothingEvent( + makeICDelegate( + &TestContextFree::OnNothing)); + m_controller->DPL::Event::ControllerEventHandler::PostEvent( + getNothingEvent); + } + + void StartTestOnInt() + { + GetIntEvent getIntEvent( + makeICDelegate( + &TestContextFree::OnIntReceive)); + m_controller->DPL::Event::ControllerEventHandler::PostEvent( + getIntEvent); + } + + void StartTestOnIntAndString() + { + GetIntAndStringEvent getIntAndStringEvent( + makeICDelegate( + &TestContextFree::OnIntAndStringReceive)); + m_controller->DPL::Event::ControllerEventHandler::PostEvent( + getIntAndStringEvent); + } + + bool CheckTest() + { + LogDebug("Checking test result"); + return m_eventsCount == 0; + } + + private: + ICTestController* m_controller; + int m_eventsCount; + DPL::WaitableEvent m_waitable; +}; + +class TestRunnerInThread : public DPL::Thread +{ + public: + TestRunnerInThread(int events, int tests) : + m_eventsCount(events), + m_tests(tests) {} + + void WaitForInit() + { + LogDebug("Waiting for thread"); + DPL::WaitForSingleHandle(m_init.GetHandle()); + } + + protected: + virtual int ThreadEntry() + { + LogDebug("Thread starts"); + { + DPL::Mutex::ScopedLock lock(&mutex); + for (int i = 0; i < m_tests; ++i) + { + if (i % TestsPerController == 0) { + if (ctrls.size() % ControllersPerThread == 0) { + ThreadPtr thread(new DPL::Thread()); + thread->Run(); + ctrls_threads.push_back(thread); + } + ICTestControllerPtr ptr(new ICTestController()); + ptr->Touch(); + ptr->SwitchToThread(ctrls_threads.back().Get()); + ctrls.push_back(ptr); + + TestContextFreePtr t(new TestContextFree(ctrls.back().Get(), + m_eventsCount)); + t->StartTestOnNothing(); + LogDebug(""); + frees.push_back(t); + } + } + } + m_init.Signal(); + LogDebug("Thread starts loop"); + return DPL::Thread::ThreadEntry(); + } + + private: + DPL::WaitableEvent m_init; + int m_eventsCount; + int m_tests; +}; + +RUNNER_TEST(ICDelegate_2) +{ + LogDebug("Creating test threads"); + for (int i = 0; i < TestThreads; ++i) + { + TestRunnerInThreadPtr ptr( + new TestRunnerInThread(NumberOfEvents, TestsPerThread)); + frees_threads.push_back(ptr); + frees_threads.back()->Run(); + } + + FOREACH(it, frees_threads) { + (*it)->WaitForInit(); + } + LogDebug("Creating test threads done"); + + FOREACH(it, frees) { + LogDebug("..."); + (*it)->Wait(); + } + + FOREACH(it, frees) { + RUNNER_ASSERT((*it)->CheckTest()); + } + + frees.clear(); + + FOREACH(it, frees_threads) { + (*it)->Quit(); + } + + frees_threads.clear(); + + FOREACH(it, ctrls) { + (*it)->SwitchToThread(NULL); + } + + FOREACH(it, ctrls_threads) { + (*it)->Quit(); + } + + ctrls.clear(); + ctrls_threads.clear(); +} + +namespace ReuseCheck { +const int ReuseCount = 5; +typedef DPL::Event::ICDelegate<> GetNothingDlpType; +DECLARE_GENERIC_EVENT_1(ReuseCountEvent, GetNothingDlpType) + +class ICReuseTestController +: public DPL::Event::Controller::Type> +{ + public: + ICReuseTestController() { m_reuseCount = 0; } + + protected: + virtual void OnEventReceived(const ReuseCountEvent& event) + { + event.GetArg0()(); //calling intercontext delegate + if(++m_reuseCount < ReuseCount){ + LogInfo("[Send] Reuse: " << m_reuseCount); + DPL::Event::ControllerEventHandler::PostEvent(event); + } + } + + int m_reuseCount; +}; + +class ReuseTestContextFreeClass : + protected DPL::Thread, + public DPL::Event::ICDelegateSupport +{ + public: + ReuseTestContextFreeClass(ICReuseTestController* controller) : + Thread(), + m_controller(controller), + m_reuseCount(0) + { } + + void Run() { Thread::Run(); } + void Quit() { Thread::Quit(); } + void Wait() { DPL::WaitForSingleHandle(m_waitable.GetHandle()); } + + protected: + void OnReuseReceive() + { + LogDebug("[Received] : " << ++m_reuseCount); + if(m_reuseCount == ReuseCount) + m_waitable.Signal(); + } + + virtual int ThreadEntry() + { + ReuseCountEvent reuseEvent( + makeICDelegate( + &ReuseTestContextFreeClass::OnReuseReceive, + DPL::Event::ICD::Reuse::Yes)); + m_controller->DPL::Event::ControllerEventHandler::PostEvent( + reuseEvent); + + return Thread::ThreadEntry(); + } + + private: + DPL::WaitableEvent m_waitable; + ICReuseTestController* m_controller; + int m_reuseCount; +}; + +RUNNER_TEST(ICDelegate_3) +{ + DPL::Thread thread; + thread.Run(); + LogDebug("Controller thread id = " << &thread); + + ICReuseTestController testController; + testController.Touch(); + testController.SwitchToThread(&thread); + + ReuseTestContextFreeClass* contextFree = + new ReuseTestContextFreeClass(&testController); + + thread.Run(); + contextFree->Run(); + contextFree->Wait(); + contextFree->Quit(); + thread.Quit(); + + delete contextFree; + + RUNNER_ASSERT(true); +} +} //namespace ReuseCheck diff --git a/tests/event/test_property.cpp b/tests/event/test_property.cpp new file mode 100644 index 0000000..c095e5b --- /dev/null +++ b/tests/event/test_property.cpp @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_property.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of test property + */ +#include +#include +#include +#include + +namespace { +const int PROPERTY_VALUE_INT = 2; +const std::string PROPERTY_VALUE_STRING = "aaa"; +} + +int ReadSomething2(DPL::Event::Model */*model*/); +int ReadSomething2(DPL::Event::Model */*model*/) +{ + return PROPERTY_VALUE_INT; +} + +std::string ReadSomething(DPL::Event::Model */*model*/); +std::string ReadSomething(DPL::Event::Model */*model*/) +{ + return PROPERTY_VALUE_STRING; +} + +void WriteSomething(const std::string &/*value*/, DPL::Event::Model */*model*/); +void WriteSomething(const std::string &/*value*/, DPL::Event::Model */*model*/) +{ +} + +class MyModel + : public DPL::Event::Model +{ +public: + ~MyModel() {} + + DPL::Event::Property + Caption; + + DPL::Event::Property + Testproperty0; + + DPL::Event::Property + Testproperty1; + + DPL::Event::Property + Testproperty2; + + DPL::Event::Property Testproperty3; + + DPL::Event::Property Testproperty4; + + DPL::Event::Property Testproperty5; + + MyModel() + : Caption(this, "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 &event); +void OnNameChanged(const DPL::Event::PropertyEvent &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); +} diff --git a/tests/localization/CMakeLists.txt b/tests/localization/CMakeLists.txt new file mode 100644 index 0000000..47e8229 --- /dev/null +++ b/tests/localization/CMakeLists.txt @@ -0,0 +1,76 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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) diff --git a/tests/localization/files/CMakeLists.txt b/tests/localization/files/CMakeLists.txt new file mode 100644 index 0000000..c887914 --- /dev/null +++ b/tests/localization/files/CMakeLists.txt @@ -0,0 +1,19 @@ +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 + ) + diff --git a/tests/localization/files/one b/tests/localization/files/one new file mode 100644 index 0000000..e69de29 diff --git a/tests/localization/files/two b/tests/localization/files/two new file mode 100644 index 0000000..e69de29 diff --git a/tests/localization/mockup_include/dpl/wrt-dao-ro/common_dao_types.h b/tests/localization/mockup_include/dpl/wrt-dao-ro/common_dao_types.h new file mode 100644 index 0000000..9e49d0d --- /dev/null +++ b/tests/localization/mockup_include/dpl/wrt-dao-ro/common_dao_types.h @@ -0,0 +1,487 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 +#include +#include +#include +#include +#include +#include + +namespace WrtDB { +namespace Powder { + +typedef std::set 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 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 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 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 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 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 m_deviceCapabilities; + + bool operator< (const Feature& obj) const + { + return m_name < obj.m_name; + } + }; + typedef std::set 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 Objects; + typedef DPL::SharedPtr 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 WidgetAccessInfoList; + +typedef std::list 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 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 DbWidgetFeatureSet; + +/** + * @brief Default container with DbWidgetHandle's + */ +typedef std::list 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 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 WidgetApplicationServiceList; +#endif /* WRT_SRC_CONFIGURATION_COMMON_DAO_TYPES_H_ */ diff --git a/tests/localization/mockup_include/dpl/wrt-dao-rw/widget_dao.h b/tests/localization/mockup_include/dpl/wrt-dao-rw/widget_dao.h new file mode 100644 index 0000000..42b6c5b --- /dev/null +++ b/tests/localization/mockup_include/dpl/wrt-dao-rw/widget_dao.h @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * This file contains the declaration of widget dao class. + * + * @file widget_dao_read_only.h + * @author Yang Jie (jie2.yang@samsung.com) + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @version 1.0 + * @brief This file contains the declaration of widget dao + */ + +#ifndef _WRT_SRC_CONFIGURATION_WIDGET_DAO_READ_ONLY_H_ +#define _WRT_SRC_CONFIGURATION_WIDGET_DAO_READ_ONLY_H_ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +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 StringList; + +struct WidgetLocalizedInfo +{ + DPL::OptionalString name; + DPL::OptionalString shortName; + DPL::OptionalString description; + DPL::OptionalString license; + DPL::OptionalString licenseHref; +}; + +typedef std::list 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 WidgetLocalizedIconList; + + struct WidgetIconRow + { + int iconId; + int appId; + DPL::String iconSrc; + DPL::OptionalInt iconWidth; + DPL::OptionalInt iconHeight; + }; + typedef std::list WidgetIconList; + + struct WidgetStartFileRow + { + int startFileId; + int appId; + DPL::String src; + }; + typedef std::list WidgetStartFileList; + + struct WidgetLocalizedStartFileRow + { + int startFileId; + int appId; + DPL::String widgetLocale; + DPL::String type; + DPL::String encoding; + }; + typedef std::list LocalizedStartFileList; + + + /** + * This is a constructor. + * + * @param[in] widgetHandle application id of widget. + */ + 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 s_startFileMap; + static std::map s_localizedStartFileMap; + static std::map s_pathMap; +}; + +} // namespace WrtDB + +#endif // _WRT_SRC_CONFIGURATION_WIDGET_DAO_READ_ONLY_H_ + diff --git a/tests/localization/mockup_src/widget_dao.cpp b/tests/localization/mockup_src/widget_dao.cpp new file mode 100644 index 0000000..3fe877b --- /dev/null +++ b/tests/localization/mockup_src/widget_dao.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * This file contains the declaration of widget dao class. + * + * @file widget_dao_read_only.cpp + * @author Yang Jie (jie2.yang@samsung.com) + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @version 1.0 + * @brief This file contains the declaration of widget dao + */ + +#include + +#include +#include +#include +#include + +namespace WrtDB { + +std::map WidgetDAO::s_startFileMap; +std::map WidgetDAO::s_localizedStartFileMap; +std::map 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 diff --git a/tests/localization/test_localization.cpp b/tests/localization/test_localization.cpp new file mode 100644 index 0000000..42ffe3a --- /dev/null +++ b/tests/localization/test_localization.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file main.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of main + */ +#include + +int main(int argc, char *argv[]) +{ + return DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv); +} + diff --git a/tests/localization/test_suite01.cpp b/tests/localization/test_suite01.cpp new file mode 100644 index 0000000..83f53f5 --- /dev/null +++ b/tests/localization/test_suite01.cpp @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include +#include + +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"); +} + diff --git a/tests/vcore/CMakeLists.txt b/tests/vcore/CMakeLists.txt new file mode 100644 index 0000000..443438d --- /dev/null +++ b/tests/vcore/CMakeLists.txt @@ -0,0 +1,129 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file 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/ +) + diff --git a/tests/vcore/TestCRL.cpp b/tests/vcore/TestCRL.cpp new file mode 100644 index 0000000..37998df --- /dev/null +++ b/tests/vcore/TestCRL.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include +#include +#include "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(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); +} diff --git a/tests/vcore/TestCRL.h b/tests/vcore/TestCRL.h new file mode 100644 index 0000000..d6c1ee6 --- /dev/null +++ b/tests/vcore/TestCRL.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _TEST_CRL_H +#define _TEST_CRL_H + +#include +#include + +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 diff --git a/tests/vcore/TestCases.cpp b/tests/vcore/TestCases.cpp new file mode 100644 index 0000000..8fdd4e7 --- /dev/null +++ b/tests/vcore/TestCases.cpp @@ -0,0 +1,1325 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "TestEnv.h" +#include +#include +#include +#include +#include +#include +#include "TestCRL.h" +#include + +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 +//{ +// public: +// PolicyChanger() +// { +// DPL::Event::EventDeliverySystem::AddListener(this); +// } +// +// ~PolicyChanger() +// { +// DPL::Event::EventDeliverySystem::RemoveListener(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(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(); +} + diff --git a/tests/vcore/TestEnv.cpp b/tests/vcore/TestEnv.cpp new file mode 100644 index 0000000..b12c3e1 --- /dev/null +++ b/tests/vcore/TestEnv.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include + +#include + +#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; +} + diff --git a/tests/vcore/TestEnv.h b/tests/vcore/TestEnv.h new file mode 100644 index 0000000..88c5d3a --- /dev/null +++ b/tests/vcore/TestEnv.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#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 diff --git a/tests/vcore/certificate-generator/create_certs.sh b/tests/vcore/certificate-generator/create_certs.sh new file mode 100755 index 0000000..4d03927 --- /dev/null +++ b/tests/vcore/certificate-generator/create_certs.sh @@ -0,0 +1,94 @@ +#!/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 < + + + + + + + xUKQbov3HL7JD2/zVUKpPEVGc5C6VWDXwxoDHzDs9y0= + + + + cIE41PzyhMnF++EmhJ3Ptnd4ZqXyBlRJgiIqxlutbV8= + + + + + + + MH34nIMXxv0fMQQ8bTV1wZUNLOrXTmpnxpADlNzmQ/4= + + + fhh+VQq76Uodq4upHhvcC2tgbVY8bL9DiiSe9wn1O4YrIFKMnEEYqYmpQbL1puWU +Zbht0hXpvEFXg1010q5kOZQxknqcyFg3hyVUpFDPARkJs1XhRNbFWJJF7qNXVgt5 +NyFrdXFv4lVFjkv+chSykaWu6V22z43E8kJcg+zGVU8= + + + 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== + + + + + + + + + + + + + + + + diff --git a/tests/vcore/test-cases/widget/config.xml b/tests/vcore/test-cases/widget/config.xml new file mode 100755 index 0000000..82b077b --- /dev/null +++ b/tests/vcore/test-cases/widget/config.xml @@ -0,0 +1,6 @@ + + Widget Name OK + 1.2.3.4 + A short description of widget + Author Name + diff --git a/tests/vcore/test-cases/widget/index.html b/tests/vcore/test-cases/widget/index.html new file mode 100755 index 0000000..c47b20a --- /dev/null +++ b/tests/vcore/test-cases/widget/index.html @@ -0,0 +1,4 @@ + +Not tested + +

None

diff --git a/tests/vcore/test-cases/widget/signature1.xml b/tests/vcore/test-cases/widget/signature1.xml new file mode 100644 index 0000000..71a100b --- /dev/null +++ b/tests/vcore/test-cases/widget/signature1.xml @@ -0,0 +1,62 @@ + + + + + + + + ZLhd8X2rzCIDGHkIvpDbCXq+dwq+DK7ZZaDD/fII8RU= + + + + xUKQbov3HL7JD2/zVUKpPEVGc5C6VWDXwxoDHzDs9y0= + + + + cIE41PzyhMnF++EmhJ3Ptnd4ZqXyBlRJgiIqxlutbV8= + + + + + + + ZxnfFPi1rAoxfpN98xSP3lv5tZg9ymJElAFdg3ejrXE= + + + Dwm15jQbvUxe7fa7p4RVRAUzYY6eGQmDJSWXnv2LBbouch163OMaXgjKXWOLU+ZA +MwwuUUXG44QvOIv5M3Kd/Pc6kwvyb9+xm8zqmFF/mhttmAHc7VjY5sfB+bYFt9/3 +8+upSqxiUGLXYzMD/9u4W9ociwAcLiOQytBF1/TCv/4= + + + 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= + + + + + + + + + + + + + + + + diff --git a/tests/vcore/test-cases/widget/signature22.xml b/tests/vcore/test-cases/widget/signature22.xml new file mode 100644 index 0000000..715a7cc --- /dev/null +++ b/tests/vcore/test-cases/widget/signature22.xml @@ -0,0 +1,66 @@ + + + + + + + + ZLhd8X2rzCIDGHkIvpDbCXq+dwq+DK7ZZaDD/fII8RU= + + + + xUKQbov3HL7JD2/zVUKpPEVGc5C6VWDXwxoDHzDs9y0= + + + + cIE41PzyhMnF++EmhJ3Ptnd4ZqXyBlRJgiIqxlutbV8= + + + + + + + ZxnfFPi1rAoxfpN98xSP3lv5tZg9ymJElAFdg3ejrXE= + + + fV1J/120GG5L7qsxEkyH6fBvQh2atlpiGMbVM1+pb8Q6pHib5beV6A== + + + 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= + + + + + + + + + + + + + + + + diff --git a/tests/vcore/vcore_tests.cpp b/tests/vcore/vcore_tests.cpp new file mode 100644 index 0000000..02517fc --- /dev/null +++ b/tests/vcore/vcore_tests.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file main.cpp + * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of main + */ +#include +#include + +#include // 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; +} +