[
  {
    "path": ".gitignore",
    "content": "bin/\nobj/\nxmr-stak-amd.layout\nxmr-stak-amd.depend\nconfig-debug.txt\n"
  },
  {
    "path": "CMakeLists.txt",
    "content": "project(xmr-stak-amd)\n\ncmake_minimum_required(VERSION 3.1.3)\n\n# enforce C++11\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\nset(CMAKE_CXX_EXTENSIONS OFF)\nset(CMAKE_CXX_STANDARD 11)\n\nif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)\n    set(CMAKE_INSTALL_PREFIX \"${CMAKE_BINARY_DIR}\" CACHE PATH \"install prefix\" FORCE)\nendif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)\n\n# help to find AMD app SDK on systems with a software module system\nlist(APPEND CMAKE_PREFIX_PATH \"$ENV{AMDAPPSDKROOT}\")\n# allow user to extent CMAKE_PREFIX_PATH via environment variable\nlist(APPEND CMAKE_PREFIX_PATH \"$ENV{CMAKE_PREFIX_PATH}\")\n\n################################################################################\n# CMake user options\n################################################################################\n\n# gcc 5.1 is the first GNU version without CoW strings\n# https://github.com/fireice-uk/xmr-stak-nvidia/pull/10#issuecomment-290821792\n# If you remove this guard to compile with older gcc versions the miner will produce\n# a high rate of wrong shares.\nif(\"${CMAKE_CXX_COMPILER_ID}\" STREQUAL \"GNU\")\n    if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.1)\n        message(FATAL_ERROR \"GCC version must be at least 5.1!\")\n    endif()\nendif()\n\nset(BUILD_TYPE \"Release;Debug\")\nif(NOT CMAKE_BUILD_TYPE)\n    set(CMAKE_BUILD_TYPE \"Release\" CACHE STRING \"Choose the type of build\" FORCE)\nendif()\nset_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS \"${BUILD_TYPE}\")\n\n# option to add static libgcc and libstdc++\noption(CMAKE_LINK_STATIC \"link as much as possible libraries static\" OFF)\n\n###############################################################################\n# Find OpenCL\n###############################################################################\n\nfind_package(OpenCL REQUIRED)\ninclude_directories(SYSTEM ${OpenCL_INCLUDE_DIRS})\nset(LIBS ${LIBS} ${OpenCL_LIBRARY})\nlink_directories(${OpenCL_LIBRARY})\n\n################################################################################\n# Find PThreads\n################################################################################\n\nfind_package(Threads REQUIRED)\nset(LIBS ${LIBS} ${CMAKE_THREAD_LIBS_INIT})\n\n################################################################################\n# Find microhttpd\n################################################################################\n\noption(MICROHTTPD_ENABLE \"Enable or disable the requirement of microhttp (http deamon)\" ON)\nif(MICROHTTPD_ENABLE)\n    find_library(MHTD NAMES microhttpd)\n    if(\"${MHTD}\" STREQUAL \"MHTD-NOTFOUND\")\n        message(FATAL_ERROR \"microhttpd NOT found: use `-DMICROHTTPD_ENABLE=OFF` to build without http deamon support\")\n    else()\n        set(LIBS ${LIBS} ${MHTD})\n    endif()\nelse()\n    add_definitions(\"-DCONF_NO_HTTPD\")\nendif()\n\n###############################################################################\n# Find OpenSSL\n###############################################################################\n\noption(OpenSSL_ENABLE \"Enable or disable the requirement of OpenSSL\" ON)\nif(OpenSSL_ENABLE)\n    find_package(OpenSSL)\n    if(OPENSSL_FOUND)\n        include_directories(${OPENSSL_INCLUDE_DIR})\n        set(LIBS ${LIBS} ${OPENSSL_LIBRARIES})\n    else()\n        message(FATAL_ERROR \"OpenSSL NOT found: use `-DOpenSSL_ENABLE=OFF` to build without SSL support\")\n    endif()\nelse()\n    add_definitions(\"-DCONF_NO_TLS\")\nendif()\n\n################################################################################\n# Compile & Link\n################################################################################\n\ninclude_directories(.)\n\n# activate sse2 and aes-ni\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -msse2 -maes\")\nset(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS} -msse2 -maes\")\n\n# activate static libgcc and libstdc++ linking\nif(CMAKE_LINK_STATIC)\n    set(BUILD_SHARED_LIBRARIES OFF)\n    set(DL_LIB ${CMAKE_DL_LIBS})\n    set(CMAKE_FIND_LIBRARY_SUFFIXES \".a\")\n    set(LIBS \"-static-libgcc -static-libstdc++ ${LIBS}\")\nendif()\n\nfile(GLOB SRCFILES_CPP \"*.cpp\" \"crypto/*.cpp\")\nfile(GLOB SRCFILES_C \"crypto/*.c\" \"amd_gpu/*.c\")\n\nadd_library(xmr-stak-amd-c\n    STATIC\n    ${SRCFILES_C}\n)\nset_property(TARGET xmr-stak-amd-c PROPERTY C_STANDARD 99)\ntarget_link_libraries(xmr-stak-amd-c PUBLIC ${OpenCL_LIBRARY})\n\nadd_executable(xmr-stak-amd\n    ${SRCFILES_CPP}\n)\nset(EXECUTABLE_OUTPUT_PATH \"bin\")\ntarget_link_libraries(xmr-stak-amd ${LIBS} xmr-stak-amd-c)\n\n################################################################################\n# Install\n################################################################################\n\n# do not install the binary if the project and install are equal\nif( NOT \"${CMAKE_INSTALL_PREFIX}\" STREQUAL \"${PROJECT_BINARY_DIR}\" )\n    install(TARGETS xmr-stak-amd\n            RUNTIME DESTINATION \"${CMAKE_INSTALL_PREFIX}/bin\")\nendif()\n\ninstall(DIRECTORY \"${CMAKE_CURRENT_SOURCE_DIR}/opencl\"\n        DESTINATION \"${CMAKE_INSTALL_PREFIX}/bin\")\n\n# avoid overwrite of user defined settings\n# install `config.txt`if file not exists in `${CMAKE_INSTALL_PREFIX}/bin`\ninstall(CODE \" \\\n    if(NOT EXISTS ${CMAKE_INSTALL_PREFIX}/bin/config.txt)\\n   \\\n        file(INSTALL ${CMAKE_CURRENT_SOURCE_DIR}/config.txt   \\\n            DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)\\n        \\\n    endif()\"\n)\n"
  },
  {
    "path": "LICENSE",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The GNU General Public License is a free, copyleft license for\nsoftware and other kinds of works.\n\n  The licenses for most software and other practical works are designed\nto take away your freedom to share and change the works.  By contrast,\nthe GNU General Public License is intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users.  We, the Free Software Foundation, use the\nGNU General Public License for most of our software; it applies also to\nany other work released this way by its authors.  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\n  To protect your rights, we need to prevent others from denying you\nthese rights or asking you to surrender the rights.  Therefore, you have\ncertain responsibilities if you distribute copies of the software, or if\nyou modify it: responsibilities to respect the freedom of others.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must pass on to the recipients the same\nfreedoms that you received.  You must make sure that they, too, receive\nor can get the source code.  And you must show them these terms so they\nknow their rights.\n\n  Developers that use the GNU GPL protect your rights with two steps:\n(1) assert copyright on the software, and (2) offer you this License\ngiving you legal permission to copy, distribute and/or modify it.\n\n  For the developers' and authors' protection, the GPL clearly explains\nthat there is no warranty for this free software.  For both users' and\nauthors' sake, the GPL requires that modified versions be marked as\nchanged, so that their problems will not be attributed erroneously to\nauthors of previous versions.\n\n  Some devices are designed to deny users access to install or run\nmodified versions of the software inside them, although the manufacturer\ncan do so.  This is fundamentally incompatible with the aim of\nprotecting users' freedom to change the software.  The systematic\npattern of such abuse occurs in the area of products for individuals to\nuse, which is precisely where it is most unacceptable.  Therefore, we\nhave designed this version of the GPL to prohibit the practice for those\nproducts.  If such problems arise substantially in other domains, we\nstand ready to extend this provision to those domains in future versions\nof the GPL, as needed to protect the freedom of users.\n\n  Finally, every program is threatened constantly by software patents.\nStates should not allow patents to restrict development and use of\nsoftware on general-purpose computers, but in those that do, we wish to\navoid the special danger that patents applied to a free program could\nmake it effectively proprietary.  To prevent this, the GPL assures that\npatents cannot be used to render the program non-free.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n  0. Definitions.\n\n  \"This License\" refers to version 3 of the GNU General Public License.\n\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n  \"The Program\" refers to any copyrightable work licensed under this\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\n  To \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy.  The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\n  A \"covered work\" means either the unmodified Program or a work based\non the Program.\n\n  To \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy.  Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\n  To \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies.  Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\n  An interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License.  If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n  1. Source Code.\n\n  The \"source code\" for a work means the preferred form of the work\nfor making modifications to it.  \"Object code\" means any non-source\nform of a work.\n\n  A \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\n  The \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form.  A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\n  The \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities.  However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work.  For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\n  The Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\n  The Corresponding Source for a work in source code form is that\nsame work.\n\n  2. Basic Permissions.\n\n  All rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met.  This License explicitly affirms your unlimited\npermission to run the unmodified Program.  The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work.  This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\n  You may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force.  You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright.  Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\n  Conveying under any other circumstances is permitted solely under\nthe conditions stated below.  Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n  No covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\n  When you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n  4. Conveying Verbatim Copies.\n\n  You may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\n  You may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n  5. Conveying Modified Source Versions.\n\n  You may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\n  A compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit.  Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n  6. Conveying Non-Source Forms.\n\n  You may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\n  A separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\n  A \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling.  In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage.  For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product.  A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n  \"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source.  The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\n  If you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information.  But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\n  The requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed.  Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\n  Corresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n  7. Additional Terms.\n\n  \"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law.  If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\n  When you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit.  (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.)  You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\n  Notwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\n  All other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10.  If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term.  If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\n  If you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\n  Additional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n  8. Termination.\n\n  You may not propagate or modify a covered work except as expressly\nprovided under this License.  Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\n  However, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\n  Moreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\n  Termination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License.  If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n  9. Acceptance Not Required for Having Copies.\n\n  You are not required to accept this License in order to receive or\nrun a copy of the Program.  Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance.  However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work.  These actions infringe copyright if you do\nnot accept this License.  Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n  10. Automatic Licensing of Downstream Recipients.\n\n  Each time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License.  You are not responsible\nfor enforcing compliance by third parties with this License.\n\n  An \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations.  If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\n  You may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License.  For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n  11. Patents.\n\n  A \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based.  The\nwork thus licensed is called the contributor's \"contributor version\".\n\n  A contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version.  For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\n  In the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement).  To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\n  If you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients.  \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\n  If, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\n  A patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License.  You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\n  Nothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n  12. No Surrender of Others' Freedom.\n\n  If conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all.  For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n  13. Use with the GNU Affero General Public License.\n\n  Notwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU Affero General Public License into a single\ncombined work, and to convey the resulting work.  The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the special requirements of the GNU Affero General Public License,\nsection 13, concerning interaction through a network will apply to the\ncombination as such.\n\n  14. Revised Versions of this License.\n\n  The Free Software Foundation may publish revised and/or new versions of\nthe GNU General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\n  Each version is given a distinguishing version number.  If the\nProgram specifies that a certain numbered version of the GNU General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation.  If the Program does not specify a version number of the\nGNU General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\n  If the Program specifies that a proxy can decide which future\nversions of the GNU General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\n  Later license versions may give you additional or different\npermissions.  However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n  15. Disclaimer of Warranty.\n\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. Limitation of Liability.\n\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n  17. Interpretation of Sections 15 and 16.\n\n  If the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n"
  },
  {
    "path": "README.md",
    "content": "# XMR-Stak is now supporting CPU, AMD and NVIDIA GPUs in a unified miner.\n\nOur new repository is https://github.com/fireice-uk/xmr-stak.\n\nPlease use our new miner, the old version is retired and unsupported.\n"
  },
  {
    "path": "amd_gpu/gpu.c",
    "content": "/*\n  * This program is free software: you can redistribute it and/or modify\n  * it under the terms of the GNU General Public License as published by\n  * the Free Software Foundation, either version 3 of the License, or\n  * any later version.\n  *\n  * This program is distributed in the hope that it will be useful,\n  * but WITHOUT ANY WARRANTY; without even the implied warranty of\n  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n  * GNU General Public License for more details.\n  *\n  * You should have received a copy of the GNU General Public License\n  * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n  */\n\n#include <stdio.h>\n#include <string.h>\n#include <math.h>\n\n#ifdef _WIN32\n#include <windows.h>\nconst char* sSourcePath = \"opencl\\\\cryptonight.cl\";\n\nstatic inline void port_sleep(size_t sec)\n{\n\tSleep(sec * 1000);\n}\n#else\n#include <unistd.h>\nconst char* sSourcePath = \"opencl/cryptonight.cl\";\n\nstatic inline void port_sleep(size_t sec)\n{\n\tsleep(sec);\n}\n#endif // _WIN32\n\nstatic inline long long unsigned int int_port(size_t i)\n{\n\treturn i;\n}\n\n#include \"gpu.h\"\n\nconst char* err_to_str(cl_int ret)\n{\n\tswitch(ret)\n\t{\n\tcase CL_SUCCESS:\n\t\treturn \"CL_SUCCESS\";\n\tcase CL_DEVICE_NOT_FOUND:\n\t\treturn \"CL_DEVICE_NOT_FOUND\";\n\tcase CL_DEVICE_NOT_AVAILABLE:\n\t\treturn \"CL_DEVICE_NOT_AVAILABLE\";\n\tcase CL_COMPILER_NOT_AVAILABLE:\n\t\treturn \"CL_COMPILER_NOT_AVAILABLE\";\n\tcase CL_MEM_OBJECT_ALLOCATION_FAILURE:\n\t\treturn \"CL_MEM_OBJECT_ALLOCATION_FAILURE\";\n\tcase CL_OUT_OF_RESOURCES:\n\t\treturn \"CL_OUT_OF_RESOURCES\";\n\tcase CL_OUT_OF_HOST_MEMORY:\n\t\treturn \"CL_OUT_OF_HOST_MEMORY\";\n\tcase CL_PROFILING_INFO_NOT_AVAILABLE:\n\t\treturn \"CL_PROFILING_INFO_NOT_AVAILABLE\";\n\tcase CL_MEM_COPY_OVERLAP:\n\t\treturn \"CL_MEM_COPY_OVERLAP\";\n\tcase CL_IMAGE_FORMAT_MISMATCH:\n\t\treturn \"CL_IMAGE_FORMAT_MISMATCH\";\n\tcase CL_IMAGE_FORMAT_NOT_SUPPORTED:\n\t\treturn \"CL_IMAGE_FORMAT_NOT_SUPPORTED\";\n\tcase CL_BUILD_PROGRAM_FAILURE:\n\t\treturn \"CL_BUILD_PROGRAM_FAILURE\";\n\tcase CL_MAP_FAILURE:\n\t\treturn \"CL_MAP_FAILURE\";\n\tcase CL_MISALIGNED_SUB_BUFFER_OFFSET:\n\t\treturn \"CL_MISALIGNED_SUB_BUFFER_OFFSET\";\n\tcase CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST:\n\t\treturn \"CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST\";\n\tcase CL_COMPILE_PROGRAM_FAILURE:\n\t\treturn \"CL_COMPILE_PROGRAM_FAILURE\";\n\tcase CL_LINKER_NOT_AVAILABLE:\n\t\treturn \"CL_LINKER_NOT_AVAILABLE\";\n\tcase CL_LINK_PROGRAM_FAILURE:\n\t\treturn \"CL_LINK_PROGRAM_FAILURE\";\n\tcase CL_DEVICE_PARTITION_FAILED:\n\t\treturn \"CL_DEVICE_PARTITION_FAILED\";\n\tcase CL_KERNEL_ARG_INFO_NOT_AVAILABLE:\n\t\treturn \"CL_KERNEL_ARG_INFO_NOT_AVAILABLE\";\n\tcase CL_INVALID_VALUE:\n\t\treturn \"CL_INVALID_VALUE\";\n\tcase CL_INVALID_DEVICE_TYPE:\n\t\treturn \"CL_INVALID_DEVICE_TYPE\";\n\tcase CL_INVALID_PLATFORM:\n\t\treturn \"CL_INVALID_PLATFORM\";\n\tcase CL_INVALID_DEVICE:\n\t\treturn \"CL_INVALID_DEVICE\";\n\tcase CL_INVALID_CONTEXT:\n\t\treturn \"CL_INVALID_CONTEXT\";\n\tcase CL_INVALID_QUEUE_PROPERTIES:\n\t\treturn \"CL_INVALID_QUEUE_PROPERTIES\";\n\tcase CL_INVALID_COMMAND_QUEUE:\n\t\treturn \"CL_INVALID_COMMAND_QUEUE\";\n\tcase CL_INVALID_HOST_PTR:\n\t\treturn \"CL_INVALID_HOST_PTR\";\n\tcase CL_INVALID_MEM_OBJECT:\n\t\treturn \"CL_INVALID_MEM_OBJECT\";\n\tcase CL_INVALID_IMAGE_FORMAT_DESCRIPTOR:\n\t\treturn \"CL_INVALID_IMAGE_FORMAT_DESCRIPTOR\";\n\tcase CL_INVALID_IMAGE_SIZE:\n\t\treturn \"CL_INVALID_IMAGE_SIZE\";\n\tcase CL_INVALID_SAMPLER:\n\t\treturn \"CL_INVALID_SAMPLER\";\n\tcase CL_INVALID_BINARY:\n\t\treturn \"CL_INVALID_BINARY\";\n\tcase CL_INVALID_BUILD_OPTIONS:\n\t\treturn \"CL_INVALID_BUILD_OPTIONS\";\n\tcase CL_INVALID_PROGRAM:\n\t\treturn \"CL_INVALID_PROGRAM\";\n\tcase CL_INVALID_PROGRAM_EXECUTABLE:\n\t\treturn \"CL_INVALID_PROGRAM_EXECUTABLE\";\n\tcase CL_INVALID_KERNEL_NAME:\n\t\treturn \"CL_INVALID_KERNEL_NAME\";\n\tcase CL_INVALID_KERNEL_DEFINITION:\n\t\treturn \"CL_INVALID_KERNEL_DEFINITION\";\n\tcase CL_INVALID_KERNEL:\n\t\treturn \"CL_INVALID_KERNEL\";\n\tcase CL_INVALID_ARG_INDEX:\n\t\treturn \"CL_INVALID_ARG_INDEX\";\n\tcase CL_INVALID_ARG_VALUE:\n\t\treturn \"CL_INVALID_ARG_VALUE\";\n\tcase CL_INVALID_ARG_SIZE:\n\t\treturn \"CL_INVALID_ARG_SIZE\";\n\tcase CL_INVALID_KERNEL_ARGS:\n\t\treturn \"CL_INVALID_KERNEL_ARGS\";\n\tcase CL_INVALID_WORK_DIMENSION:\n\t\treturn \"CL_INVALID_WORK_DIMENSION\";\n\tcase CL_INVALID_WORK_GROUP_SIZE:\n\t\treturn \"CL_INVALID_WORK_GROUP_SIZE\";\n\tcase CL_INVALID_WORK_ITEM_SIZE:\n\t\treturn \"CL_INVALID_WORK_ITEM_SIZE\";\n\tcase CL_INVALID_GLOBAL_OFFSET:\n\t\treturn \"CL_INVALID_GLOBAL_OFFSET\";\n\tcase CL_INVALID_EVENT_WAIT_LIST:\n\t\treturn \"CL_INVALID_EVENT_WAIT_LIST\";\n\tcase CL_INVALID_EVENT:\n\t\treturn \"CL_INVALID_EVENT\";\n\tcase CL_INVALID_OPERATION:\n\t\treturn \"CL_INVALID_OPERATION\";\n\tcase CL_INVALID_GL_OBJECT:\n\t\treturn \"CL_INVALID_GL_OBJECT\";\n\tcase CL_INVALID_BUFFER_SIZE:\n\t\treturn \"CL_INVALID_BUFFER_SIZE\";\n\tcase CL_INVALID_MIP_LEVEL:\n\t\treturn \"CL_INVALID_MIP_LEVEL\";\n\tcase CL_INVALID_GLOBAL_WORK_SIZE:\n\t\treturn \"CL_INVALID_GLOBAL_WORK_SIZE\";\n\tcase CL_INVALID_PROPERTY:\n\t\treturn \"CL_INVALID_PROPERTY\";\n\tcase CL_INVALID_IMAGE_DESCRIPTOR:\n\t\treturn \"CL_INVALID_IMAGE_DESCRIPTOR\";\n\tcase CL_INVALID_COMPILER_OPTIONS:\n\t\treturn \"CL_INVALID_COMPILER_OPTIONS\";\n\tcase CL_INVALID_LINKER_OPTIONS:\n\t\treturn \"CL_INVALID_LINKER_OPTIONS\";\n\tcase CL_INVALID_DEVICE_PARTITION_COUNT:\n\t\treturn \"CL_INVALID_DEVICE_PARTITION_COUNT\";\n#ifdef CL_VERSION_2_0\n\tcase CL_INVALID_PIPE_SIZE:\n\t\treturn \"CL_INVALID_PIPE_SIZE\";\n\tcase CL_INVALID_DEVICE_QUEUE:\n\t\treturn \"CL_INVALID_DEVICE_QUEUE\";\n#endif\n\tdefault:\n\t\treturn \"UNKNOWN_ERROR\";\n\t}\n}\n\nvoid printer_print_msg(const char* fmt, ...);\nvoid printer_print_str(const char* str);\n\nchar* LoadTextFile(const char* filename)\n{\n\tsize_t flen;\n\tchar* out;\n\tFILE* kernel = fopen(filename, \"rb\");\n\n\tif(kernel == NULL)\n\t\treturn NULL;\n\n\tfseek(kernel, 0, SEEK_END);\n\tflen = ftell(kernel);\n\tfseek(kernel, 0, SEEK_SET);\n\n\tout = (char*)malloc(flen+1);\n\tsize_t r = fread(out, flen, 1, kernel);\n\tfclose(kernel);\n\n\tif(r != 1)\n\t{\n\t\tfree(out);\n\t\treturn NULL;\n\t}\n\n\tout[flen] = '\\0';\n\treturn out;\n}\n\nsize_t InitOpenCLGpu(cl_context opencl_ctx, GpuContext* ctx, char* source_code)\n{\n\tsize_t MaximumWorkSize;\n\tcl_int ret;\n\n\tif((ret = clGetDeviceInfo(ctx->DeviceID, CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(size_t), &MaximumWorkSize, NULL)) != CL_SUCCESS)\n\t{\n\t\tprinter_print_msg(\"Error %s when querying a device's max worksize using clGetDeviceInfo.\", err_to_str(ret));\n\t\treturn ERR_OCL_API;\n\t}\n\n\tprinter_print_msg(\"Device %lu work size %lu / %lu.\", ctx->deviceIdx, ctx->workSize, MaximumWorkSize);\n#ifdef CL_VERSION_2_0\n\tconst cl_queue_properties CommandQueueProperties[] = { 0, 0, 0 };\n\tctx->CommandQueues = clCreateCommandQueueWithProperties(opencl_ctx, ctx->DeviceID, CommandQueueProperties, &ret);\n#else\n\tconst cl_command_queue_properties CommandQueueProperties = { 0 };\n\tctx->CommandQueues = clCreateCommandQueue(opencl_ctx, ctx->DeviceID, CommandQueueProperties, &ret);\n#endif\n\n\tif(ret != CL_SUCCESS)\n\t{\n\t\tprinter_print_msg(\"Error %s when calling clCreateCommandQueueWithProperties.\", err_to_str(ret));\n\t\treturn ERR_OCL_API;\n\t}\n\n\tctx->InputBuffer = clCreateBuffer(opencl_ctx, CL_MEM_READ_ONLY, 88, NULL, &ret);\n\tif(ret != CL_SUCCESS)\n\t{\n\t\tprinter_print_msg(\"Error %s when calling clCreateBuffer to create input buffer.\", err_to_str(ret));\n\t\treturn ERR_OCL_API;\n\t}\n\n\tsize_t g_thd = ctx->rawIntensity;\n\tctx->ExtraBuffers[0] = clCreateBuffer(opencl_ctx, CL_MEM_READ_WRITE, (1 << 21) * g_thd, NULL, &ret);\n\tif(ret != CL_SUCCESS)\n\t{\n\t\tprinter_print_msg(\"Error %s when calling clCreateBuffer to create hash scratchpads buffer.\", err_to_str(ret));\n\t\treturn ERR_OCL_API;\n\t}\n\n\tctx->ExtraBuffers[1] = clCreateBuffer(opencl_ctx, CL_MEM_READ_WRITE, 200 * g_thd, NULL, &ret);\n\tif(ret != CL_SUCCESS)\n\t{\n\t\tprinter_print_msg(\"Error %s when calling clCreateBuffer to create hash states buffer.\", err_to_str(ret));\n\t\treturn ERR_OCL_API;\n\t}\n\n\t// Blake-256 branches\n\tctx->ExtraBuffers[2] = clCreateBuffer(opencl_ctx, CL_MEM_READ_WRITE, sizeof(cl_uint) * (g_thd + 2), NULL, &ret);\n\tif(ret != CL_SUCCESS)\n\t{\n\t\tprinter_print_msg(\"Error %s when calling clCreateBuffer to create Branch 0 buffer.\", err_to_str(ret));\n\t\treturn ERR_OCL_API;\n\t}\n\n\t// Groestl-256 branches\n\tctx->ExtraBuffers[3] = clCreateBuffer(opencl_ctx, CL_MEM_READ_WRITE, sizeof(cl_uint) * (g_thd + 2), NULL, &ret);\n\tif(ret != CL_SUCCESS)\n\t{\n\t\tprinter_print_msg(\"Error %s when calling clCreateBuffer to create Branch 1 buffer.\", err_to_str(ret));\n\t\treturn ERR_OCL_API;\n\t}\n\n\t// JH-256 branches\n\tctx->ExtraBuffers[4] = clCreateBuffer(opencl_ctx, CL_MEM_READ_WRITE, sizeof(cl_uint) * (g_thd + 2), NULL, &ret);\n\tif(ret != CL_SUCCESS)\n\t{\n\t\tprinter_print_msg(\"Error %s when calling clCreateBuffer to create Branch 2 buffer.\", err_to_str(ret));\n\t\treturn ERR_OCL_API;\n\t}\n\n\t// Skein-512 branches\n\tctx->ExtraBuffers[5] = clCreateBuffer(opencl_ctx, CL_MEM_READ_WRITE, sizeof(cl_uint) * (g_thd + 2), NULL, &ret);\n\tif(ret != CL_SUCCESS)\n\t{\n\t\tprinter_print_msg(\"Error %s when calling clCreateBuffer to create Branch 3 buffer.\", err_to_str(ret));\n\t\treturn ERR_OCL_API;\n\t}\n\n\t// Assume we may find up to 0xFF nonces in one run - it's reasonable\n\tctx->OutputBuffer = clCreateBuffer(opencl_ctx, CL_MEM_READ_WRITE, sizeof(cl_uint) * 0x100, NULL, &ret);\n\tif(ret != CL_SUCCESS)\n\t{\n\t\tprinter_print_msg(\"Error %s when calling clCreateBuffer to create output buffer.\", err_to_str(ret));\n\t\treturn ERR_OCL_API;\n\t}\n\n\tctx->Program = clCreateProgramWithSource(opencl_ctx, 1, (const char**)&source_code, NULL, &ret);\n\tif(ret != CL_SUCCESS)\n\t{\n\t\tprinter_print_msg(\"Error %s when calling clCreateProgramWithSource on the contents of cryptonight.cl\", err_to_str(ret));\n\t\treturn ERR_OCL_API;\n\t}\n\n\tchar options[32];\n\tsnprintf(options, sizeof(options), \"-I. -DWORKSIZE=%llu\", int_port(ctx->workSize));\n\tret = clBuildProgram(ctx->Program, 1, &ctx->DeviceID, options, NULL, NULL);\n\tif(ret != CL_SUCCESS)\n\t{\n\t\tsize_t len;\n\t\tprinter_print_msg(\"Error %s when calling clBuildProgram.\", err_to_str(ret));\n\n\t\tif((ret = clGetProgramBuildInfo(ctx->Program, ctx->DeviceID, CL_PROGRAM_BUILD_LOG, 0, NULL, &len)) != CL_SUCCESS)\n\t\t{\n\t\t\tprinter_print_msg(\"Error %s when calling clGetProgramBuildInfo for length of build log output.\", err_to_str(ret));\n\t\t\treturn ERR_OCL_API;\n\t\t}\n\n\t\tchar* BuildLog = (char*)malloc(len + 1);\n\t\tBuildLog[0] = '\\0';\n\n\t\tif((ret = clGetProgramBuildInfo(ctx->Program, ctx->DeviceID, CL_PROGRAM_BUILD_LOG, len, BuildLog, NULL)) != CL_SUCCESS)\n\t\t{\n\t\t\tfree(BuildLog);\n\t\t\tprinter_print_msg(\"Error %s when calling clGetProgramBuildInfo for build log.\", err_to_str(ret));\n\t\t\treturn ERR_OCL_API;\n\t\t}\n\n\t\tprinter_print_str(\"Build log:\\n\");\n\t\tprinter_print_str(BuildLog);\n\n\t\tfree(BuildLog);\n\t\treturn ERR_OCL_API;\n\t}\n\n\tcl_build_status status;\n\tdo\n\t{\n\t\tif((ret = clGetProgramBuildInfo(ctx->Program, ctx->DeviceID, CL_PROGRAM_BUILD_STATUS, sizeof(cl_build_status), &status, NULL)) != CL_SUCCESS)\n\t\t{\n\t\t\tprinter_print_msg(\"Error %s when calling clGetProgramBuildInfo for status of build.\", err_to_str(ret));\n\t\t\treturn ERR_OCL_API;\n\t\t}\n\t\tport_sleep(1);\n\t}\n\twhile(status == CL_BUILD_IN_PROGRESS);\n\n\tconst char *KernelNames[] = { \"cn0\", \"cn1\", \"cn2\", \"Blake\", \"Groestl\", \"JH\", \"Skein\" };\n\tfor(int i = 0; i < 7; ++i)\n\t{\n\t\tctx->Kernels[i] = clCreateKernel(ctx->Program, KernelNames[i], &ret);\n\t\tif(ret != CL_SUCCESS)\n\t\t{\n\t\t\tprinter_print_msg(\"Error %s when calling clCreateKernel for kernel %s.\", err_to_str(ret), KernelNames[i]);\n\t\t\treturn ERR_OCL_API;\n\t\t}\n\t}\n\n\tctx->Nonce = 0;\n\treturn 0;\n}\n\n// RequestedDeviceIdxs is a list of OpenCL device indexes\n// NumDevicesRequested is number of devices in RequestedDeviceIdxs list\n// Returns 0 on success, -1 on stupid params, -2 on OpenCL API error\nsize_t InitOpenCL(GpuContext* ctx, size_t num_gpus, size_t platform_idx)\n{\n\tcl_context opencl_ctx;\n\tcl_int ret;\n\tcl_uint entries;\n\n\tif((ret = clGetPlatformIDs(0, NULL, &entries)) != CL_SUCCESS)\n\t{\n\t\tprinter_print_msg(\"Error %s when calling clGetPlatformIDs for number of platforms.\", err_to_str(ret));\n\t\treturn ERR_OCL_API;\n\t}\n\n\t// The number of platforms naturally is the index of the last platform plus one.\n\tif(entries <= platform_idx)\n\t{\n\t\tprinter_print_msg(\"Selected OpenCL platform index %d doesn't exist.\", platform_idx);\n\t\treturn ERR_STUPID_PARAMS;\n\t}\n\n\t/*MSVC skimping on devel costs by shoehorning C99 to be a subset of C++? Noooo... can't be.*/\n#ifdef __GNUC__\n\tcl_platform_id PlatformIDList[entries];\n#else\n\tcl_platform_id* PlatformIDList = _alloca(entries * sizeof(cl_platform_id));\n#endif\n\tif((ret = clGetPlatformIDs(entries, PlatformIDList, NULL)) != CL_SUCCESS)\n\t{\n\t\tprinter_print_msg(\"Error %s when calling clGetPlatformIDs for platform ID information.\", err_to_str(ret));\n\t\treturn ERR_OCL_API;\n\t}\n\n\tif((ret = clGetDeviceIDs(PlatformIDList[platform_idx], CL_DEVICE_TYPE_GPU, 0, NULL, &entries)) != CL_SUCCESS)\n\t{\n\t\tprinter_print_msg(\"Error %s when calling clGetDeviceIDs for number of devices.\", err_to_str(ret));\n\t\treturn ERR_OCL_API;\n\t}\n\n\t// Same as the platform index sanity check, except we must check all requested device indexes\n\tfor(int i = 0; i < num_gpus; ++i)\n\t{\n\t\tif(entries <= ctx[i].deviceIdx)\n\t\t{\n\t\t\tprinter_print_msg(\"Selected OpenCL device index %lu doesn't exist.\\n\", ctx[i].deviceIdx);\n\t\t\treturn ERR_STUPID_PARAMS;\n\t\t}\n\t}\n\n#ifdef __GNUC__\n\tcl_device_id DeviceIDList[entries];\n#else\n\tcl_device_id* DeviceIDList = _alloca(entries * sizeof(cl_device_id));\n#endif\n\tif((ret = clGetDeviceIDs(PlatformIDList[platform_idx], CL_DEVICE_TYPE_GPU, entries, DeviceIDList, NULL)) != CL_SUCCESS)\n\t{\n\t\tprinter_print_msg(\"Error %s when calling clGetDeviceIDs for device ID information.\", err_to_str(ret));\n\t\treturn ERR_OCL_API;\n\t}\n\n\t// Indexes sanity checked above\n#ifdef __GNUC__\n\tcl_device_id TempDeviceList[num_gpus];\n#else\n\tcl_device_id* TempDeviceList = _alloca(entries * sizeof(cl_device_id));\n#endif\n\tfor(int i = 0; i < num_gpus; ++i)\n\t{\n\t\tctx[i].DeviceID = DeviceIDList[ctx[i].deviceIdx];\n\t\tTempDeviceList[i] = DeviceIDList[ctx[i].deviceIdx];\n\t}\n\n\topencl_ctx = clCreateContext(NULL, num_gpus, TempDeviceList, NULL, NULL, &ret);\n\tif(ret != CL_SUCCESS)\n\t{\n\t\tprinter_print_msg(\"Error %s when calling clCreateContext.\", err_to_str(ret));\n\t\treturn ERR_OCL_API;\n\t}\n\n\tchar* source_code = LoadTextFile(sSourcePath);\n\tif(source_code == NULL)\n\t{\n\t\tprinter_print_msg(\"Couldn't locate GPU source code file at %s.\", sSourcePath);\n\t\treturn ERR_STUPID_PARAMS;\n\t}\n\n\tfor(int i = 0; i < num_gpus; ++i)\n\t{\n\t\tif((ret = InitOpenCLGpu(opencl_ctx, &ctx[i], source_code)) != ERR_SUCCESS)\n\t\t{\n\t\t\tfree(source_code);\n\t\t\treturn ret;\n\t\t}\n\t}\n\tfree(source_code);\n\n\treturn ERR_SUCCESS;\n}\n\nsize_t XMRSetJob(GpuContext* ctx, uint8_t* input, size_t input_len, uint32_t target)\n{\n\tcl_int ret;\n\n\tif(input_len > 84)\n\t\treturn ERR_STUPID_PARAMS;\n\n\tinput[input_len] = 0x01;\n\tmemset(input + input_len + 1, 0, 88 - input_len - 1);\n\n\tif((ret = clEnqueueWriteBuffer(ctx->CommandQueues, ctx->InputBuffer, CL_TRUE, 0, 88, input, 0, NULL, NULL)) != CL_SUCCESS)\n\t{\n\t\tprinter_print_msg(\"Error %s when calling clEnqueueWriteBuffer to fill input buffer.\", err_to_str(ret));\n\t\treturn ERR_OCL_API;\n\t}\n\n\tif((ret = clSetKernelArg(ctx->Kernels[0], 0, sizeof(cl_mem), &ctx->InputBuffer)) != CL_SUCCESS)\n\t{\n\t\tprinter_print_msg(\"Error %s when calling clSetKernelArg for kernel 0, argument 0.\", err_to_str(ret));\n\t\treturn ERR_OCL_API;\n\t}\n\n\t// Scratchpads\n\tif((ret = clSetKernelArg(ctx->Kernels[0], 1, sizeof(cl_mem), ctx->ExtraBuffers + 0)) != CL_SUCCESS)\n\t{\n\t\tprinter_print_msg(\"Error %s when calling clSetKernelArg for kernel 0, argument 1.\", err_to_str(ret));\n\t\treturn ERR_OCL_API;\n\t}\n\n\t// States\n\tif((ret = clSetKernelArg(ctx->Kernels[0], 2, sizeof(cl_mem), ctx->ExtraBuffers + 1)) != CL_SUCCESS)\n\t{\n\t\tprinter_print_msg(\"Error %s when calling clSetKernelArg for kernel 0, argument 2.\", err_to_str(ret));\n\t\treturn ERR_OCL_API;\n\t}\n\n\t// CN2 Kernel\n\n\t// Scratchpads\n\tif((ret = clSetKernelArg(ctx->Kernels[1], 0, sizeof(cl_mem), ctx->ExtraBuffers + 0)) != CL_SUCCESS)\n\t{\n\t\tprinter_print_msg(\"Error %s when calling clSetKernelArg for kernel 1, argument 0.\", err_to_str(ret));\n\t\treturn ERR_OCL_API;\n\t}\n\n\t// States\n\tif((ret = clSetKernelArg(ctx->Kernels[1], 1, sizeof(cl_mem), ctx->ExtraBuffers + 1)) != CL_SUCCESS)\n\t{\n\t\tprinter_print_msg(\"Error %s when calling clSetKernelArg for kernel 1, argument 1.\", err_to_str(ret));\n\t\treturn ERR_OCL_API;\n\t}\n\n\t// CN3 Kernel\n\t// Scratchpads\n\tif((ret = clSetKernelArg(ctx->Kernels[2], 0, sizeof(cl_mem), ctx->ExtraBuffers + 0)) != CL_SUCCESS)\n\t{\n\t\tprinter_print_msg(\"Error %s when calling clSetKernelArg for kernel 2, argument 0.\", err_to_str(ret));\n\t\treturn ERR_OCL_API;\n\t}\n\n\t// States\n\tif((ret = clSetKernelArg(ctx->Kernels[2], 1, sizeof(cl_mem), ctx->ExtraBuffers + 1)) != CL_SUCCESS)\n\t{\n\t\tprinter_print_msg(\"Error %s when calling clSetKernelArg for kernel 2, argument 1.\", err_to_str(ret));\n\t\treturn ERR_OCL_API;\n\t}\n\n\t// Branch 0\n\tif((ret = clSetKernelArg(ctx->Kernels[2], 2, sizeof(cl_mem), ctx->ExtraBuffers + 2)) != CL_SUCCESS)\n\t{\n\t\tprinter_print_msg(\"Error %s when calling clSetKernelArg for kernel 2, argument 2.\", err_to_str(ret));\n\t\treturn ERR_OCL_API;\n\t}\n\n\t// Branch 1\n\tif((ret = clSetKernelArg(ctx->Kernels[2], 3, sizeof(cl_mem), ctx->ExtraBuffers + 3)) != CL_SUCCESS)\n\t{\n\t\tprinter_print_msg(\"Error %s when calling clSetKernelArg for kernel 2, argument 3.\", err_to_str(ret));\n\t\treturn ERR_OCL_API;\n\t}\n\n\t// Branch 2\n\tif((ret = clSetKernelArg(ctx->Kernels[2], 4, sizeof(cl_mem), ctx->ExtraBuffers + 4)) != CL_SUCCESS)\n\t{\n\t\tprinter_print_msg(\"Error %s when calling clSetKernelArg for kernel 2, argument 4.\", err_to_str(ret));\n\t\treturn ERR_OCL_API;\n\t}\n\n\t// Branch 3\n\tif((ret = clSetKernelArg(ctx->Kernels[2], 5, sizeof(cl_mem), ctx->ExtraBuffers + 5)) != CL_SUCCESS)\n\t{\n\t\tprinter_print_msg(\"Error %s when calling clSetKernelArg for kernel 2, argument 5.\", err_to_str(ret));\n\t\treturn ERR_OCL_API;\n\t}\n\n\tfor(int i = 0; i < 4; ++i)\n\t{\n\t\t// States\n\t\tif((ret = clSetKernelArg(ctx->Kernels[i + 3], 0, sizeof(cl_mem), ctx->ExtraBuffers + 1)) != CL_SUCCESS)\n\t\t{\n\t\t\tprinter_print_msg(\"Error %s when calling clSetKernelArg for kernel %d, argument %d.\", err_to_str(ret), i + 3, 0);\n\t\t\treturn ERR_OCL_API;\n\t\t}\n\n\t\t// Nonce buffer\n\t\tif((ret = clSetKernelArg(ctx->Kernels[i + 3], 1, sizeof(cl_mem), ctx->ExtraBuffers + (i + 2))) != CL_SUCCESS)\n\t\t{\n\t\t\tprinter_print_msg(\"Error %s when calling clSetKernelArg for kernel %d, argument %d.\", err_to_str(ret), i + 3, 1);\n\t\t\treturn ERR_OCL_API;\n\t\t}\n\n\t\t// Output\n\t\tif((ret = clSetKernelArg(ctx->Kernels[i + 3], 2, sizeof(cl_mem), &ctx->OutputBuffer)) != CL_SUCCESS)\n\t\t{\n\t\t\tprinter_print_msg(\"Error %s when calling clSetKernelArg for kernel %d, argument %d.\", err_to_str(ret), i + 3, 2);\n\t\t\treturn ERR_OCL_API;\n\t\t}\n\n\t\t// Target\n\t\tif((ret = clSetKernelArg(ctx->Kernels[i + 3], 3, sizeof(cl_uint), &target)) != CL_SUCCESS)\n\t\t{\n\t\t\tprinter_print_msg(\"Error %s when calling clSetKernelArg for kernel %d, argument %d.\", err_to_str(ret), i + 3, 3);\n\t\t\treturn ERR_OCL_API;\n\t\t}\n\t}\n\n\treturn ERR_SUCCESS;\n}\n\nsize_t XMRRunJob(GpuContext* ctx, cl_uint* HashOutput)\n{\n\tcl_int ret;\n\tcl_uint zero = 0;\n\tsize_t BranchNonces[4] = {0};\n\n\tsize_t g_thd = ctx->rawIntensity;\n\tsize_t w_size = ctx->workSize;\n\n\tfor(int i = 2; i < 6; ++i)\n\t{\n\t\tif((ret = clEnqueueWriteBuffer(ctx->CommandQueues, ctx->ExtraBuffers[i], CL_FALSE, sizeof(cl_uint) * g_thd, sizeof(cl_uint), &zero, 0, NULL, NULL)) != CL_SUCCESS)\n\t\t{\n\t\t\tprinter_print_msg(\"Error %s when calling clEnqueueWriteBuffer to zero branch buffer counter %d.\", err_to_str(ret), i - 2);\n\t\t\treturn ERR_OCL_API;\n\t\t}\n\t}\n\n\tif((ret = clEnqueueWriteBuffer(ctx->CommandQueues, ctx->OutputBuffer, CL_FALSE, sizeof(cl_uint) * 0xFF, sizeof(cl_uint), &zero, 0, NULL, NULL)) != CL_SUCCESS)\n\t{\n\t\tprinter_print_msg(\"Error %s when calling clEnqueueReadBuffer to fetch results.\", err_to_str(ret));\n\t\treturn ERR_OCL_API;\n\t}\n\n\tclFinish(ctx->CommandQueues);\n\n\tsize_t Nonce[2] = {ctx->Nonce, 1}, gthreads[2] = { g_thd, 8 }, lthreads[2] = { w_size, 8 };\n\tif((ret = clEnqueueNDRangeKernel(ctx->CommandQueues, ctx->Kernels[0], 2, Nonce, gthreads, lthreads, 0, NULL, NULL)) != CL_SUCCESS)\n\t{\n\t\tprinter_print_msg(\"Error %s when calling clEnqueueNDRangeKernel for kernel %d.\", err_to_str(ret), 0);\n\t\treturn ERR_OCL_API;\n\t}\n\n\t/*for(int i = 1; i < 3; ++i)\n\t{\n\t\tif((ret = clEnqueueNDRangeKernel(*ctx->CommandQueues, ctx->Kernels[i], 1, &ctx->Nonce, &g_thd, &w_size, 0, NULL, NULL)) != CL_SUCCESS)\n\t\t{\n\t\t\tLog(LOG_CRITICAL, \"Error %s when calling clEnqueueNDRangeKernel for kernel %d.\", err_to_str(ret), i);\n\t\t\treturn(ERR_OCL_API);\n\t\t}\n\t}*/\n\n\tif((ret = clEnqueueNDRangeKernel(ctx->CommandQueues, ctx->Kernels[1], 1, &ctx->Nonce, &g_thd, &w_size, 0, NULL, NULL)) != CL_SUCCESS)\n\t{\n\t\tprinter_print_msg(\"Error %s when calling clEnqueueNDRangeKernel for kernel %d.\", err_to_str(ret), 1);\n\t\treturn ERR_OCL_API;\n\t}\n\n\tif((ret = clEnqueueNDRangeKernel(ctx->CommandQueues, ctx->Kernels[2], 2, Nonce, gthreads, lthreads, 0, NULL, NULL)) != CL_SUCCESS)\n\t{\n\t\tprinter_print_msg(\"Error %s when calling clEnqueueNDRangeKernel for kernel %d.\", err_to_str(ret), 2);\n\t\treturn ERR_OCL_API;\n\t}\n\n\tif((ret = clEnqueueReadBuffer(ctx->CommandQueues, ctx->ExtraBuffers[2], CL_FALSE, sizeof(cl_uint) * g_thd, sizeof(cl_uint), BranchNonces, 0, NULL, NULL)) != CL_SUCCESS)\n\t{\n\t\tprinter_print_msg(\"Error %s when calling clEnqueueReadBuffer to fetch results.\", err_to_str(ret));\n\t\treturn ERR_OCL_API;\n\t}\n\n\tif((ret = clEnqueueReadBuffer(ctx->CommandQueues, ctx->ExtraBuffers[3], CL_FALSE, sizeof(cl_uint) * g_thd, sizeof(cl_uint), BranchNonces + 1, 0, NULL, NULL)) != CL_SUCCESS)\n\t{\n\t\tprinter_print_msg(\"Error %s when calling clEnqueueReadBuffer to fetch results.\", err_to_str(ret));\n\t\treturn ERR_OCL_API;\n\t}\n\n\tif((ret = clEnqueueReadBuffer(ctx->CommandQueues, ctx->ExtraBuffers[4], CL_FALSE, sizeof(cl_uint) * g_thd, sizeof(cl_uint), BranchNonces + 2, 0, NULL, NULL)) != CL_SUCCESS)\n\t{\n\t\tprinter_print_msg(\"Error %s when calling clEnqueueReadBuffer to fetch results.\", err_to_str(ret));\n\t\treturn ERR_OCL_API;\n\t}\n\n\tif((ret = clEnqueueReadBuffer(ctx->CommandQueues, ctx->ExtraBuffers[5], CL_FALSE, sizeof(cl_uint) * g_thd, sizeof(cl_uint), BranchNonces + 3, 0, NULL, NULL)) != CL_SUCCESS)\n\t{\n\t\tprinter_print_msg(\"Error %s when calling clEnqueueReadBuffer to fetch results.\", err_to_str(ret));\n\t\treturn ERR_OCL_API;\n\t}\n\n\tclFinish(ctx->CommandQueues);\n\n\tfor(int i = 0; i < 4; ++i)\n\t{\n\t\tif(BranchNonces[i])\n\t\t{\n\t\t\t// Threads\n\t\t\tif((clSetKernelArg(ctx->Kernels[i + 3], 4, sizeof(cl_ulong), BranchNonces + i)) != CL_SUCCESS)\n\t\t\t{\n\t\t\t\tprinter_print_msg(\"Error %s when calling clSetKernelArg for kernel %d, argument %d.\", err_to_str(ret), i + 3, 4);\n\t\t\t\treturn(ERR_OCL_API);\n\t\t\t}\n\n\t\t\tBranchNonces[i] = ((size_t)ceil( (double)BranchNonces[i] / (double)w_size) ) * w_size;\n\t\t\tif((ret = clEnqueueNDRangeKernel(ctx->CommandQueues, ctx->Kernels[i + 3], 1, &ctx->Nonce, BranchNonces + i, &w_size, 0, NULL, NULL)) != CL_SUCCESS)\n\t\t\t{\n\t\t\t\tprinter_print_msg(\"Error %s when calling clEnqueueNDRangeKernel for kernel %d.\", err_to_str(ret), i + 3);\n\t\t\t\treturn ERR_OCL_API;\n\t\t\t}\n\t\t}\n\t}\n\n\tif((ret = clEnqueueReadBuffer(ctx->CommandQueues, ctx->OutputBuffer, CL_TRUE, 0, sizeof(cl_uint) * 0x100, HashOutput, 0, NULL, NULL)) != CL_SUCCESS)\n\t{\n\t\tprinter_print_msg(\"Error %s when calling clEnqueueReadBuffer to fetch results.\", err_to_str(ret));\n\t\treturn ERR_OCL_API;\n\t}\n\n\tclFinish(ctx->CommandQueues);\n\tctx->Nonce += g_thd;\n\n\treturn ERR_SUCCESS;\n}\n"
  },
  {
    "path": "amd_gpu/gpu.h",
    "content": "#pragma once\n\n#include <CL/cl.h>\n#include <stdint.h>\n\n#define ERR_SUCCESS (0)\n#define ERR_OCL_API (2)\n#define ERR_STUPID_PARAMS (1)\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif // __cplusplus\n\ntypedef struct _GpuContext\n{\n\t/*Input vars*/\n\tsize_t deviceIdx;\n\tsize_t rawIntensity;\n\tsize_t workSize;\n\n\t/*Output vars*/\n\tcl_device_id DeviceID;\n\tcl_command_queue CommandQueues;\n\tcl_mem InputBuffer;\n\tcl_mem OutputBuffer;\n\tcl_mem ExtraBuffers[6];\n\tcl_program Program;\n\tcl_kernel Kernels[7];\n\n\tsize_t Nonce;\n} GpuContext;\n\nsize_t InitOpenCL(GpuContext* ctx, size_t num_gpus, size_t platform_idx);\nsize_t XMRSetJob(GpuContext* ctx, uint8_t* input, size_t input_len, uint32_t target);\nsize_t XMRRunJob(GpuContext* ctx, cl_uint* HashOutput);\n\n#ifdef __cplusplus\n}\n#endif // __cplusplus\n"
  },
  {
    "path": "cli-miner.cpp",
    "content": " /*\n  * This program is free software: you can redistribute it and/or modify\n  * it under the terms of the GNU General Public License as published by\n  * the Free Software Foundation, either version 3 of the License, or\n  * any later version.\n  *\n  * This program is distributed in the hope that it will be useful,\n  * but WITHOUT ANY WARRANTY; without even the implied warranty of\n  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n  * GNU General Public License for more details.\n  *\n  * You should have received a copy of the GNU General Public License\n  * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n  *\n  * Additional permission under GNU GPL version 3 section 7\n  *\n  * If you modify this Program, or any covered work, by linking or combining\n  * it with OpenSSL (or a modified version of that library), containing parts\n  * covered by the terms of OpenSSL License and SSLeay License, the licensors\n  * of this Program grant you additional permission to convey the resulting work.\n  *\n  */\n\n#include \"executor.h\"\n#include \"minethd.h\"\n#include \"jconf.h\"\n#include \"console.h\"\n#include \"donate-level.h\"\n#include \"version.h\"\n\n#ifndef CONF_NO_HTTPD\n#\tinclude \"httpd.h\"\n#endif\n\n#include <stdlib.h>\n#include <stdio.h>\n#include <string.h>\n\n#ifndef CONF_NO_TLS\n#include <openssl/ssl.h>\n#include <openssl/err.h>\n#endif\n\n//Do a press any key for the windows folk. *insert any key joke here*\n#ifdef _WIN32\nvoid win_exit()\n{\n\tprinter::inst()->print_str(\"Press any key to exit.\");\n\tget_key();\n\treturn;\n}\n\n#define strcasecmp _stricmp\n\n#else\nvoid win_exit() { return; }\n#endif // _WIN32\n\nvoid do_benchmark();\n\nint main(int argc, char *argv[])\n{\n#ifndef CONF_NO_TLS\n\tSSL_library_init();\n\tSSL_load_error_strings();\n\tERR_load_BIO_strings();\n\tERR_load_crypto_strings();\n\tSSL_load_error_strings();\n\tOpenSSL_add_all_digests();\n#endif\n\n\tconst char* sFilename = \"config.txt\";\n\tbool benchmark_mode = false;\n\n\tif(argc >= 2)\n\t{\n\t\tif(strcmp(argv[1], \"-h\") == 0)\n\t\t{\n\t\t\tprinter::inst()->print_msg(L0, \"Usage %s [CONFIG FILE]\", argv[0]);\n\t\t\twin_exit();\n\t\t\treturn 0;\n\t\t}\n\n\t\tif(argc >= 3 && strcasecmp(argv[1], \"-c\") == 0)\n\t\t{\n\t\t\tsFilename = argv[2];\n\t\t}\n\t\telse if(argc >= 3 && strcasecmp(argv[1], \"benchmark_mode\") == 0)\n\t\t{\n\t\t\tsFilename = argv[2];\n\t\t\tbenchmark_mode = true;\n\t\t}\n\t\telse\n\t\t\tsFilename = argv[1];\n\t}\n\n\tif(!jconf::inst()->parse_config(sFilename))\n\t{\n\t\twin_exit();\n\t\treturn 0;\n\t}\n\n\tif(!minethd::init_gpus())\n\t{\n\t\twin_exit();\n\t\treturn 0;\n\t}\n\n\tif(benchmark_mode)\n\t{\n\t\tdo_benchmark();\n\t\twin_exit();\n\t\treturn 0;\n\t}\n\n#ifndef CONF_NO_HTTPD\n\tif(jconf::inst()->GetHttpdPort() != 0)\n\t{\n\t\tif (!httpd::inst()->start_daemon())\n\t\t{\n\t\t\twin_exit();\n\t\t\treturn 0;\n\t\t}\n\t}\n#endif\n\n\tprinter::inst()->print_str(\"-------------------------------------------------------------------\\n\");\n\tprinter::inst()->print_str( XMR_STAK_NAME\" \" XMR_STAK_VERSION \" mining software, AMD Version.\\n\");\n\tprinter::inst()->print_str(\"AMD mining code was written by wolf9466.\\n\");\n\tprinter::inst()->print_str(\"Brought to you by fireice_uk under GPLv3.\\n\\n\");\n\tchar buffer[64];\n\tsnprintf(buffer, sizeof(buffer), \"Configurable dev donation level is set to %.1f %%\\n\\n\", fDevDonationLevel * 100.0);\n\tprinter::inst()->print_str(buffer);\n\tprinter::inst()->print_str(\"You can use following keys to display reports:\\n\");\n\tprinter::inst()->print_str(\"'h' - hashrate\\n\");\n\tprinter::inst()->print_str(\"'r' - results\\n\");\n\tprinter::inst()->print_str(\"'c' - connection\\n\");\n\tprinter::inst()->print_str(\"-------------------------------------------------------------------\\n\");\n\n\tif(strlen(jconf::inst()->GetOutputFile()) != 0)\n\t\tprinter::inst()->open_logfile(jconf::inst()->GetOutputFile());\n\n\texecutor::inst()->ex_start(jconf::inst()->DaemonMode());\n\n\tusing namespace std::chrono;\n\tuint64_t lastTime = time_point_cast<milliseconds>(high_resolution_clock::now()).time_since_epoch().count();\n\n\tint key;\n\twhile(true)\n\t{\n\t\tkey = get_key();\n\n\t\tswitch(key)\n\t\t{\n\t\tcase 'h':\n\t\t\texecutor::inst()->push_event(ex_event(EV_USR_HASHRATE));\n\t\t\tbreak;\n\t\tcase 'r':\n\t\t\texecutor::inst()->push_event(ex_event(EV_USR_RESULTS));\n\t\t\tbreak;\n\t\tcase 'c':\n\t\t\texecutor::inst()->push_event(ex_event(EV_USR_CONNSTAT));\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\n\t\tuint64_t currentTime = time_point_cast<milliseconds>(high_resolution_clock::now()).time_since_epoch().count();\n\n\t\t/* Hard guard to make sure we never get called more than twice per second */\n\t\tif( currentTime - lastTime < 500)\n\t\t\tstd::this_thread::sleep_for(std::chrono::milliseconds(500 - (currentTime - lastTime)));\n\t\tlastTime = currentTime;\n\t}\n\n\treturn 0;\n}\n\nvoid do_benchmark()\n{\n\tusing namespace std::chrono;\n\tstd::vector<minethd*>* pvThreads;\n\n\tprinter::inst()->print_msg(L0, \"Running a 60 second benchmark...\");\n\n\tuint8_t work[76] = {0};\n\tminethd::miner_work oWork = minethd::miner_work(\"\", work, sizeof(work), 0, 0, 0);\n\tpvThreads = minethd::thread_starter(oWork);\n\n\tuint64_t iStartStamp = time_point_cast<milliseconds>(high_resolution_clock::now()).time_since_epoch().count();\n\n\tstd::this_thread::sleep_for(std::chrono::seconds(60));\n\n\toWork = minethd::miner_work();\n\tminethd::switch_work(oWork);\n\n\tdouble fTotalHps = 0.0;\n\tfor (uint32_t i = 0; i < pvThreads->size(); i++)\n\t{\n\t\tdouble fHps = pvThreads->at(i)->iHashCount;\n\t\tfHps /= (pvThreads->at(i)->iTimestamp - iStartStamp) / 1000.0;\n\n\t\tprinter::inst()->print_msg(L0, \"Thread %u: %.1f H/S\", i, fHps);\n\t\tfTotalHps += fHps;\n\t}\n\n\tprinter::inst()->print_msg(L0, \"Total: %.1f H/S\", fTotalHps);\n}\n"
  },
  {
    "path": "config.txt",
    "content": "/* \r\n * Number of GPUs that you have in your system. Each GPU will get its own CPU thread.\r\n */\r\n\"gpu_thread_num\" : 6,\r\n\r\n/*\r\n * GPU configuration. You should play around with intensity and worksize as the fastest settings will vary.\r\n *      index    - GPU index number usually starts from 0\r\n *  intensity    - Number of parallel GPU threads (nothing to do with CPU threads)\r\n *   worksize    - Number of local GPU threads (nothing to do with CPU threads)\r\n * affine_to_cpu - This will affine the thread to a CPU. This can make a GPU miner play along nicer with a CPU miner.\r\n */\r\n\"gpu_threads_conf\" : [ \r\n\t{ \"index\" : 0, \"intensity\" : 1000, \"worksize\" : 8, \"affine_to_cpu\" : false },\r\n\t{ \"index\" : 1, \"intensity\" : 1000, \"worksize\" : 8, \"affine_to_cpu\" : false },\r\n\t{ \"index\" : 2, \"intensity\" : 1000, \"worksize\" : 8, \"affine_to_cpu\" : false },\r\n\t{ \"index\" : 3, \"intensity\" : 1000, \"worksize\" : 8, \"affine_to_cpu\" : false },\r\n\t{ \"index\" : 4, \"intensity\" : 1000, \"worksize\" : 8, \"affine_to_cpu\" : false },\r\n\t{ \"index\" : 5, \"intensity\" : 1000, \"worksize\" : 8, \"affine_to_cpu\" : false },\r\n],\r\n\r\n/*\r\n * Platform index. This will be 0 unless you have different OpenCL platform - eg. AMD and Intel.\r\n */\r\n\"platform_index\" : 0,\r\n\r\n/*\r\n * TLS Settings\r\n * If you need real security, make sure tls_secure_algo is enabled (otherwise MITM attack can downgrade encryption\r\n * to trivially breakable stuff like DES and MD5), and verify the server's fingerprint through a trusted channel. \r\n *\r\n * use_tls         - This option will make us connect using Transport Layer Security.\r\n * tls_secure_algo - Use only secure algorithms. This will make us quit with an error if we can't negotiate a secure algo.\r\n * tls_fingerprint - Server's SHA256 fingerprint. If this string is non-empty then we will check the server's cert against it.\r\n */\r\n\"use_tls\" : false,\r\n\"tls_secure_algo\" : true,\r\n\"tls_fingerprint\" : \"\",\r\n\r\n/*\r\n * pool_address\t  - Pool address should be in the form \"pool.supportxmr.com:3333\". Only stratum pools are supported.\r\n * wallet_address - Your wallet, or pool login.\r\n * pool_password  - Can be empty in most cases or \"x\".\r\n */\r\n\"pool_address\" : \"pool.supportxmr.com:3333\",\r\n\"wallet_address\" : \"\",\r\n\"pool_password\" : \"\",\r\n\r\n/*\r\n * Network timeouts.\r\n * Because of the way this client is written it doesn't need to constantly talk (keep-alive) to the server to make \r\n * sure it is there. We detect a buggy / overloaded server by the call timeout. The default values will be ok for \r\n * nearly all cases. If they aren't the pool has most likely overload issues. Low call timeout values are preferable -\r\n * long timeouts mean that we waste hashes on potentially stale jobs. Connection report will tell you how long the\r\n * server usually takes to process our calls.\r\n *\r\n * call_timeout - How long should we wait for a response from the server before we assume it is dead and drop the connection.\r\n * retry_time\t- How long should we wait before another connection attempt.\r\n *                Both values are in seconds.\r\n * giveup_limit - Limit how many times we try to reconnect to the pool. Zero means no limit. Note that stak miners\r\n *                don't mine while the connection is lost, so your computer's power usage goes down to idle.\r\n */\r\n\"call_timeout\" : 10,\r\n\"retry_time\" : 10,\r\n\"giveup_limit\" : 0,\r\n\r\n/*\r\n * Output control.\r\n * Since most people are used to miners printing all the time, that's what we do by default too. This is suboptimal\r\n * really, since you cannot see errors under pages and pages of text and performance stats. Given that we have internal\r\n * performance monitors, there is very little reason to spew out pages of text instead of concise reports.\r\n * Press 'h' (hashrate), 'r' (results) or 'c' (connection) to print reports.\r\n *\r\n * verbose_level - 0 - Don't print anything. \r\n *                 1 - Print intro, connection event, disconnect event\r\n *                 2 - All of level 1, and new job (block) event if the difficulty is different from the last job\r\n *                 3 - All of level 1, and new job (block) event in all cases, result submission event.\r\n *                 4 - All of level 3, and automatic hashrate report printing \r\n */\r\n\"verbose_level\" : 3,\r\n\r\n/*\r\n * Automatic hashrate report\r\n *\r\n * h_print_time - How often, in seconds, should we print a hashrate report if verbose_level is set to 4.\r\n *                This option has no effect if verbose_level is not 4.\r\n */\r\n\"h_print_time\" : 60,\r\n\r\n/*\r\n * Daemon mode\r\n *\r\n * If you are running the process in the background and you don't need the keyboard reports, set this to true.\r\n * This should solve the hashrate problems on some emulated terminals.\r\n */\r\n\"daemon_mode\" : false,\r\n\r\n/*\r\n * Output file\r\n *\r\n * output_file  - This option will log all output to a file.\r\n *\r\n */\r\n\"output_file\" : \"\",\r\n\r\n/*\r\n * Built-in web server\r\n * I like checking my hashrate on my phone. Don't you?\r\n * Keep in mind that you will need to set up port forwarding on your router if you want to access it from\r\n * outside of your home network. Ports lower than 1024 on Linux systems will require root.\r\n *\r\n * httpd_port - Port we should listen on. Default, 0, will switch off the server.\r\n */\r\n\"httpd_port\" : 0,\r\n\r\n/*\r\n * prefer_ipv4 - IPv6 preference. If the host is available on both IPv4 and IPv6 net, which one should be choose?\r\n *               This setting will only be needed in 2020's. No need to worry about it now.\r\n */\r\n\"prefer_ipv4\" : true,\r\n"
  },
  {
    "path": "console.cpp",
    "content": "/*\n  * This program is free software: you can redistribute it and/or modify\n  * it under the terms of the GNU General Public License as published by\n  * the Free Software Foundation, either version 3 of the License, or\n  * any later version.\n  *\n  * This program is distributed in the hope that it will be useful,\n  * but WITHOUT ANY WARRANTY; without even the implied warranty of\n  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n  * GNU General Public License for more details.\n  *\n  * You should have received a copy of the GNU General Public License\n  * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n  *\n  * Additional permission under GNU GPL version 3 section 7\n  *\n  * If you modify this Program, or any covered work, by linking or combining\n  * it with OpenSSL (or a modified version of that library), containing parts\n  * covered by the terms of OpenSSL License and SSLeay License, the licensors\n  * of this Program grant you additional permission to convey the resulting work.\n  *\n  */\n\n#include \"console.h\"\n#include <time.h>\n#include <stdio.h>\n#include <string.h>\n#include <stdarg.h>\n\n#ifdef _WIN32\n#include <windows.h>\n\nint get_key()\n{\n\tDWORD mode, rd;\n\tHANDLE h;\n\n\tif ((h = GetStdHandle(STD_INPUT_HANDLE)) == NULL)\n\t\treturn -1;\n\n\tGetConsoleMode( h, &mode );\n\tSetConsoleMode( h, mode & ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT) );\n\n\tint c = 0;\n\tReadConsole( h, &c, 1, &rd, NULL );\n\tSetConsoleMode( h, mode );\n\n\treturn c;\n}\n\nvoid set_colour(out_colours cl)\n{\n\tWORD attr = 0;\n\n\tswitch(cl)\n\t{\n\tcase K_RED:\n\t\tattr = FOREGROUND_RED | FOREGROUND_INTENSITY;\n\t\tbreak;\n\tcase K_GREEN:\n\t\tattr = FOREGROUND_GREEN | FOREGROUND_INTENSITY;\n\t\tbreak;\n\tcase K_BLUE:\n\t\tattr = FOREGROUND_BLUE | FOREGROUND_INTENSITY;\n\t\tbreak;\n\tcase K_YELLOW:\n\t\tattr = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY;\n\t\tbreak;\n\tcase K_CYAN:\n\t\tattr = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY;\n\t\tbreak;\n\tcase K_MAGENTA:\n\t\tattr = FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY;\n\t\tbreak;\n\tcase K_WHITE:\n\t\tattr = FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY;\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\n\tSetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), attr);\n}\n\nvoid reset_colour()\n{\n\tSetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);\n}\n\n#else\n#include <termios.h>\n#include <unistd.h>\n#include <stdio.h>\n\nint get_key()\n{\n\tstruct termios oldattr, newattr;\n\tint ch;\n\ttcgetattr( STDIN_FILENO, &oldattr );\n\tnewattr = oldattr;\n\tnewattr.c_lflag &= ~( ICANON | ECHO );\n\ttcsetattr( STDIN_FILENO, TCSANOW, &newattr );\n\tch = getchar();\n\ttcsetattr( STDIN_FILENO, TCSANOW, &oldattr );\n\treturn ch;\n}\n\nvoid set_colour(out_colours cl)\n{\n\tswitch(cl)\n\t{\n\tcase K_RED:\n\t\tfputs(\"\\x1B[1;31m\", stdout);\n\t\tbreak;\n\tcase K_GREEN:\n\t\tfputs(\"\\x1B[1;32m\", stdout);\n\t\tbreak;\n\tcase K_BLUE:\n\t\tfputs(\"\\x1B[1;34m\", stdout);\n\t\tbreak;\n\tcase K_YELLOW:\n\t\tfputs(\"\\x1B[1;33m\", stdout);\n\t\tbreak;\n\tcase K_CYAN:\n\t\tfputs(\"\\x1B[1;36m\", stdout);\n\t\tbreak;\n\tcase K_MAGENTA:\n\t\tfputs(\"\\x1B[1;35m\", stdout);\n\t\tbreak;\n\tcase K_WHITE:\n\t\tfputs(\"\\x1B[1;37m\", stdout);\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n}\n\nvoid reset_colour()\n{\n\tfputs(\"\\x1B[0m\", stdout);\n}\n#endif // _WIN32\n\ninline void comp_localtime(const time_t* ctime, tm* stime)\n{\n#ifdef _WIN32\n\tlocaltime_s(stime, ctime);\n#else\n\tlocaltime_r(ctime, stime);\n#endif // __WIN32\n}\n\nprinter* printer::oInst = nullptr;\n\nprinter::printer()\n{\n\tverbose_level = LINF;\n\tlogfile = nullptr;\n}\n\nbool printer::open_logfile(const char* file)\n{\n\tlogfile = fopen(file, \"ab+\");\n\treturn logfile != nullptr;\n}\n\nvoid printer::print_msg(verbosity verbose, const char* fmt, ...)\n{\n\tif(verbose > verbose_level)\n\t\treturn;\n\n\tchar buf[1024];\n\tsize_t bpos;\n\ttm stime;\n\n\ttime_t now = time(nullptr);\n\tcomp_localtime(&now, &stime);\n\tstrftime(buf, sizeof(buf), \"[%F %T] : \", &stime);\n\tbpos = strlen(buf);\n\n\tva_list args;\n\tva_start(args, fmt);\n\tvsnprintf(buf+bpos, sizeof(buf)-bpos, fmt, args);\n\tva_end(args);\n\tbpos = strlen(buf);\n\n\tif(bpos+2 >= sizeof(buf))\n\t\treturn;\n\n\tbuf[bpos] = '\\n';\n\tbuf[bpos+1] = '\\0';\n\n\tstd::unique_lock<std::mutex> lck(print_mutex);\n\tfputs(buf, stdout);\n\n\tif(logfile != nullptr)\n\t{\n\t\tfputs(buf, logfile);\n\t\tfflush(logfile);\n\t}\n}\n\nvoid printer::print_str(const char* str)\n{\n\tstd::unique_lock<std::mutex> lck(print_mutex);\n\tfputs(str, stdout);\n\n\tif(logfile != nullptr)\n\t{\n\t\tfputs(str, logfile);\n\t\tfflush(logfile);\n\t}\n}\n\nextern \"C\" void printer_print_msg(const char* fmt, ...)\n{\n\tchar buf[1024];\n\tsize_t bpos;\n\ttm stime;\n\n\ttime_t now = time(nullptr);\n\tcomp_localtime(&now, &stime);\n\tstrftime(buf, sizeof(buf), \"[%F %T] : \", &stime);\n\tbpos = strlen(buf);\n\n\tva_list args;\n\tva_start(args, fmt);\n\tvsnprintf(buf+bpos, sizeof(buf)-bpos, fmt, args);\n\tva_end(args);\n\tbpos = strlen(buf);\n\n\tif(bpos+2 >= sizeof(buf))\n\t\treturn;\n\n\tbuf[bpos] = '\\n';\n\tbuf[bpos+1] = '\\0';\n\n\tprinter::inst()->print_str(buf);\n}\n\nextern \"C\" void printer_print_str(const char* str)\n{\n\tprinter::inst()->print_str(str);\n}\n"
  },
  {
    "path": "console.h",
    "content": "#pragma once\n#include <mutex>\n\nenum out_colours { K_RED, K_GREEN, K_BLUE, K_YELLOW, K_CYAN, K_MAGENTA, K_WHITE, K_NONE };\n\n// Warning - on Linux get_key will detect control keys, but not on Windows.\n// We will only use it for alphanum keys anyway.\nint get_key();\n\nvoid set_colour(out_colours cl);\nvoid reset_colour();\n\n// on MSVC sizeof(long int) = 4, gcc sizeof(long int) = 8, this is the workaround\n// now we can use %llu on both compilers\ninline long long unsigned int int_port(size_t i)\n{\n\treturn i;\n}\n\nenum verbosity : size_t { L0 = 0, L1 = 1, L2 = 2, L3 = 3, L4 = 4, LINF = 100};\n\nclass printer\n{\npublic:\n\tstatic inline printer* inst()\n\t{\n\t\tif (oInst == nullptr) oInst = new printer;\n\t\treturn oInst;\n\t};\n\n\tinline void set_verbose_level(size_t level) { verbose_level = (verbosity)level; }\n\tvoid print_msg(verbosity verbose, const char* fmt, ...);\n\tvoid print_str(const char* str);\n\tbool open_logfile(const char* file);\n\nprivate:\n\tprinter();\n\tstatic printer* oInst;\n\n\tstd::mutex print_mutex;\n\tverbosity verbose_level;\n\tFILE* logfile;\n};\n"
  },
  {
    "path": "crypto/c_blake256.c",
    "content": "/*\n * The blake256_* and blake224_* functions are largely copied from\n * blake256_light.c and blake224_light.c from the BLAKE website:\n *\n *     http://131002.net/blake/\n *\n * The hmac_* functions implement HMAC-BLAKE-256 and HMAC-BLAKE-224.\n * HMAC is specified by RFC 2104.\n */\n\n#include <string.h>\n#include <stdio.h>\n#include <stdint.h>\n#include \"c_blake256.h\"\n\n#define U8TO32(p) \\\n\t(((uint32_t)((p)[0]) << 24) | ((uint32_t)((p)[1]) << 16) |    \\\n\t ((uint32_t)((p)[2]) <<  8) | ((uint32_t)((p)[3])      ))\n#define U32TO8(p, v) \\\n\t(p)[0] = (uint8_t)((v) >> 24); (p)[1] = (uint8_t)((v) >> 16); \\\n\t(p)[2] = (uint8_t)((v) >>  8); (p)[3] = (uint8_t)((v)      );\n\nconst uint8_t sigma[][16] = {\n\t{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15},\n\t{14,10, 4, 8, 9,15,13, 6, 1,12, 0, 2,11, 7, 5, 3},\n\t{11, 8,12, 0, 5, 2,15,13,10,14, 3, 6, 7, 1, 9, 4},\n\t{ 7, 9, 3, 1,13,12,11,14, 2, 6, 5,10, 4, 0,15, 8},\n\t{ 9, 0, 5, 7, 2, 4,10,15,14, 1,11,12, 6, 8, 3,13},\n\t{ 2,12, 6,10, 0,11, 8, 3, 4,13, 7, 5,15,14, 1, 9},\n\t{12, 5, 1,15,14,13, 4,10, 0, 7, 6, 3, 9, 2, 8,11},\n\t{13,11, 7,14,12, 1, 3, 9, 5, 0,15, 4, 8, 6, 2,10},\n\t{ 6,15,14, 9,11, 3, 0, 8,12, 2,13, 7, 1, 4,10, 5},\n\t{10, 2, 8, 4, 7, 6, 1, 5,15,11, 9,14, 3,12,13, 0},\n\t{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15},\n\t{14,10, 4, 8, 9,15,13, 6, 1,12, 0, 2,11, 7, 5, 3},\n\t{11, 8,12, 0, 5, 2,15,13,10,14, 3, 6, 7, 1, 9, 4},\n\t{ 7, 9, 3, 1,13,12,11,14, 2, 6, 5,10, 4, 0,15, 8}\n};\n\nconst uint32_t cst[16] = {\n\t0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344,\n\t0xA4093822, 0x299F31D0, 0x082EFA98, 0xEC4E6C89,\n\t0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C,\n\t0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917\n};\n\nstatic const uint8_t padding[] = {\n\t0x80,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,\n\t0,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\n};\n\n\nvoid blake256_compress(state *S, const uint8_t *block) {\n\tuint32_t v[16], m[16], i;\n\n#define ROT(x,n) (((x)<<(32-n))|((x)>>(n)))\n#define G(a,b,c,d,e)                                      \\\n\tv[a] += (m[sigma[i][e]] ^ cst[sigma[i][e+1]]) + v[b]; \\\n\tv[d] = ROT(v[d] ^ v[a],16);                           \\\n\tv[c] += v[d];                                         \\\n\tv[b] = ROT(v[b] ^ v[c],12);                           \\\n\tv[a] += (m[sigma[i][e+1]] ^ cst[sigma[i][e]])+v[b];   \\\n\tv[d] = ROT(v[d] ^ v[a], 8);                           \\\n\tv[c] += v[d];                                         \\\n\tv[b] = ROT(v[b] ^ v[c], 7);\n\n\tfor (i = 0; i < 16; ++i) m[i] = U8TO32(block + i * 4);\n\tfor (i = 0; i < 8;  ++i) v[i] = S->h[i];\n\tv[ 8] = S->s[0] ^ 0x243F6A88;\n\tv[ 9] = S->s[1] ^ 0x85A308D3;\n\tv[10] = S->s[2] ^ 0x13198A2E;\n\tv[11] = S->s[3] ^ 0x03707344;\n\tv[12] = 0xA4093822;\n\tv[13] = 0x299F31D0;\n\tv[14] = 0x082EFA98;\n\tv[15] = 0xEC4E6C89;\n\n\tif (S->nullt == 0) {\n\t\tv[12] ^= S->t[0];\n\t\tv[13] ^= S->t[0];\n\t\tv[14] ^= S->t[1];\n\t\tv[15] ^= S->t[1];\n\t}\n\n\tfor (i = 0; i < 14; ++i) {\n\t\tG(0, 4,  8, 12,  0);\n\t\tG(1, 5,  9, 13,  2);\n\t\tG(2, 6, 10, 14,  4);\n\t\tG(3, 7, 11, 15,  6);\n\t\tG(3, 4,  9, 14, 14);\n\t\tG(2, 7,  8, 13, 12);\n\t\tG(0, 5, 10, 15,  8);\n\t\tG(1, 6, 11, 12, 10);\n\t}\n\n\tfor (i = 0; i < 16; ++i) S->h[i % 8] ^= v[i];\n\tfor (i = 0; i < 8;  ++i) S->h[i] ^= S->s[i % 4];\n}\n\nvoid blake256_init(state *S) {\n\tS->h[0] = 0x6A09E667;\n\tS->h[1] = 0xBB67AE85;\n\tS->h[2] = 0x3C6EF372;\n\tS->h[3] = 0xA54FF53A;\n\tS->h[4] = 0x510E527F;\n\tS->h[5] = 0x9B05688C;\n\tS->h[6] = 0x1F83D9AB;\n\tS->h[7] = 0x5BE0CD19;\n\tS->t[0] = S->t[1] = S->buflen = S->nullt = 0;\n\tS->s[0] = S->s[1] = S->s[2] = S->s[3] = 0;\n}\n\nvoid blake224_init(state *S) {\n\tS->h[0] = 0xC1059ED8;\n\tS->h[1] = 0x367CD507;\n\tS->h[2] = 0x3070DD17;\n\tS->h[3] = 0xF70E5939;\n\tS->h[4] = 0xFFC00B31;\n\tS->h[5] = 0x68581511;\n\tS->h[6] = 0x64F98FA7;\n\tS->h[7] = 0xBEFA4FA4;\n\tS->t[0] = S->t[1] = S->buflen = S->nullt = 0;\n\tS->s[0] = S->s[1] = S->s[2] = S->s[3] = 0;\n}\n\n// datalen = number of bits\nvoid blake256_update(state *S, const uint8_t *data, uint64_t datalen) {\n\tint left = S->buflen >> 3;\n\tint fill = 64 - left;\n\n\tif (left && (((datalen >> 3) & 0x3F) >= (unsigned) fill)) {\n\t\tmemcpy((void *) (S->buf + left), (void *) data, fill);\n\t\tS->t[0] += 512;\n\t\tif (S->t[0] == 0) S->t[1]++;\n\t\tblake256_compress(S, S->buf);\n\t\tdata += fill;\n\t\tdatalen -= (fill << 3);\n\t\tleft = 0;\n\t}\n\n\twhile (datalen >= 512) {\n\t\tS->t[0] += 512;\n\t\tif (S->t[0] == 0) S->t[1]++;\n\t\tblake256_compress(S, data);\n\t\tdata += 64;\n\t\tdatalen -= 512;\n\t}\n\n\tif (datalen > 0) {\n\t\tmemcpy((void *) (S->buf + left), (void *) data, datalen >> 3);\n\t\tS->buflen = (left << 3) + datalen;\n\t} else {\n\t\tS->buflen = 0;\n\t}\n}\n\n// datalen = number of bits\nvoid blake224_update(state *S, const uint8_t *data, uint64_t datalen) {\n\tblake256_update(S, data, datalen);\n}\n\nvoid blake256_final_h(state *S, uint8_t *digest, uint8_t pa, uint8_t pb) {\n\tuint8_t msglen[8];\n\tuint32_t lo = S->t[0] + S->buflen, hi = S->t[1];\n\tif (lo < (unsigned) S->buflen) hi++;\n\tU32TO8(msglen + 0, hi);\n\tU32TO8(msglen + 4, lo);\n\n\tif (S->buflen == 440) { /* one padding byte */\n\t\tS->t[0] -= 8;\n\t\tblake256_update(S, &pa, 8);\n\t} else {\n\t\tif (S->buflen < 440) { /* enough space to fill the block  */\n\t\t\tif (S->buflen == 0) S->nullt = 1;\n\t\t\tS->t[0] -= 440 - S->buflen;\n\t\t\tblake256_update(S, padding, 440 - S->buflen);\n\t\t} else { /* need 2 compressions */\n\t\t\tS->t[0] -= 512 - S->buflen;\n\t\t\tblake256_update(S, padding, 512 - S->buflen);\n\t\t\tS->t[0] -= 440;\n\t\t\tblake256_update(S, padding + 1, 440);\n\t\t\tS->nullt = 1;\n\t\t}\n\t\tblake256_update(S, &pb, 8);\n\t\tS->t[0] -= 8;\n\t}\n\tS->t[0] -= 64;\n\tblake256_update(S, msglen, 64);\n\n\tU32TO8(digest +  0, S->h[0]);\n\tU32TO8(digest +  4, S->h[1]);\n\tU32TO8(digest +  8, S->h[2]);\n\tU32TO8(digest + 12, S->h[3]);\n\tU32TO8(digest + 16, S->h[4]);\n\tU32TO8(digest + 20, S->h[5]);\n\tU32TO8(digest + 24, S->h[6]);\n\tU32TO8(digest + 28, S->h[7]);\n}\n\nvoid blake256_final(state *S, uint8_t *digest) {\n\tblake256_final_h(S, digest, 0x81, 0x01);\n}\n\nvoid blake224_final(state *S, uint8_t *digest) {\n\tblake256_final_h(S, digest, 0x80, 0x00);\n}\n\n// inlen = number of bytes\nvoid blake256_hash(uint8_t *out, const uint8_t *in, uint64_t inlen) {\n\tstate S;\n\tblake256_init(&S);\n\tblake256_update(&S, in, inlen * 8);\n\tblake256_final(&S, out);\n}\n\n// inlen = number of bytes\nvoid blake224_hash(uint8_t *out, const uint8_t *in, uint64_t inlen) {\n\tstate S;\n\tblake224_init(&S);\n\tblake224_update(&S, in, inlen * 8);\n\tblake224_final(&S, out);\n}\n\n// keylen = number of bytes\nvoid hmac_blake256_init(hmac_state *S, const uint8_t *_key, uint64_t keylen) {\n\tconst uint8_t *key = _key;\n\tuint8_t keyhash[32];\n\tuint8_t pad[64];\n\tuint64_t i;\n\n\tif (keylen > 64) {\n\t\tblake256_hash(keyhash, key, keylen);\n\t\tkey = keyhash;\n\t\tkeylen = 32;\n\t}\n\n\tblake256_init(&S->inner);\n\tmemset(pad, 0x36, 64);\n\tfor (i = 0; i < keylen; ++i) {\n\t\tpad[i] ^= key[i];\n\t}\n\tblake256_update(&S->inner, pad, 512);\n\n\tblake256_init(&S->outer);\n\tmemset(pad, 0x5c, 64);\n\tfor (i = 0; i < keylen; ++i) {\n\t\tpad[i] ^= key[i];\n\t}\n\tblake256_update(&S->outer, pad, 512);\n\n\tmemset(keyhash, 0, 32);\n}\n\n// keylen = number of bytes\nvoid hmac_blake224_init(hmac_state *S, const uint8_t *_key, uint64_t keylen) {\n\tconst uint8_t *key = _key;\n\tuint8_t keyhash[32];\n\tuint8_t pad[64];\n\tuint64_t i;\n\n\tif (keylen > 64) {\n\t\tblake256_hash(keyhash, key, keylen);\n\t\tkey = keyhash;\n\t\tkeylen = 28;\n\t}\n\n\tblake224_init(&S->inner);\n\tmemset(pad, 0x36, 64);\n\tfor (i = 0; i < keylen; ++i) {\n\t\tpad[i] ^= key[i];\n\t}\n\tblake224_update(&S->inner, pad, 512);\n\n\tblake224_init(&S->outer);\n\tmemset(pad, 0x5c, 64);\n\tfor (i = 0; i < keylen; ++i) {\n\t\tpad[i] ^= key[i];\n\t}\n\tblake224_update(&S->outer, pad, 512);\n\n\tmemset(keyhash, 0, 32);\n}\n\n// datalen = number of bits\nvoid hmac_blake256_update(hmac_state *S, const uint8_t *data, uint64_t datalen) {\n  // update the inner state\n  blake256_update(&S->inner, data, datalen);\n}\n\n// datalen = number of bits\nvoid hmac_blake224_update(hmac_state *S, const uint8_t *data, uint64_t datalen) {\n  // update the inner state\n  blake224_update(&S->inner, data, datalen);\n}\n\nvoid hmac_blake256_final(hmac_state *S, uint8_t *digest) {\n\tuint8_t ihash[32];\n\tblake256_final(&S->inner, ihash);\n\tblake256_update(&S->outer, ihash, 256);\n\tblake256_final(&S->outer, digest);\n\tmemset(ihash, 0, 32);\n}\n\nvoid hmac_blake224_final(hmac_state *S, uint8_t *digest) {\n\tuint8_t ihash[32];\n\tblake224_final(&S->inner, ihash);\n\tblake224_update(&S->outer, ihash, 224);\n\tblake224_final(&S->outer, digest);\n\tmemset(ihash, 0, 32);\n}\n\n// keylen = number of bytes; inlen = number of bytes\nvoid hmac_blake256_hash(uint8_t *out, const uint8_t *key, uint64_t keylen, const uint8_t *in, uint64_t inlen) {\n\thmac_state S;\n\thmac_blake256_init(&S, key, keylen);\n\thmac_blake256_update(&S, in, inlen * 8);\n\thmac_blake256_final(&S, out);\n}\n\n// keylen = number of bytes; inlen = number of bytes\nvoid hmac_blake224_hash(uint8_t *out, const uint8_t *key, uint64_t keylen, const uint8_t *in, uint64_t inlen) {\n\thmac_state S;\n\thmac_blake224_init(&S, key, keylen);\n\thmac_blake224_update(&S, in, inlen * 8);\n\thmac_blake224_final(&S, out);\n}\n"
  },
  {
    "path": "crypto/c_blake256.h",
    "content": "#ifndef _BLAKE256_H_\n#define _BLAKE256_H_\n\n#include <stdint.h>\n\ntypedef struct {\n  uint32_t h[8], s[4], t[2];\n  int buflen, nullt;\n  uint8_t buf[64];\n} state;\n\ntypedef struct {\n  state inner;\n  state outer;\n} hmac_state;\n\nvoid blake256_init(state *);\nvoid blake224_init(state *);\n\nvoid blake256_update(state *, const uint8_t *, uint64_t);\nvoid blake224_update(state *, const uint8_t *, uint64_t);\n\nvoid blake256_final(state *, uint8_t *);\nvoid blake224_final(state *, uint8_t *);\n\nvoid blake256_hash(uint8_t *, const uint8_t *, uint64_t);\nvoid blake224_hash(uint8_t *, const uint8_t *, uint64_t);\n\n/* HMAC functions: */\n\nvoid hmac_blake256_init(hmac_state *, const uint8_t *, uint64_t);\nvoid hmac_blake224_init(hmac_state *, const uint8_t *, uint64_t);\n\nvoid hmac_blake256_update(hmac_state *, const uint8_t *, uint64_t);\nvoid hmac_blake224_update(hmac_state *, const uint8_t *, uint64_t);\n\nvoid hmac_blake256_final(hmac_state *, uint8_t *);\nvoid hmac_blake224_final(hmac_state *, uint8_t *);\n\nvoid hmac_blake256_hash(uint8_t *, const uint8_t *, uint64_t, const uint8_t *, uint64_t);\nvoid hmac_blake224_hash(uint8_t *, const uint8_t *, uint64_t, const uint8_t *, uint64_t);\n\n#endif /* _BLAKE256_H_ */\n"
  },
  {
    "path": "crypto/c_groestl.c",
    "content": "/* hash.c     April 2012\n * Groestl ANSI C code optimised for 32-bit machines\n * Author: Thomas Krinninger\n *\n *  This work is based on the implementation of\n *          Soeren S. Thomsen and Krystian Matusiewicz\n *          \n *\n */\n\n#include \"c_groestl.h\"\n#include \"groestl_tables.h\"\n\n#define P_TYPE 0\n#define Q_TYPE 1\n\nconst uint8_t shift_Values[2][8] = {{0,1,2,3,4,5,6,7},{1,3,5,7,0,2,4,6}};\n\nconst uint8_t indices_cyclic[15] = {0,1,2,3,4,5,6,7,0,1,2,3,4,5,6};\n\n\n#define ROTATE_COLUMN_DOWN(v1, v2, amount_bytes, temp_var) {temp_var = (v1<<(8*amount_bytes))|(v2>>(8*(4-amount_bytes))); \\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tv2 = (v2<<(8*amount_bytes))|(v1>>(8*(4-amount_bytes))); \\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tv1 = temp_var;}\n  \n\n#define COLUMN(x,y,i,c0,c1,c2,c3,c4,c5,c6,c7,tv1,tv2,tu,tl,t)\t\t\t\t\\\n   tu = T[2*(uint32_t)x[4*c0+0]];\t\t\t    \\\n   tl = T[2*(uint32_t)x[4*c0+0]+1];\t\t    \\\n   tv1 = T[2*(uint32_t)x[4*c1+1]];\t\t\t\\\n   tv2 = T[2*(uint32_t)x[4*c1+1]+1];\t\t\t\\\n   ROTATE_COLUMN_DOWN(tv1,tv2,1,t)\t\\\n   tu ^= tv1;\t\t\t\t\t\t\\\n   tl ^= tv2;\t\t\t\t\t\t\\\n   tv1 = T[2*(uint32_t)x[4*c2+2]];\t\t\t\\\n   tv2 = T[2*(uint32_t)x[4*c2+2]+1];\t\t\t\\\n   ROTATE_COLUMN_DOWN(tv1,tv2,2,t)\t\\\n   tu ^= tv1;\t\t\t\t\t\t\\\n   tl ^= tv2;   \t\t\t\t\t\\\n   tv1 = T[2*(uint32_t)x[4*c3+3]];\t\t\t\\\n   tv2 = T[2*(uint32_t)x[4*c3+3]+1];\t\t\t\\\n   ROTATE_COLUMN_DOWN(tv1,tv2,3,t)\t\\\n   tu ^= tv1;\t\t\t\t\t\t\\\n   tl ^= tv2;\t\t\t\t\t\t\\\n   tl ^= T[2*(uint32_t)x[4*c4+0]];\t\t\t\\\n   tu ^= T[2*(uint32_t)x[4*c4+0]+1];\t\t\t\\\n   tv1 = T[2*(uint32_t)x[4*c5+1]];\t\t\t\\\n   tv2 = T[2*(uint32_t)x[4*c5+1]+1];\t\t\t\\\n   ROTATE_COLUMN_DOWN(tv1,tv2,1,t)\t\\\n   tl ^= tv1;\t\t\t\t\t\t\\\n   tu ^= tv2;\t\t\t\t\t\t\\\n   tv1 = T[2*(uint32_t)x[4*c6+2]];\t\t\t\\\n   tv2 = T[2*(uint32_t)x[4*c6+2]+1];\t\t\t\\\n   ROTATE_COLUMN_DOWN(tv1,tv2,2,t)\t\\\n   tl ^= tv1;\t\t\t\t\t\t\\\n   tu ^= tv2;   \t\t\t\t\t\\\n   tv1 = T[2*(uint32_t)x[4*c7+3]];\t\t\t\\\n   tv2 = T[2*(uint32_t)x[4*c7+3]+1];\t\t\t\\\n   ROTATE_COLUMN_DOWN(tv1,tv2,3,t)\t\\\n   tl ^= tv1;\t\t\t\t\t\t\\\n   tu ^= tv2;\t\t\t\t\t\t\\\n   y[i] = tu;\t\t\t\t\t\t\\\n   y[i+1] = tl;\n\n\n/* compute one round of P (short variants) */\nstatic void RND512P(uint8_t *x, uint32_t *y, uint32_t r) {\n  uint32_t temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp;\n  uint32_t* x32 = (uint32_t*)x;\n  x32[ 0] ^= 0x00000000^r;\n  x32[ 2] ^= 0x00000010^r;\n  x32[ 4] ^= 0x00000020^r;\n  x32[ 6] ^= 0x00000030^r;\n  x32[ 8] ^= 0x00000040^r;\n  x32[10] ^= 0x00000050^r;\n  x32[12] ^= 0x00000060^r;\n  x32[14] ^= 0x00000070^r;\n  COLUMN(x,y, 0,  0,  2,  4,  6,  9, 11, 13, 15, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);\n  COLUMN(x,y, 2,  2,  4,  6,  8, 11, 13, 15,  1, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);\n  COLUMN(x,y, 4,  4,  6,  8, 10, 13, 15,  1,  3, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);\n  COLUMN(x,y, 6,  6,  8, 10, 12, 15,  1,  3,  5, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);\n  COLUMN(x,y, 8,  8, 10, 12, 14,  1,  3,  5,  7, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);\n  COLUMN(x,y,10, 10, 12, 14,  0,  3,  5,  7,  9, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);\n  COLUMN(x,y,12, 12, 14,  0,  2,  5,  7,  9, 11, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);\n  COLUMN(x,y,14, 14,  0,  2,  4,  7,  9, 11, 13, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);\n}\n\n/* compute one round of Q (short variants) */\nstatic void RND512Q(uint8_t *x, uint32_t *y, uint32_t r) {\n  uint32_t temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp;\n  uint32_t* x32 = (uint32_t*)x;\n  x32[ 0] = ~x32[ 0];\n  x32[ 1] ^= 0xffffffff^r;\n  x32[ 2] = ~x32[ 2];\n  x32[ 3] ^= 0xefffffff^r;\n  x32[ 4] = ~x32[ 4];\n  x32[ 5] ^= 0xdfffffff^r;\n  x32[ 6] = ~x32[ 6];\n  x32[ 7] ^= 0xcfffffff^r;\n  x32[ 8] = ~x32[ 8];\n  x32[ 9] ^= 0xbfffffff^r;\n  x32[10] = ~x32[10];\n  x32[11] ^= 0xafffffff^r;\n  x32[12] = ~x32[12];\n  x32[13] ^= 0x9fffffff^r;\n  x32[14] = ~x32[14];\n  x32[15] ^= 0x8fffffff^r;\n  COLUMN(x,y, 0,  2,  6, 10, 14,  1,  5,  9, 13, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);\n  COLUMN(x,y, 2,  4,  8, 12,  0,  3,  7, 11, 15, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);\n  COLUMN(x,y, 4,  6, 10, 14,  2,  5,  9, 13,  1, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);\n  COLUMN(x,y, 6,  8, 12,  0,  4,  7, 11, 15,  3, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);\n  COLUMN(x,y, 8, 10, 14,  2,  6,  9, 13,  1,  5, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);\n  COLUMN(x,y,10, 12,  0,  4,  8, 11, 15,  3,  7, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);\n  COLUMN(x,y,12, 14,  2,  6, 10, 13,  1,  5,  9, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);\n  COLUMN(x,y,14,  0,  4,  8, 12, 15,  3,  7, 11, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);\n}\n\n/* compute compression function (short variants) */\nstatic void F512(uint32_t *h, const uint32_t *m) {\n  int i;\n  uint32_t Ptmp[2*COLS512];\n  uint32_t Qtmp[2*COLS512];\n  uint32_t y[2*COLS512];\n  uint32_t z[2*COLS512];\n\n  for (i = 0; i < 2*COLS512; i++) {\n\tz[i] = m[i];\n\tPtmp[i] = h[i]^m[i];\n  }\n\n  /* compute Q(m) */\n  RND512Q((uint8_t*)z, y, 0x00000000);\n  RND512Q((uint8_t*)y, z, 0x01000000);\n  RND512Q((uint8_t*)z, y, 0x02000000);\n  RND512Q((uint8_t*)y, z, 0x03000000);\n  RND512Q((uint8_t*)z, y, 0x04000000);\n  RND512Q((uint8_t*)y, z, 0x05000000);\n  RND512Q((uint8_t*)z, y, 0x06000000);\n  RND512Q((uint8_t*)y, z, 0x07000000);\n  RND512Q((uint8_t*)z, y, 0x08000000);\n  RND512Q((uint8_t*)y, Qtmp, 0x09000000);\n\n  /* compute P(h+m) */\n  RND512P((uint8_t*)Ptmp, y, 0x00000000);\n  RND512P((uint8_t*)y, z, 0x00000001);\n  RND512P((uint8_t*)z, y, 0x00000002);\n  RND512P((uint8_t*)y, z, 0x00000003);\n  RND512P((uint8_t*)z, y, 0x00000004);\n  RND512P((uint8_t*)y, z, 0x00000005);\n  RND512P((uint8_t*)z, y, 0x00000006);\n  RND512P((uint8_t*)y, z, 0x00000007);\n  RND512P((uint8_t*)z, y, 0x00000008);\n  RND512P((uint8_t*)y, Ptmp, 0x00000009);\n\n  /* compute P(h+m) + Q(m) + h */\n  for (i = 0; i < 2*COLS512; i++) {\n\th[i] ^= Ptmp[i]^Qtmp[i];\n  }\n}\n\n\n/* digest up to msglen bytes of input (full blocks only) */\nstatic void Transform(groestlHashState *ctx,\n\t       const uint8_t *input, \n\t       int msglen) {\n\n  /* digest message, one block at a time */\n  for (; msglen >= SIZE512; \n\t   msglen -= SIZE512, input += SIZE512) {\n\tF512(ctx->chaining,(uint32_t*)input);\n\n\t/* increment block counter */\n\tctx->block_counter1++;\n\tif (ctx->block_counter1 == 0) ctx->block_counter2++;\n  }\n}\n\n/* given state h, do h <- P(h)+h */\nstatic void OutputTransformation(groestlHashState *ctx) {\n  int j;\n  uint32_t temp[2*COLS512];\n  uint32_t y[2*COLS512];\n  uint32_t z[2*COLS512];\n\n\n\n\tfor (j = 0; j < 2*COLS512; j++) {\n\t  temp[j] = ctx->chaining[j];\n\t}\n\tRND512P((uint8_t*)temp, y, 0x00000000);\n\tRND512P((uint8_t*)y, z, 0x00000001);\n\tRND512P((uint8_t*)z, y, 0x00000002);\n\tRND512P((uint8_t*)y, z, 0x00000003);\n\tRND512P((uint8_t*)z, y, 0x00000004);\n\tRND512P((uint8_t*)y, z, 0x00000005);\n\tRND512P((uint8_t*)z, y, 0x00000006);\n\tRND512P((uint8_t*)y, z, 0x00000007);\n\tRND512P((uint8_t*)z, y, 0x00000008);\n\tRND512P((uint8_t*)y, temp, 0x00000009);\n\tfor (j = 0; j < 2*COLS512; j++) {\n\t  ctx->chaining[j] ^= temp[j];\n\t}\t\t\t\t\t\t\t\t\t  \n}\n\n/* initialise context */\nstatic void Init(groestlHashState* ctx) {\n  int i = 0;\n  /* allocate memory for state and data buffer */\n\n  for(;i<(SIZE512/sizeof(uint32_t));i++)\n  {\n\tctx->chaining[i] = 0;\n  }\n\n  /* set initial value */\n  ctx->chaining[2*COLS512-1] = u32BIG((uint32_t)HASH_BIT_LEN);\n\n  /* set other variables */\n  ctx->buf_ptr = 0;\n  ctx->block_counter1 = 0;\n  ctx->block_counter2 = 0;\n  ctx->bits_in_last_byte = 0;\n}\n\n/* update state with databitlen bits of input */\nstatic void Update(groestlHashState* ctx,\n\t\t  const BitSequence* input,\n\t\t  DataLength databitlen) {\n  int index = 0;\n  int msglen = (int)(databitlen/8);\n  int rem = (int)(databitlen%8);\n\n  /* if the buffer contains data that has not yet been digested, first\n\t add data to buffer until full */\n  if (ctx->buf_ptr) {\n\twhile (ctx->buf_ptr < SIZE512 && index < msglen) {\n\t  ctx->buffer[(int)ctx->buf_ptr++] = input[index++];\n\t}\n\tif (ctx->buf_ptr < SIZE512) {\n\t  /* buffer still not full, return */\n\t  if (rem) {\n\tctx->bits_in_last_byte = rem;\n\tctx->buffer[(int)ctx->buf_ptr++] = input[index];\n\t  }\n\t  return;\n\t}\n\n\t/* digest buffer */\n\tctx->buf_ptr = 0;\n\tTransform(ctx, ctx->buffer, SIZE512);\n  }\n\n  /* digest bulk of message */\n  Transform(ctx, input+index, msglen-index);\n  index += ((msglen-index)/SIZE512)*SIZE512;\n\n  /* store remaining data in buffer */\n  while (index < msglen) {\n\tctx->buffer[(int)ctx->buf_ptr++] = input[index++];\n  }\n\n  /* if non-integral number of bytes have been supplied, store\n\t remaining bits in last byte, together with information about\n\t number of bits */\n  if (rem) {\n\tctx->bits_in_last_byte = rem;\n\tctx->buffer[(int)ctx->buf_ptr++] = input[index];\n  }\n}\n\n#define BILB ctx->bits_in_last_byte\n\n/* finalise: process remaining data (including padding), perform\n   output transformation, and write hash result to 'output' */\nstatic void Final(groestlHashState* ctx,\n\t\t BitSequence* output) {\n  int i, j = 0, hashbytelen = HASH_BIT_LEN/8;\n  uint8_t *s = (BitSequence*)ctx->chaining;\n\n  /* pad with '1'-bit and first few '0'-bits */\n  if (BILB) {\n\tctx->buffer[(int)ctx->buf_ptr-1] &= ((1<<BILB)-1)<<(8-BILB);\n\tctx->buffer[(int)ctx->buf_ptr-1] ^= 0x1<<(7-BILB);\n\tBILB = 0;\n  }\n  else ctx->buffer[(int)ctx->buf_ptr++] = 0x80;\n\n  /* pad with '0'-bits */\n  if (ctx->buf_ptr > SIZE512-LENGTHFIELDLEN) {\n\t/* padding requires two blocks */\n\twhile (ctx->buf_ptr < SIZE512) {\n\t  ctx->buffer[(int)ctx->buf_ptr++] = 0;\n\t}\n\t/* digest first padding block */\n\tTransform(ctx, ctx->buffer, SIZE512);\n\tctx->buf_ptr = 0;\n  }\n  while (ctx->buf_ptr < SIZE512-LENGTHFIELDLEN) {\n\tctx->buffer[(int)ctx->buf_ptr++] = 0;\n  }\n\n  /* length padding */\n  ctx->block_counter1++;\n  if (ctx->block_counter1 == 0) ctx->block_counter2++;\n  ctx->buf_ptr = SIZE512;\n\n  while (ctx->buf_ptr > SIZE512-(int)sizeof(uint32_t)) {\n\tctx->buffer[(int)--ctx->buf_ptr] = (uint8_t)ctx->block_counter1;\n\tctx->block_counter1 >>= 8;\n  }\n  while (ctx->buf_ptr > SIZE512-LENGTHFIELDLEN) {\n\tctx->buffer[(int)--ctx->buf_ptr] = (uint8_t)ctx->block_counter2;\n\tctx->block_counter2 >>= 8;\n  }\n  /* digest final padding block */\n  Transform(ctx, ctx->buffer, SIZE512); \n  /* perform output transformation */\n  OutputTransformation(ctx);\n\n  /* store hash result in output */\n  for (i = SIZE512-hashbytelen; i < SIZE512; i++,j++) {\n\toutput[j] = s[i];\n  }\n\n  /* zeroise relevant variables and deallocate memory */\n  for (i = 0; i < COLS512; i++) {\n\tctx->chaining[i] = 0;\n  }\n  for (i = 0; i < SIZE512; i++) {\n\tctx->buffer[i] = 0;\n  }\n}\n\n/* hash bit sequence */\nvoid groestl(const BitSequence* data, \n\t\tDataLength databitlen,\n\t\tBitSequence* hashval) {\n\n  groestlHashState context;\n\n  /* initialise */\n\tInit(&context);\n\n\n  /* process message */\n  Update(&context, data, databitlen);\n\n  /* finalise */\n  Final(&context, hashval);\n}\n/*\nstatic int crypto_hash(unsigned char *out,\n\t\tconst unsigned char *in,\n\t\tunsigned long long len)\n{\n  groestl(in, 8*len, out);\n  return 0;\n}\n\n*/\n"
  },
  {
    "path": "crypto/c_groestl.h",
    "content": "#ifndef __hash_h\n#define __hash_h\n/*\n#include \"crypto_uint8.h\"\n#include \"crypto_uint32.h\"\n#include \"crypto_uint64.h\"\n#include \"crypto_hash.h\" \n\ntypedef crypto_uint8 uint8_t; \ntypedef crypto_uint32 uint32_t; \ntypedef crypto_uint64 uint64_t;\n*/\n#include <stdint.h>\n\n#include \"hash.h\"\n\n/* some sizes (number of bytes) */\n#define ROWS 8\n#define LENGTHFIELDLEN ROWS\n#define COLS512 8\n\n#define SIZE512 (ROWS*COLS512)\n\n#define ROUNDS512 10\n#define HASH_BIT_LEN 256\n\n#define ROTL32(v, n) ((((v)<<(n))|((v)>>(32-(n))))&li_32(ffffffff))\n\n\n#define li_32(h) 0x##h##u\n#define EXT_BYTE(var,n) ((uint8_t)((uint32_t)(var) >> (8*n)))\n#define u32BIG(a)\t\t\t\t\\\n  ((ROTL32(a,8) & li_32(00FF00FF)) |\t\t\\\n   (ROTL32(a,24) & li_32(FF00FF00)))\n\n\n/* NIST API begin */\ntypedef struct {\n  uint32_t chaining[SIZE512/sizeof(uint32_t)];            /* actual state */\n  uint32_t block_counter1,\n  block_counter2;         /* message block counter(s) */\n  BitSequence buffer[SIZE512];      /* data buffer */\n  int buf_ptr;              /* data buffer pointer */\n  int bits_in_last_byte;    /* no. of message bits in last byte of\n\t\t\t       data buffer */\n} groestlHashState;\n\n/*void Init(hashState*);\nvoid Update(hashState*, const BitSequence*, DataLength);\nvoid Final(hashState*, BitSequence*); */\nvoid groestl(const BitSequence*, DataLength, BitSequence*);\n/* NIST API end   */\n\n/*\nint crypto_hash(unsigned char *out,\n\t\tconst unsigned char *in,\n\t\tunsigned long long len);\n*/\n\n#endif /* __hash_h */\n"
  },
  {
    "path": "crypto/c_jh.c",
    "content": "/*This program gives the 64-bit optimized bitslice implementation of JH using ANSI C\n\n   --------------------------------\n   Performance\n\n   Microprocessor: Intel CORE 2 processor (Core 2 Duo Mobile T6600 2.2GHz)\n   Operating System: 64-bit Ubuntu 10.04 (Linux kernel 2.6.32-22-generic)\n   Speed for long message:\n   1) 45.8 cycles/byte   compiler: Intel C++ Compiler 11.1   compilation option: icc -O2\n   2) 56.8 cycles/byte   compiler: gcc 4.4.3                 compilation option: gcc -O3\n\n   --------------------------------\n   Last Modified: January 16, 2011\n*/\n\n#include \"c_jh.h\"\n\n#include <stdint.h>\n#include <string.h>\n\n/*typedef unsigned long long uint64;*/\ntypedef uint64_t uint64;\n\n/*define data alignment for different C compilers*/\n#if defined(__GNUC__)\n\t  #define DATA_ALIGN16(x) x __attribute__ ((aligned(16)))\n#else\n\t  #define DATA_ALIGN16(x) __declspec(align(16)) x\n#endif\n\n\ntypedef struct {\n\tint hashbitlen;\t   \t              /*the message digest size*/\n\tunsigned long long databitlen;    /*the message size in bits*/\n\tunsigned long long datasize_in_buffer;      /*the size of the message remained in buffer; assumed to be multiple of 8bits except for the last partial block at the end of the message*/\n\tDATA_ALIGN16(uint64 x[8][2]);     /*the 1024-bit state, ( x[i][0] || x[i][1] ) is the ith row of the state in the pseudocode*/\n\tunsigned char buffer[64];         /*the 512-bit message block to be hashed;*/\n} hashState;\n\n\n/*The initial hash value H(0)*/\nconst unsigned char JH224_H0[128]={0x2d,0xfe,0xdd,0x62,0xf9,0x9a,0x98,0xac,0xae,0x7c,0xac,0xd6,0x19,0xd6,0x34,0xe7,0xa4,0x83,0x10,0x5,0xbc,0x30,0x12,0x16,0xb8,0x60,0x38,0xc6,0xc9,0x66,0x14,0x94,0x66,0xd9,0x89,0x9f,0x25,0x80,0x70,0x6f,0xce,0x9e,0xa3,0x1b,0x1d,0x9b,0x1a,0xdc,0x11,0xe8,0x32,0x5f,0x7b,0x36,0x6e,0x10,0xf9,0x94,0x85,0x7f,0x2,0xfa,0x6,0xc1,0x1b,0x4f,0x1b,0x5c,0xd8,0xc8,0x40,0xb3,0x97,0xf6,0xa1,0x7f,0x6e,0x73,0x80,0x99,0xdc,0xdf,0x93,0xa5,0xad,0xea,0xa3,0xd3,0xa4,0x31,0xe8,0xde,0xc9,0x53,0x9a,0x68,0x22,0xb4,0xa9,0x8a,0xec,0x86,0xa1,0xe4,0xd5,0x74,0xac,0x95,0x9c,0xe5,0x6c,0xf0,0x15,0x96,0xd,0xea,0xb5,0xab,0x2b,0xbf,0x96,0x11,0xdc,0xf0,0xdd,0x64,0xea,0x6e};\nconst unsigned char JH256_H0[128]={0xeb,0x98,0xa3,0x41,0x2c,0x20,0xd3,0xeb,0x92,0xcd,0xbe,0x7b,0x9c,0xb2,0x45,0xc1,0x1c,0x93,0x51,0x91,0x60,0xd4,0xc7,0xfa,0x26,0x0,0x82,0xd6,0x7e,0x50,0x8a,0x3,0xa4,0x23,0x9e,0x26,0x77,0x26,0xb9,0x45,0xe0,0xfb,0x1a,0x48,0xd4,0x1a,0x94,0x77,0xcd,0xb5,0xab,0x26,0x2,0x6b,0x17,0x7a,0x56,0xf0,0x24,0x42,0xf,0xff,0x2f,0xa8,0x71,0xa3,0x96,0x89,0x7f,0x2e,0x4d,0x75,0x1d,0x14,0x49,0x8,0xf7,0x7d,0xe2,0x62,0x27,0x76,0x95,0xf7,0x76,0x24,0x8f,0x94,0x87,0xd5,0xb6,0x57,0x47,0x80,0x29,0x6c,0x5c,0x5e,0x27,0x2d,0xac,0x8e,0xd,0x6c,0x51,0x84,0x50,0xc6,0x57,0x5,0x7a,0xf,0x7b,0xe4,0xd3,0x67,0x70,0x24,0x12,0xea,0x89,0xe3,0xab,0x13,0xd3,0x1c,0xd7,0x69};\nconst unsigned char JH384_H0[128]={0x48,0x1e,0x3b,0xc6,0xd8,0x13,0x39,0x8a,0x6d,0x3b,0x5e,0x89,0x4a,0xde,0x87,0x9b,0x63,0xfa,0xea,0x68,0xd4,0x80,0xad,0x2e,0x33,0x2c,0xcb,0x21,0x48,0xf,0x82,0x67,0x98,0xae,0xc8,0x4d,0x90,0x82,0xb9,0x28,0xd4,0x55,0xea,0x30,0x41,0x11,0x42,0x49,0x36,0xf5,0x55,0xb2,0x92,0x48,0x47,0xec,0xc7,0x25,0xa,0x93,0xba,0xf4,0x3c,0xe1,0x56,0x9b,0x7f,0x8a,0x27,0xdb,0x45,0x4c,0x9e,0xfc,0xbd,0x49,0x63,0x97,0xaf,0xe,0x58,0x9f,0xc2,0x7d,0x26,0xaa,0x80,0xcd,0x80,0xc0,0x8b,0x8c,0x9d,0xeb,0x2e,0xda,0x8a,0x79,0x81,0xe8,0xf8,0xd5,0x37,0x3a,0xf4,0x39,0x67,0xad,0xdd,0xd1,0x7a,0x71,0xa9,0xb4,0xd3,0xbd,0xa4,0x75,0xd3,0x94,0x97,0x6c,0x3f,0xba,0x98,0x42,0x73,0x7f};\nconst unsigned char JH512_H0[128]={0x6f,0xd1,0x4b,0x96,0x3e,0x0,0xaa,0x17,0x63,0x6a,0x2e,0x5,0x7a,0x15,0xd5,0x43,0x8a,0x22,0x5e,0x8d,0xc,0x97,0xef,0xb,0xe9,0x34,0x12,0x59,0xf2,0xb3,0xc3,0x61,0x89,0x1d,0xa0,0xc1,0x53,0x6f,0x80,0x1e,0x2a,0xa9,0x5,0x6b,0xea,0x2b,0x6d,0x80,0x58,0x8e,0xcc,0xdb,0x20,0x75,0xba,0xa6,0xa9,0xf,0x3a,0x76,0xba,0xf8,0x3b,0xf7,0x1,0x69,0xe6,0x5,0x41,0xe3,0x4a,0x69,0x46,0xb5,0x8a,0x8e,0x2e,0x6f,0xe6,0x5a,0x10,0x47,0xa7,0xd0,0xc1,0x84,0x3c,0x24,0x3b,0x6e,0x71,0xb1,0x2d,0x5a,0xc1,0x99,0xcf,0x57,0xf6,0xec,0x9d,0xb1,0xf8,0x56,0xa7,0x6,0x88,0x7c,0x57,0x16,0xb1,0x56,0xe3,0xc2,0xfc,0xdf,0xe6,0x85,0x17,0xfb,0x54,0x5a,0x46,0x78,0xcc,0x8c,0xdd,0x4b};\n\n/*42 round constants, each round constant is 32-byte (256-bit)*/\nconst unsigned char E8_bitslice_roundconstant[42][32]={\n{0x72,0xd5,0xde,0xa2,0xdf,0x15,0xf8,0x67,0x7b,0x84,0x15,0xa,0xb7,0x23,0x15,0x57,0x81,0xab,0xd6,0x90,0x4d,0x5a,0x87,0xf6,0x4e,0x9f,0x4f,0xc5,0xc3,0xd1,0x2b,0x40},\n{0xea,0x98,0x3a,0xe0,0x5c,0x45,0xfa,0x9c,0x3,0xc5,0xd2,0x99,0x66,0xb2,0x99,0x9a,0x66,0x2,0x96,0xb4,0xf2,0xbb,0x53,0x8a,0xb5,0x56,0x14,0x1a,0x88,0xdb,0xa2,0x31},\n{0x3,0xa3,0x5a,0x5c,0x9a,0x19,0xe,0xdb,0x40,0x3f,0xb2,0xa,0x87,0xc1,0x44,0x10,0x1c,0x5,0x19,0x80,0x84,0x9e,0x95,0x1d,0x6f,0x33,0xeb,0xad,0x5e,0xe7,0xcd,0xdc},\n{0x10,0xba,0x13,0x92,0x2,0xbf,0x6b,0x41,0xdc,0x78,0x65,0x15,0xf7,0xbb,0x27,0xd0,0xa,0x2c,0x81,0x39,0x37,0xaa,0x78,0x50,0x3f,0x1a,0xbf,0xd2,0x41,0x0,0x91,0xd3},\n{0x42,0x2d,0x5a,0xd,0xf6,0xcc,0x7e,0x90,0xdd,0x62,0x9f,0x9c,0x92,0xc0,0x97,0xce,0x18,0x5c,0xa7,0xb,0xc7,0x2b,0x44,0xac,0xd1,0xdf,0x65,0xd6,0x63,0xc6,0xfc,0x23},\n{0x97,0x6e,0x6c,0x3,0x9e,0xe0,0xb8,0x1a,0x21,0x5,0x45,0x7e,0x44,0x6c,0xec,0xa8,0xee,0xf1,0x3,0xbb,0x5d,0x8e,0x61,0xfa,0xfd,0x96,0x97,0xb2,0x94,0x83,0x81,0x97},\n{0x4a,0x8e,0x85,0x37,0xdb,0x3,0x30,0x2f,0x2a,0x67,0x8d,0x2d,0xfb,0x9f,0x6a,0x95,0x8a,0xfe,0x73,0x81,0xf8,0xb8,0x69,0x6c,0x8a,0xc7,0x72,0x46,0xc0,0x7f,0x42,0x14},\n{0xc5,0xf4,0x15,0x8f,0xbd,0xc7,0x5e,0xc4,0x75,0x44,0x6f,0xa7,0x8f,0x11,0xbb,0x80,0x52,0xde,0x75,0xb7,0xae,0xe4,0x88,0xbc,0x82,0xb8,0x0,0x1e,0x98,0xa6,0xa3,0xf4},\n{0x8e,0xf4,0x8f,0x33,0xa9,0xa3,0x63,0x15,0xaa,0x5f,0x56,0x24,0xd5,0xb7,0xf9,0x89,0xb6,0xf1,0xed,0x20,0x7c,0x5a,0xe0,0xfd,0x36,0xca,0xe9,0x5a,0x6,0x42,0x2c,0x36},\n{0xce,0x29,0x35,0x43,0x4e,0xfe,0x98,0x3d,0x53,0x3a,0xf9,0x74,0x73,0x9a,0x4b,0xa7,0xd0,0xf5,0x1f,0x59,0x6f,0x4e,0x81,0x86,0xe,0x9d,0xad,0x81,0xaf,0xd8,0x5a,0x9f},\n{0xa7,0x5,0x6,0x67,0xee,0x34,0x62,0x6a,0x8b,0xb,0x28,0xbe,0x6e,0xb9,0x17,0x27,0x47,0x74,0x7,0x26,0xc6,0x80,0x10,0x3f,0xe0,0xa0,0x7e,0x6f,0xc6,0x7e,0x48,0x7b},\n{0xd,0x55,0xa,0xa5,0x4a,0xf8,0xa4,0xc0,0x91,0xe3,0xe7,0x9f,0x97,0x8e,0xf1,0x9e,0x86,0x76,0x72,0x81,0x50,0x60,0x8d,0xd4,0x7e,0x9e,0x5a,0x41,0xf3,0xe5,0xb0,0x62},\n{0xfc,0x9f,0x1f,0xec,0x40,0x54,0x20,0x7a,0xe3,0xe4,0x1a,0x0,0xce,0xf4,0xc9,0x84,0x4f,0xd7,0x94,0xf5,0x9d,0xfa,0x95,0xd8,0x55,0x2e,0x7e,0x11,0x24,0xc3,0x54,0xa5},\n{0x5b,0xdf,0x72,0x28,0xbd,0xfe,0x6e,0x28,0x78,0xf5,0x7f,0xe2,0xf,0xa5,0xc4,0xb2,0x5,0x89,0x7c,0xef,0xee,0x49,0xd3,0x2e,0x44,0x7e,0x93,0x85,0xeb,0x28,0x59,0x7f},\n{0x70,0x5f,0x69,0x37,0xb3,0x24,0x31,0x4a,0x5e,0x86,0x28,0xf1,0x1d,0xd6,0xe4,0x65,0xc7,0x1b,0x77,0x4,0x51,0xb9,0x20,0xe7,0x74,0xfe,0x43,0xe8,0x23,0xd4,0x87,0x8a},\n{0x7d,0x29,0xe8,0xa3,0x92,0x76,0x94,0xf2,0xdd,0xcb,0x7a,0x9,0x9b,0x30,0xd9,0xc1,0x1d,0x1b,0x30,0xfb,0x5b,0xdc,0x1b,0xe0,0xda,0x24,0x49,0x4f,0xf2,0x9c,0x82,0xbf},\n{0xa4,0xe7,0xba,0x31,0xb4,0x70,0xbf,0xff,0xd,0x32,0x44,0x5,0xde,0xf8,0xbc,0x48,0x3b,0xae,0xfc,0x32,0x53,0xbb,0xd3,0x39,0x45,0x9f,0xc3,0xc1,0xe0,0x29,0x8b,0xa0},\n{0xe5,0xc9,0x5,0xfd,0xf7,0xae,0x9,0xf,0x94,0x70,0x34,0x12,0x42,0x90,0xf1,0x34,0xa2,0x71,0xb7,0x1,0xe3,0x44,0xed,0x95,0xe9,0x3b,0x8e,0x36,0x4f,0x2f,0x98,0x4a},\n{0x88,0x40,0x1d,0x63,0xa0,0x6c,0xf6,0x15,0x47,0xc1,0x44,0x4b,0x87,0x52,0xaf,0xff,0x7e,0xbb,0x4a,0xf1,0xe2,0xa,0xc6,0x30,0x46,0x70,0xb6,0xc5,0xcc,0x6e,0x8c,0xe6},\n{0xa4,0xd5,0xa4,0x56,0xbd,0x4f,0xca,0x0,0xda,0x9d,0x84,0x4b,0xc8,0x3e,0x18,0xae,0x73,0x57,0xce,0x45,0x30,0x64,0xd1,0xad,0xe8,0xa6,0xce,0x68,0x14,0x5c,0x25,0x67},\n{0xa3,0xda,0x8c,0xf2,0xcb,0xe,0xe1,0x16,0x33,0xe9,0x6,0x58,0x9a,0x94,0x99,0x9a,0x1f,0x60,0xb2,0x20,0xc2,0x6f,0x84,0x7b,0xd1,0xce,0xac,0x7f,0xa0,0xd1,0x85,0x18},\n{0x32,0x59,0x5b,0xa1,0x8d,0xdd,0x19,0xd3,0x50,0x9a,0x1c,0xc0,0xaa,0xa5,0xb4,0x46,0x9f,0x3d,0x63,0x67,0xe4,0x4,0x6b,0xba,0xf6,0xca,0x19,0xab,0xb,0x56,0xee,0x7e},\n{0x1f,0xb1,0x79,0xea,0xa9,0x28,0x21,0x74,0xe9,0xbd,0xf7,0x35,0x3b,0x36,0x51,0xee,0x1d,0x57,0xac,0x5a,0x75,0x50,0xd3,0x76,0x3a,0x46,0xc2,0xfe,0xa3,0x7d,0x70,0x1},\n{0xf7,0x35,0xc1,0xaf,0x98,0xa4,0xd8,0x42,0x78,0xed,0xec,0x20,0x9e,0x6b,0x67,0x79,0x41,0x83,0x63,0x15,0xea,0x3a,0xdb,0xa8,0xfa,0xc3,0x3b,0x4d,0x32,0x83,0x2c,0x83},\n{0xa7,0x40,0x3b,0x1f,0x1c,0x27,0x47,0xf3,0x59,0x40,0xf0,0x34,0xb7,0x2d,0x76,0x9a,0xe7,0x3e,0x4e,0x6c,0xd2,0x21,0x4f,0xfd,0xb8,0xfd,0x8d,0x39,0xdc,0x57,0x59,0xef},\n{0x8d,0x9b,0xc,0x49,0x2b,0x49,0xeb,0xda,0x5b,0xa2,0xd7,0x49,0x68,0xf3,0x70,0xd,0x7d,0x3b,0xae,0xd0,0x7a,0x8d,0x55,0x84,0xf5,0xa5,0xe9,0xf0,0xe4,0xf8,0x8e,0x65},\n{0xa0,0xb8,0xa2,0xf4,0x36,0x10,0x3b,0x53,0xc,0xa8,0x7,0x9e,0x75,0x3e,0xec,0x5a,0x91,0x68,0x94,0x92,0x56,0xe8,0x88,0x4f,0x5b,0xb0,0x5c,0x55,0xf8,0xba,0xbc,0x4c},\n{0xe3,0xbb,0x3b,0x99,0xf3,0x87,0x94,0x7b,0x75,0xda,0xf4,0xd6,0x72,0x6b,0x1c,0x5d,0x64,0xae,0xac,0x28,0xdc,0x34,0xb3,0x6d,0x6c,0x34,0xa5,0x50,0xb8,0x28,0xdb,0x71},\n{0xf8,0x61,0xe2,0xf2,0x10,0x8d,0x51,0x2a,0xe3,0xdb,0x64,0x33,0x59,0xdd,0x75,0xfc,0x1c,0xac,0xbc,0xf1,0x43,0xce,0x3f,0xa2,0x67,0xbb,0xd1,0x3c,0x2,0xe8,0x43,0xb0},\n{0x33,0xa,0x5b,0xca,0x88,0x29,0xa1,0x75,0x7f,0x34,0x19,0x4d,0xb4,0x16,0x53,0x5c,0x92,0x3b,0x94,0xc3,0xe,0x79,0x4d,0x1e,0x79,0x74,0x75,0xd7,0xb6,0xee,0xaf,0x3f},\n{0xea,0xa8,0xd4,0xf7,0xbe,0x1a,0x39,0x21,0x5c,0xf4,0x7e,0x9,0x4c,0x23,0x27,0x51,0x26,0xa3,0x24,0x53,0xba,0x32,0x3c,0xd2,0x44,0xa3,0x17,0x4a,0x6d,0xa6,0xd5,0xad},\n{0xb5,0x1d,0x3e,0xa6,0xaf,0xf2,0xc9,0x8,0x83,0x59,0x3d,0x98,0x91,0x6b,0x3c,0x56,0x4c,0xf8,0x7c,0xa1,0x72,0x86,0x60,0x4d,0x46,0xe2,0x3e,0xcc,0x8,0x6e,0xc7,0xf6},\n{0x2f,0x98,0x33,0xb3,0xb1,0xbc,0x76,0x5e,0x2b,0xd6,0x66,0xa5,0xef,0xc4,0xe6,0x2a,0x6,0xf4,0xb6,0xe8,0xbe,0xc1,0xd4,0x36,0x74,0xee,0x82,0x15,0xbc,0xef,0x21,0x63},\n{0xfd,0xc1,0x4e,0xd,0xf4,0x53,0xc9,0x69,0xa7,0x7d,0x5a,0xc4,0x6,0x58,0x58,0x26,0x7e,0xc1,0x14,0x16,0x6,0xe0,0xfa,0x16,0x7e,0x90,0xaf,0x3d,0x28,0x63,0x9d,0x3f},\n{0xd2,0xc9,0xf2,0xe3,0x0,0x9b,0xd2,0xc,0x5f,0xaa,0xce,0x30,0xb7,0xd4,0xc,0x30,0x74,0x2a,0x51,0x16,0xf2,0xe0,0x32,0x98,0xd,0xeb,0x30,0xd8,0xe3,0xce,0xf8,0x9a},\n{0x4b,0xc5,0x9e,0x7b,0xb5,0xf1,0x79,0x92,0xff,0x51,0xe6,0x6e,0x4,0x86,0x68,0xd3,0x9b,0x23,0x4d,0x57,0xe6,0x96,0x67,0x31,0xcc,0xe6,0xa6,0xf3,0x17,0xa,0x75,0x5},\n{0xb1,0x76,0x81,0xd9,0x13,0x32,0x6c,0xce,0x3c,0x17,0x52,0x84,0xf8,0x5,0xa2,0x62,0xf4,0x2b,0xcb,0xb3,0x78,0x47,0x15,0x47,0xff,0x46,0x54,0x82,0x23,0x93,0x6a,0x48},\n{0x38,0xdf,0x58,0x7,0x4e,0x5e,0x65,0x65,0xf2,0xfc,0x7c,0x89,0xfc,0x86,0x50,0x8e,0x31,0x70,0x2e,0x44,0xd0,0xb,0xca,0x86,0xf0,0x40,0x9,0xa2,0x30,0x78,0x47,0x4e},\n{0x65,0xa0,0xee,0x39,0xd1,0xf7,0x38,0x83,0xf7,0x5e,0xe9,0x37,0xe4,0x2c,0x3a,0xbd,0x21,0x97,0xb2,0x26,0x1,0x13,0xf8,0x6f,0xa3,0x44,0xed,0xd1,0xef,0x9f,0xde,0xe7},\n{0x8b,0xa0,0xdf,0x15,0x76,0x25,0x92,0xd9,0x3c,0x85,0xf7,0xf6,0x12,0xdc,0x42,0xbe,0xd8,0xa7,0xec,0x7c,0xab,0x27,0xb0,0x7e,0x53,0x8d,0x7d,0xda,0xaa,0x3e,0xa8,0xde},\n{0xaa,0x25,0xce,0x93,0xbd,0x2,0x69,0xd8,0x5a,0xf6,0x43,0xfd,0x1a,0x73,0x8,0xf9,0xc0,0x5f,0xef,0xda,0x17,0x4a,0x19,0xa5,0x97,0x4d,0x66,0x33,0x4c,0xfd,0x21,0x6a},\n{0x35,0xb4,0x98,0x31,0xdb,0x41,0x15,0x70,0xea,0x1e,0xf,0xbb,0xed,0xcd,0x54,0x9b,0x9a,0xd0,0x63,0xa1,0x51,0x97,0x40,0x72,0xf6,0x75,0x9d,0xbf,0x91,0x47,0x6f,0xe2}};\n\n\nstatic void E8(hashState *state);  /*The bijective function E8, in bitslice form*/\nstatic void F8(hashState *state);  /*The compression function F8 */\n\n/*The API functions*/\nstatic HashReturn Init(hashState *state, int hashbitlen);\nstatic HashReturn Update(hashState *state, const BitSequence *data, DataLength databitlen);\nstatic HashReturn Final(hashState *state, BitSequence *hashval);\nHashReturn jh_hash(int hashbitlen, const BitSequence *data,DataLength databitlen, BitSequence *hashval);\n\n/*swapping bit 2i with bit 2i+1 of 64-bit x*/\n#define SWAP1(x)   (x) = ((((x) & 0x5555555555555555ULL) << 1) | (((x) & 0xaaaaaaaaaaaaaaaaULL) >> 1));\n/*swapping bits 4i||4i+1 with bits 4i+2||4i+3 of 64-bit x*/\n#define SWAP2(x)   (x) = ((((x) & 0x3333333333333333ULL) << 2) | (((x) & 0xccccccccccccccccULL) >> 2));\n/*swapping bits 8i||8i+1||8i+2||8i+3 with bits 8i+4||8i+5||8i+6||8i+7 of 64-bit x*/\n#define SWAP4(x)   (x) = ((((x) & 0x0f0f0f0f0f0f0f0fULL) << 4) | (((x) & 0xf0f0f0f0f0f0f0f0ULL) >> 4));\n/*swapping bits 16i||16i+1||......||16i+7  with bits 16i+8||16i+9||......||16i+15 of 64-bit x*/\n#define SWAP8(x)   (x) = ((((x) & 0x00ff00ff00ff00ffULL) << 8) | (((x) & 0xff00ff00ff00ff00ULL) >> 8));\n/*swapping bits 32i||32i+1||......||32i+15 with bits 32i+16||32i+17||......||32i+31 of 64-bit x*/\n#define SWAP16(x)  (x) = ((((x) & 0x0000ffff0000ffffULL) << 16) | (((x) & 0xffff0000ffff0000ULL) >> 16));\n/*swapping bits 64i||64i+1||......||64i+31 with bits 64i+32||64i+33||......||64i+63 of 64-bit x*/\n#define SWAP32(x)  (x) = (((x) << 32) | ((x) >> 32));\n\n/*The MDS transform*/\n#define L(m0,m1,m2,m3,m4,m5,m6,m7) \\\n\t  (m4) ^= (m1);                \\\n\t  (m5) ^= (m2);                \\\n\t  (m6) ^= (m0) ^ (m3);         \\\n\t  (m7) ^= (m0);                \\\n\t  (m0) ^= (m5);                \\\n\t  (m1) ^= (m6);                \\\n\t  (m2) ^= (m4) ^ (m7);         \\\n\t  (m3) ^= (m4);\n\n/*Two Sboxes are computed in parallel, each Sbox implements S0 and S1, selected by a constant bit*/\n/*The reason to compute two Sboxes in parallel is to try to fully utilize the parallel processing power*/\n#define SS(m0,m1,m2,m3,m4,m5,m6,m7,cc0,cc1)   \\\n\t  m3  = ~(m3);                  \\\n\t  m7  = ~(m7);                  \\\n\t  m0 ^= ((~(m2)) & (cc0));      \\\n\t  m4 ^= ((~(m6)) & (cc1));      \\\n\t  temp0 = (cc0) ^ ((m0) & (m1));\\\n\t  temp1 = (cc1) ^ ((m4) & (m5));\\\n\t  m0 ^= ((m2) & (m3));          \\\n\t  m4 ^= ((m6) & (m7));          \\\n\t  m3 ^= ((~(m1)) & (m2));       \\\n\t  m7 ^= ((~(m5)) & (m6));       \\\n\t  m1 ^= ((m0) & (m2));          \\\n\t  m5 ^= ((m4) & (m6));          \\\n\t  m2 ^= ((m0) & (~(m3)));       \\\n\t  m6 ^= ((m4) & (~(m7)));       \\\n\t  m0 ^= ((m1) | (m3));          \\\n\t  m4 ^= ((m5) | (m7));          \\\n\t  m3 ^= ((m1) & (m2));          \\\n\t  m7 ^= ((m5) & (m6));          \\\n\t  m1 ^= (temp0 & (m0));         \\\n\t  m5 ^= (temp1 & (m4));         \\\n\t  m2 ^= temp0;                  \\\n\t  m6 ^= temp1;\n\n/*The bijective function E8, in bitslice form*/\nstatic void E8(hashState *state)\n{\n\t  uint64 i,roundnumber,temp0,temp1;\n\n\t  for (roundnumber = 0; roundnumber < 42; roundnumber = roundnumber+7) {\n\t\t\t/*round 7*roundnumber+0: Sbox, MDS and Swapping layers*/\n\t\t\tfor (i = 0; i < 2; i++) {\n\t\t\t\t  SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+0])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+0])[i+2] );\n\t\t\t\t  L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]);\n\t\t\t\t  SWAP1(state->x[1][i]); SWAP1(state->x[3][i]); SWAP1(state->x[5][i]); SWAP1(state->x[7][i]);\n\t\t\t}\n\n\t\t\t/*round 7*roundnumber+1: Sbox, MDS and Swapping layers*/\n\t\t\tfor (i = 0; i < 2; i++) {\n\t\t\t\t  SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+1])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+1])[i+2] );\n\t\t\t\t  L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]);\n\t\t\t\t  SWAP2(state->x[1][i]); SWAP2(state->x[3][i]); SWAP2(state->x[5][i]); SWAP2(state->x[7][i]);\n\t\t\t}\n\n\t\t\t/*round 7*roundnumber+2: Sbox, MDS and Swapping layers*/\n\t\t\tfor (i = 0; i < 2; i++) {\n\t\t\t\t  SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+2])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+2])[i+2] );\n\t\t\t\t  L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]);\n\t\t\t\t  SWAP4(state->x[1][i]); SWAP4(state->x[3][i]); SWAP4(state->x[5][i]); SWAP4(state->x[7][i]);\n\t\t\t}\n\n\t\t\t/*round 7*roundnumber+3: Sbox, MDS and Swapping layers*/\n\t\t\tfor (i = 0; i < 2; i++) {\n\t\t\t\t  SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+3])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+3])[i+2] );\n\t\t\t\t  L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]);\n\t\t\t\t  SWAP8(state->x[1][i]); SWAP8(state->x[3][i]); SWAP8(state->x[5][i]); SWAP8(state->x[7][i]);\n\t\t\t}\n\n\t\t\t/*round 7*roundnumber+4: Sbox, MDS and Swapping layers*/\n\t\t\tfor (i = 0; i < 2; i++) {\n\t\t\t\t  SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+4])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+4])[i+2] );\n\t\t\t\t  L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]);\n\t\t\t\t  SWAP16(state->x[1][i]); SWAP16(state->x[3][i]); SWAP16(state->x[5][i]); SWAP16(state->x[7][i]);\n\t\t\t}\n\n\t\t\t/*round 7*roundnumber+5: Sbox, MDS and Swapping layers*/\n\t\t\tfor (i = 0; i < 2; i++) {\n\t\t\t\t  SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+5])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+5])[i+2] );\n\t\t\t\t  L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]);\n\t\t\t\t  SWAP32(state->x[1][i]); SWAP32(state->x[3][i]); SWAP32(state->x[5][i]); SWAP32(state->x[7][i]);\n\t\t\t}\n\n\t\t\t/*round 7*roundnumber+6: Sbox and MDS layers*/\n\t\t\tfor (i = 0; i < 2; i++) {\n\t\t\t\t  SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+6])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+6])[i+2] );\n\t\t\t\t  L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]);\n\t\t\t}\n\t\t\t/*round 7*roundnumber+6: swapping layer*/\n\t\t\tfor (i = 1; i < 8; i = i+2) {\n\t\t\t\t  temp0 = state->x[i][0]; state->x[i][0] = state->x[i][1]; state->x[i][1] = temp0;\n\t\t\t}\n\t  }\n\n}\n\n/*The compression function F8 */\nstatic void F8(hashState *state)\n{\n\t  uint64  i;\n\n\t  /*xor the 512-bit message with the fist half of the 1024-bit hash state*/\n\t  for (i = 0; i < 8; i++)  state->x[i >> 1][i & 1] ^= ((uint64*)state->buffer)[i];\n\n\t  /*the bijective function E8 */\n\t  E8(state);\n\n\t  /*xor the 512-bit message with the second half of the 1024-bit hash state*/\n\t  for (i = 0; i < 8; i++)  state->x[(8+i) >> 1][(8+i) & 1] ^= ((uint64*)state->buffer)[i];\n}\n\n/*before hashing a message, initialize the hash state as H0 */\nstatic HashReturn Init(hashState *state, int hashbitlen)\n{\n\t  state->databitlen = 0;\n\t  state->datasize_in_buffer = 0;\n\n\t  /*initialize the initial hash value of JH*/\n\t  state->hashbitlen = hashbitlen;\n\n\t  /*load the intital hash value into state*/\n\t  switch (hashbitlen)\n\t  {\n\t\t\tcase 224: memcpy(state->x,JH224_H0,128); break;\n\t\t\tcase 256: memcpy(state->x,JH256_H0,128); break;\n\t\t\tcase 384: memcpy(state->x,JH384_H0,128); break;\n\t\t\tcase 512: memcpy(state->x,JH512_H0,128); break;\n\t  }\n\n\t  return(SUCCESS);\n}\n\n\n/*hash each 512-bit message block, except the last partial block*/\nstatic HashReturn Update(hashState *state, const BitSequence *data, DataLength databitlen)\n{\n\t  DataLength index; /*the starting address of the data to be compressed*/\n\n\t  state->databitlen += databitlen;\n\t  index = 0;\n\n\t  /*if there is remaining data in the buffer, fill it to a full message block first*/\n\t  /*we assume that the size of the data in the buffer is the multiple of 8 bits if it is not at the end of a message*/\n\n\t  /*There is data in the buffer, but the incoming data is insufficient for a full block*/\n\t  if ( (state->datasize_in_buffer > 0 ) && (( state->datasize_in_buffer + databitlen) < 512)  ) {\n\t\t\tif ( (databitlen & 7) == 0 ) {\n\t\t\t\t memcpy(state->buffer + (state->datasize_in_buffer >> 3), data, 64-(state->datasize_in_buffer >> 3)) ;\n\t\t    }\n\t\t\telse memcpy(state->buffer + (state->datasize_in_buffer >> 3), data, 64-(state->datasize_in_buffer >> 3)+1) ;\n\t\t\tstate->datasize_in_buffer += databitlen;\n\t\t\tdatabitlen = 0;\n\t  }\n\n\t  /*There is data in the buffer, and the incoming data is sufficient for a full block*/\n\t  if ( (state->datasize_in_buffer > 0 ) && (( state->datasize_in_buffer + databitlen) >= 512)  ) {\n\t        memcpy( state->buffer + (state->datasize_in_buffer >> 3), data, 64-(state->datasize_in_buffer >> 3) ) ;\n\t        index = 64-(state->datasize_in_buffer >> 3);\n\t        databitlen = databitlen - (512 - state->datasize_in_buffer);\n\t        F8(state);\n\t        state->datasize_in_buffer = 0;\n\t  }\n\n\t  /*hash the remaining full message blocks*/\n\t  for ( ; databitlen >= 512; index = index+64, databitlen = databitlen - 512) {\n\t\t\tmemcpy(state->buffer, data+index, 64);\n\t\t\tF8(state);\n\t  }\n\n\t  /*store the partial block into buffer, assume that -- if part of the last byte is not part of the message, then that part consists of 0 bits*/\n\t  if ( databitlen > 0) {\n\t\t\tif ((databitlen & 7) == 0)\n\t\t\t\t  memcpy(state->buffer, data+index, (databitlen & 0x1ff) >> 3);\n\t\t\telse\n\t\t\t\t  memcpy(state->buffer, data+index, ((databitlen & 0x1ff) >> 3)+1);\n\t\t\tstate->datasize_in_buffer = databitlen;\n\t  }\n\n\t  return(SUCCESS);\n}\n\n/*pad the message, process the padded block(s), truncate the hash value H to obtain the message digest*/\nstatic HashReturn Final(hashState *state, BitSequence *hashval)\n{\n\t  unsigned int i;\n\n\t  if ( (state->databitlen & 0x1ff) == 0 ) {\n\t\t\t/*pad the message when databitlen is multiple of 512 bits, then process the padded block*/\n\t\t\tmemset(state->buffer, 0, 64);\n\t\t\tstate->buffer[0]  = 0x80;\n\t\t\tstate->buffer[63] = state->databitlen & 0xff;\n\t\t\tstate->buffer[62] = (state->databitlen >> 8)  & 0xff;\n\t\t\tstate->buffer[61] = (state->databitlen >> 16) & 0xff;\n\t\t\tstate->buffer[60] = (state->databitlen >> 24) & 0xff;\n\t\t\tstate->buffer[59] = (state->databitlen >> 32) & 0xff;\n\t\t\tstate->buffer[58] = (state->databitlen >> 40) & 0xff;\n\t\t\tstate->buffer[57] = (state->databitlen >> 48) & 0xff;\n\t\t\tstate->buffer[56] = (state->databitlen >> 56) & 0xff;\n\t\t\tF8(state);\n\t  }\n\t  else {\n\t\t    /*set the rest of the bytes in the buffer to 0*/\n\t\t\tif ( (state->datasize_in_buffer & 7) == 0)\n\t\t\t\t  for (i = (state->databitlen & 0x1ff) >> 3; i < 64; i++)  state->buffer[i] = 0;\n\t\t\telse\n\t\t\t\t  for (i = ((state->databitlen & 0x1ff) >> 3)+1; i < 64; i++)  state->buffer[i] = 0;\n\n\t\t\t/*pad and process the partial block when databitlen is not multiple of 512 bits, then hash the padded blocks*/\n\t\t\tstate->buffer[((state->databitlen & 0x1ff) >> 3)] |= 1 << (7- (state->databitlen & 7));\n\n\t\t\tF8(state);\n\t\t\tmemset(state->buffer, 0, 64);\n\t\t\tstate->buffer[63] = state->databitlen & 0xff;\n\t\t\tstate->buffer[62] = (state->databitlen >> 8) & 0xff;\n\t\t\tstate->buffer[61] = (state->databitlen >> 16) & 0xff;\n\t\t\tstate->buffer[60] = (state->databitlen >> 24) & 0xff;\n\t\t\tstate->buffer[59] = (state->databitlen >> 32) & 0xff;\n\t\t\tstate->buffer[58] = (state->databitlen >> 40) & 0xff;\n\t\t\tstate->buffer[57] = (state->databitlen >> 48) & 0xff;\n\t\t\tstate->buffer[56] = (state->databitlen >> 56) & 0xff;\n\t\t\tF8(state);\n\t  }\n\n\t  /*truncating the final hash value to generate the message digest*/\n\t  switch(state->hashbitlen) {\n\t\t\tcase 224: memcpy(hashval,(unsigned char*)state->x+64+36,28);  break;\n\t\t\tcase 256: memcpy(hashval,(unsigned char*)state->x+64+32,32);  break;\n\t\t\tcase 384: memcpy(hashval,(unsigned char*)state->x+64+16,48);  break;\n\t\t\tcase 512: memcpy(hashval,(unsigned char*)state->x+64,64);     break;\n\t  }\n\n\t  return(SUCCESS);\n}\n\n/* hash a message,\n   three inputs: message digest size in bits (hashbitlen); message (data); message length in bits (databitlen)\n   one output:   message digest (hashval)\n*/\nHashReturn jh_hash(int hashbitlen, const BitSequence *data,DataLength databitlen, BitSequence *hashval)\n{\n\t  hashState state;\n\n\t  if ( hashbitlen == 224 || hashbitlen == 256 || hashbitlen == 384 || hashbitlen == 512 ) {\n\t\t\tInit(&state, hashbitlen);\n\t\t\tUpdate(&state, data, databitlen);\n\t\t\tFinal(&state, hashval);\n\t\t\treturn SUCCESS;\n\t  }\n\t  else\n\t\t\treturn(BAD_HASHLEN);\n}\n"
  },
  {
    "path": "crypto/c_jh.h",
    "content": "/*This program gives the 64-bit optimized bitslice implementation of JH using ANSI C\n\n   --------------------------------\n   Performance\n\n   Microprocessor: Intel CORE 2 processor (Core 2 Duo Mobile T6600 2.2GHz)\n   Operating System: 64-bit Ubuntu 10.04 (Linux kernel 2.6.32-22-generic)\n   Speed for long message:\n   1) 45.8 cycles/byte   compiler: Intel C++ Compiler 11.1   compilation option: icc -O2\n   2) 56.8 cycles/byte   compiler: gcc 4.4.3                 compilation option: gcc -O3\n\n   --------------------------------\n   Last Modified: January 16, 2011\n*/\n#pragma once\n\n#include \"hash.h\"\n\nHashReturn jh_hash(int hashbitlen, const BitSequence *data, DataLength databitlen, BitSequence *hashval);\n"
  },
  {
    "path": "crypto/c_keccak.c",
    "content": "// keccak.c\n// 19-Nov-11  Markku-Juhani O. Saarinen <mjos@iki.fi>\n// A baseline Keccak (3rd round) implementation.\n\n#include <stdint.h>\n#include <memory.h>\n\n#define HASH_DATA_AREA 136\n#define KECCAK_ROUNDS 24\n\n#ifndef ROTL64\n#define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y))))\n#endif\n\nconst uint64_t keccakf_rndc[24] = \n{\n\t0x0000000000000001, 0x0000000000008082, 0x800000000000808a,\n\t0x8000000080008000, 0x000000000000808b, 0x0000000080000001,\n\t0x8000000080008081, 0x8000000000008009, 0x000000000000008a,\n\t0x0000000000000088, 0x0000000080008009, 0x000000008000000a,\n\t0x000000008000808b, 0x800000000000008b, 0x8000000000008089,\n\t0x8000000000008003, 0x8000000000008002, 0x8000000000000080, \n\t0x000000000000800a, 0x800000008000000a, 0x8000000080008081,\n\t0x8000000000008080, 0x0000000080000001, 0x8000000080008008\n};\n\nconst int keccakf_rotc[24] = \n{\n\t1,  3,  6,  10, 15, 21, 28, 36, 45, 55, 2,  14, \n\t27, 41, 56, 8,  25, 43, 62, 18, 39, 61, 20, 44\n};\n\nconst int keccakf_piln[24] = \n{\n\t10, 7,  11, 17, 18, 3, 5,  16, 8,  21, 24, 4, \n\t15, 23, 19, 13, 12, 2, 20, 14, 22, 9,  6,  1 \n};\n\n// update the state with given number of rounds\n\nvoid keccakf(uint64_t st[25], int rounds)\n{\n\tint i, j, round;\n\tuint64_t t, bc[5];\n\n\tfor (round = 0; round < rounds; ++round) {\n\n\t\t// Theta\n\t\tbc[0] = st[0] ^ st[5] ^ st[10] ^ st[15] ^ st[20];\n\t\tbc[1] = st[1] ^ st[6] ^ st[11] ^ st[16] ^ st[21];\n\t\tbc[2] = st[2] ^ st[7] ^ st[12] ^ st[17] ^ st[22];\n\t\tbc[3] = st[3] ^ st[8] ^ st[13] ^ st[18] ^ st[23];\n\t\tbc[4] = st[4] ^ st[9] ^ st[14] ^ st[19] ^ st[24];\n\n\t\tfor (i = 0; i < 5; ++i) {\n\t\t\tt = bc[(i + 4) % 5] ^ ROTL64(bc[(i + 1) % 5], 1);\n\t\t\tst[i     ] ^= t;\n\t\t\tst[i +  5] ^= t;\n\t\t\tst[i + 10] ^= t;\n\t\t\tst[i + 15] ^= t;\n\t\t\tst[i + 20] ^= t;\n\t\t}\n\n\t\t// Rho Pi\n\t\tt = st[1];\n\t\tfor (i = 0; i < 24; ++i) {\n\t\t\tbc[0] = st[keccakf_piln[i]];\n\t\t\tst[keccakf_piln[i]] = ROTL64(t, keccakf_rotc[i]);\n\t\t\tt = bc[0];\n\t\t}\n\n\t\t//  Chi\n\t\tfor (j = 0; j < 25; j += 5) {\n\t\t\tbc[0] = st[j    ];\n\t\t\tbc[1] = st[j + 1];\n\t\t\tbc[2] = st[j + 2];\n\t\t\tbc[3] = st[j + 3];\n\t\t\tbc[4] = st[j + 4];\n\t\t\tst[j    ] ^= (~bc[1]) & bc[2];\n\t\t\tst[j + 1] ^= (~bc[2]) & bc[3];\n\t\t\tst[j + 2] ^= (~bc[3]) & bc[4];\n\t\t\tst[j + 3] ^= (~bc[4]) & bc[0];\n\t\t\tst[j + 4] ^= (~bc[0]) & bc[1];\n\t\t}\n\n\t\t//  Iota\n\t\tst[0] ^= keccakf_rndc[round];\n\t}\n}\n\n// compute a keccak hash (md) of given byte length from \"in\"\ntypedef uint64_t state_t[25];\n\nvoid keccak(const uint8_t *in, int inlen, uint8_t *md, int mdlen)\n{\n\tstate_t st;\n\tuint8_t temp[144];\n\tint i, rsiz, rsizw;\n\n\trsiz = sizeof(state_t) == mdlen ? HASH_DATA_AREA : 200 - 2 * mdlen;\n\trsizw = rsiz / 8;\n\t\n\tmemset(st, 0, sizeof(st));\n\n\tfor ( ; inlen >= rsiz; inlen -= rsiz, in += rsiz) {\n\t\tfor (i = 0; i < rsizw; i++)\n\t\t\tst[i] ^= ((uint64_t *) in)[i];\n\t\tkeccakf(st, KECCAK_ROUNDS);\n\t}\n\t\n\t// last block and padding\n\tmemcpy(temp, in, inlen);\n\ttemp[inlen++] = 1;\n\tmemset(temp + inlen, 0, rsiz - inlen);\n\ttemp[rsiz - 1] |= 0x80;\n\n\tfor (i = 0; i < rsizw; i++)\n\t\tst[i] ^= ((uint64_t *) temp)[i];\n\n\tkeccakf(st, KECCAK_ROUNDS);\n\n\tmemcpy(md, st, mdlen);\n}\n\nvoid keccak1600(const uint8_t *in, int inlen, uint8_t *md)\n{\n\tkeccak(in, inlen, md, sizeof(state_t));\n}"
  },
  {
    "path": "crypto/c_keccak.h",
    "content": "// keccak.h\n// 19-Nov-11  Markku-Juhani O. Saarinen <mjos@iki.fi>\n\n#ifndef KECCAK_H\n#define KECCAK_H\n\n#include <stdint.h>\n#include <string.h>\n\n#ifndef KECCAK_ROUNDS\n#define KECCAK_ROUNDS 24\n#endif\n\n#ifndef ROTL64\n#define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y))))\n#endif\n\n// compute a keccak hash (md) of given byte length from \"in\"\nint keccak(const uint8_t *in, int inlen, uint8_t *md, int mdlen);\n\n// update the state\nvoid keccakf(uint64_t st[25], int norounds);\n\nvoid keccak1600(const uint8_t *in, int inlen, uint8_t *md);\n\n#endif\n"
  },
  {
    "path": "crypto/c_skein.c",
    "content": "/***********************************************************************\n**\n** Implementation of the Skein hash function.\n**\n** Source code author: Doug Whiting, 2008.\n**\n** This algorithm and source code is released to the public domain.\n** \n************************************************************************/\n\n#define  SKEIN_PORT_CODE /* instantiate any code in skein_port.h */\n\n#include <stddef.h>                          /* get size_t definition */\n#include <string.h>      /* get the memcpy/memset functions */\n#include \"c_skein.h\"       /* get the Skein API definitions   */\n\n#define DISABLE_UNUSED 0\n\n#ifndef SKEIN_256_NIST_MAX_HASHBITS\n#define SKEIN_256_NIST_MAX_HASHBITS (0)\n#endif\n\n#ifndef SKEIN_512_NIST_MAX_HASHBITS\n#define SKEIN_512_NIST_MAX_HASHBITS (512)\n#endif\n\n#define  SKEIN_MODIFIER_WORDS  ( 2)          /* number of modifier (tweak) words */\n\n#define  SKEIN_256_STATE_WORDS ( 4)\n#define  SKEIN_512_STATE_WORDS ( 8)\n#define  SKEIN1024_STATE_WORDS (16)\n#define  SKEIN_MAX_STATE_WORDS (16)\n\n#define  SKEIN_256_STATE_BYTES ( 8*SKEIN_256_STATE_WORDS)\n#define  SKEIN_512_STATE_BYTES ( 8*SKEIN_512_STATE_WORDS)\n#define  SKEIN1024_STATE_BYTES ( 8*SKEIN1024_STATE_WORDS)\n\n#define  SKEIN_256_STATE_BITS  (64*SKEIN_256_STATE_WORDS)\n#define  SKEIN_512_STATE_BITS  (64*SKEIN_512_STATE_WORDS)\n#define  SKEIN1024_STATE_BITS  (64*SKEIN1024_STATE_WORDS)\n\n#define  SKEIN_256_BLOCK_BYTES ( 8*SKEIN_256_STATE_WORDS)\n#define  SKEIN_512_BLOCK_BYTES ( 8*SKEIN_512_STATE_WORDS)\n#define  SKEIN1024_BLOCK_BYTES ( 8*SKEIN1024_STATE_WORDS)\n\n#define SKEIN_RND_SPECIAL       (1000u)\n#define SKEIN_RND_KEY_INITIAL   (SKEIN_RND_SPECIAL+0u)\n#define SKEIN_RND_KEY_INJECT    (SKEIN_RND_SPECIAL+1u)\n#define SKEIN_RND_FEED_FWD      (SKEIN_RND_SPECIAL+2u)\n\ntypedef struct\n{\n  size_t  hashBitLen;                      /* size of hash result, in bits */\n  size_t  bCnt;                            /* current byte count in buffer b[] */\n  u64b_t  T[SKEIN_MODIFIER_WORDS];         /* tweak words: T[0]=byte cnt, T[1]=flags */\n} Skein_Ctxt_Hdr_t;\n\ntypedef struct                               /*  256-bit Skein hash context structure */\n{\n  Skein_Ctxt_Hdr_t h;                      /* common header context variables */\n  u64b_t  X[SKEIN_256_STATE_WORDS];        /* chaining variables */\n  u08b_t  b[SKEIN_256_BLOCK_BYTES];        /* partial block buffer (8-byte aligned) */\n} Skein_256_Ctxt_t;\n\ntypedef struct                               /*  512-bit Skein hash context structure */\n{\n  Skein_Ctxt_Hdr_t h;                      /* common header context variables */\n  u64b_t  X[SKEIN_512_STATE_WORDS];        /* chaining variables */\n  u08b_t  b[SKEIN_512_BLOCK_BYTES];        /* partial block buffer (8-byte aligned) */\n} Skein_512_Ctxt_t;\n\ntypedef struct                               /* 1024-bit Skein hash context structure */\n{\n  Skein_Ctxt_Hdr_t h;                      /* common header context variables */\n  u64b_t  X[SKEIN1024_STATE_WORDS];        /* chaining variables */\n  u08b_t  b[SKEIN1024_BLOCK_BYTES];        /* partial block buffer (8-byte aligned) */\n} Skein1024_Ctxt_t;\n\n/*   Skein APIs for (incremental) \"straight hashing\" */\n#if SKEIN_256_NIST_MAX_HASH_BITS\nstatic int  Skein_256_Init  (Skein_256_Ctxt_t *ctx, size_t hashBitLen);\n#endif\nstatic int  Skein_512_Init  (Skein_512_Ctxt_t *ctx, size_t hashBitLen);\nstatic int  Skein1024_Init  (Skein1024_Ctxt_t *ctx, size_t hashBitLen);\n\nstatic int  Skein_256_Update(Skein_256_Ctxt_t *ctx, const u08b_t *msg, size_t msgByteCnt);\nstatic int  Skein_512_Update(Skein_512_Ctxt_t *ctx, const u08b_t *msg, size_t msgByteCnt);\nstatic int  Skein1024_Update(Skein1024_Ctxt_t *ctx, const u08b_t *msg, size_t msgByteCnt);\n\nstatic int  Skein_256_Final (Skein_256_Ctxt_t *ctx, u08b_t * hashVal);\nstatic int  Skein_512_Final (Skein_512_Ctxt_t *ctx, u08b_t * hashVal);\nstatic int  Skein1024_Final (Skein1024_Ctxt_t *ctx, u08b_t * hashVal);\n\n/*\n**   Skein APIs for \"extended\" initialization: MAC keys, tree hashing.\n**   After an InitExt() call, just use Update/Final calls as with Init().\n**\n**   Notes: Same parameters as _Init() calls, plus treeInfo/key/keyBytes.\n**          When keyBytes == 0 and treeInfo == SKEIN_SEQUENTIAL, \n**              the results of InitExt() are identical to calling Init().\n**          The function Init() may be called once to \"precompute\" the IV for\n**              a given hashBitLen value, then by saving a copy of the context\n**              the IV computation may be avoided in later calls.\n**          Similarly, the function InitExt() may be called once per MAC key \n**              to precompute the MAC IV, then a copy of the context saved and\n**              reused for each new MAC computation.\n**/\n#if 0\nstatic int  Skein_256_InitExt(Skein_256_Ctxt_t *ctx, size_t hashBitLen, u64b_t treeInfo, const u08b_t *key, size_t keyBytes);\nstatic int  Skein_512_InitExt(Skein_512_Ctxt_t *ctx, size_t hashBitLen, u64b_t treeInfo, const u08b_t *key, size_t keyBytes);\nstatic int  Skein1024_InitExt(Skein1024_Ctxt_t *ctx, size_t hashBitLen, u64b_t treeInfo, const u08b_t *key, size_t keyBytes);\n#endif\n\n/*\n**   Skein APIs for MAC and tree hash:\n**      Final_Pad:  pad, do final block, but no OUTPUT type\n**      Output:     do just the output stage\n*/\n#if 0\nstatic int  Skein_256_Final_Pad(Skein_256_Ctxt_t *ctx, u08b_t * hashVal);\nstatic int  Skein_512_Final_Pad(Skein_512_Ctxt_t *ctx, u08b_t * hashVal);\nstatic int  Skein1024_Final_Pad(Skein1024_Ctxt_t *ctx, u08b_t * hashVal);\n#endif\n\n#ifndef SKEIN_TREE_HASH\n#define SKEIN_TREE_HASH (1)\n#endif\n#if 0\n#if  SKEIN_TREE_HASH\nstatic int  Skein_256_Output   (Skein_256_Ctxt_t *ctx, u08b_t * hashVal);\nstatic int  Skein_512_Output   (Skein_512_Ctxt_t *ctx, u08b_t * hashVal);\nstatic int  Skein1024_Output   (Skein1024_Ctxt_t *ctx, u08b_t * hashVal);\n#endif\n#endif\n\n/*****************************************************************\n** \"Internal\" Skein definitions\n**    -- not needed for sequential hashing API, but will be \n**           helpful for other uses of Skein (e.g., tree hash mode).\n**    -- included here so that they can be shared between\n**           reference and optimized code.\n******************************************************************/\n\n/* tweak word T[1]: bit field starting positions */\n#define SKEIN_T1_BIT(BIT)       ((BIT) - 64)            /* offset 64 because it's the second word  */\n\n#define SKEIN_T1_POS_TREE_LVL   SKEIN_T1_BIT(112)       /* bits 112..118: level in hash tree       */\n#define SKEIN_T1_POS_BIT_PAD    SKEIN_T1_BIT(119)       /* bit  119     : partial final input byte */\n#define SKEIN_T1_POS_BLK_TYPE   SKEIN_T1_BIT(120)       /* bits 120..125: type field               */\n#define SKEIN_T1_POS_FIRST      SKEIN_T1_BIT(126)       /* bits 126     : first block flag         */\n#define SKEIN_T1_POS_FINAL      SKEIN_T1_BIT(127)       /* bit  127     : final block flag         */\n\n/* tweak word T[1]: flag bit definition(s) */\n#define SKEIN_T1_FLAG_FIRST     (((u64b_t)  1 ) << SKEIN_T1_POS_FIRST)\n#define SKEIN_T1_FLAG_FINAL     (((u64b_t)  1 ) << SKEIN_T1_POS_FINAL)\n#define SKEIN_T1_FLAG_BIT_PAD   (((u64b_t)  1 ) << SKEIN_T1_POS_BIT_PAD)\n\n/* tweak word T[1]: tree level bit field mask */\n#define SKEIN_T1_TREE_LVL_MASK  (((u64b_t)0x7F) << SKEIN_T1_POS_TREE_LVL)\n#define SKEIN_T1_TREE_LEVEL(n)  (((u64b_t) (n)) << SKEIN_T1_POS_TREE_LVL)\n\n/* tweak word T[1]: block type field */\n#define SKEIN_BLK_TYPE_KEY      ( 0)                    /* key, for MAC and KDF */\n#define SKEIN_BLK_TYPE_CFG      ( 4)                    /* configuration block */\n#define SKEIN_BLK_TYPE_PERS     ( 8)                    /* personalization string */\n#define SKEIN_BLK_TYPE_PK       (12)                    /* public key (for digital signature hashing) */\n#define SKEIN_BLK_TYPE_KDF      (16)                    /* key identifier for KDF */\n#define SKEIN_BLK_TYPE_NONCE    (20)                    /* nonce for PRNG */\n#define SKEIN_BLK_TYPE_MSG      (48)                    /* message processing */\n#define SKEIN_BLK_TYPE_OUT      (63)                    /* output stage */\n#define SKEIN_BLK_TYPE_MASK     (63)                    /* bit field mask */\n\n#define SKEIN_T1_BLK_TYPE(T)   (((u64b_t) (SKEIN_BLK_TYPE_##T)) << SKEIN_T1_POS_BLK_TYPE)\n#define SKEIN_T1_BLK_TYPE_KEY   SKEIN_T1_BLK_TYPE(KEY)  /* key, for MAC and KDF */\n#define SKEIN_T1_BLK_TYPE_CFG   SKEIN_T1_BLK_TYPE(CFG)  /* configuration block */\n#define SKEIN_T1_BLK_TYPE_PERS  SKEIN_T1_BLK_TYPE(PERS) /* personalization string */\n#define SKEIN_T1_BLK_TYPE_PK    SKEIN_T1_BLK_TYPE(PK)   /* public key (for digital signature hashing) */\n#define SKEIN_T1_BLK_TYPE_KDF   SKEIN_T1_BLK_TYPE(KDF)  /* key identifier for KDF */\n#define SKEIN_T1_BLK_TYPE_NONCE SKEIN_T1_BLK_TYPE(NONCE)/* nonce for PRNG */\n#define SKEIN_T1_BLK_TYPE_MSG   SKEIN_T1_BLK_TYPE(MSG)  /* message processing */\n#define SKEIN_T1_BLK_TYPE_OUT   SKEIN_T1_BLK_TYPE(OUT)  /* output stage */\n#define SKEIN_T1_BLK_TYPE_MASK  SKEIN_T1_BLK_TYPE(MASK) /* field bit mask */\n\n#define SKEIN_T1_BLK_TYPE_CFG_FINAL       (SKEIN_T1_BLK_TYPE_CFG | SKEIN_T1_FLAG_FINAL)\n#define SKEIN_T1_BLK_TYPE_OUT_FINAL       (SKEIN_T1_BLK_TYPE_OUT | SKEIN_T1_FLAG_FINAL)\n\n#define SKEIN_VERSION           (1)\n\n#ifndef SKEIN_ID_STRING_LE      /* allow compile-time personalization */\n#define SKEIN_ID_STRING_LE      (0x33414853)            /* \"SHA3\" (little-endian)*/\n#endif\n\n#define SKEIN_MK_64(hi32,lo32)  ((lo32) + (((u64b_t) (hi32)) << 32))\n#define SKEIN_SCHEMA_VER        SKEIN_MK_64(SKEIN_VERSION,SKEIN_ID_STRING_LE)\n#define SKEIN_KS_PARITY         SKEIN_MK_64(0x1BD11BDA,0xA9FC1A22)\n\n#define SKEIN_CFG_STR_LEN       (4*8)\n\n/* bit field definitions in config block treeInfo word */\n#define SKEIN_CFG_TREE_LEAF_SIZE_POS  ( 0)\n#define SKEIN_CFG_TREE_NODE_SIZE_POS  ( 8)\n#define SKEIN_CFG_TREE_MAX_LEVEL_POS  (16)\n\n#define SKEIN_CFG_TREE_LEAF_SIZE_MSK  (((u64b_t) 0xFF) << SKEIN_CFG_TREE_LEAF_SIZE_POS)\n#define SKEIN_CFG_TREE_NODE_SIZE_MSK  (((u64b_t) 0xFF) << SKEIN_CFG_TREE_NODE_SIZE_POS)\n#define SKEIN_CFG_TREE_MAX_LEVEL_MSK  (((u64b_t) 0xFF) << SKEIN_CFG_TREE_MAX_LEVEL_POS)\n\n#define SKEIN_CFG_TREE_INFO(leaf,node,maxLvl)                   \\\n  ( (((u64b_t)(leaf  )) << SKEIN_CFG_TREE_LEAF_SIZE_POS) |    \\\n  (((u64b_t)(node  )) << SKEIN_CFG_TREE_NODE_SIZE_POS) |    \\\n  (((u64b_t)(maxLvl)) << SKEIN_CFG_TREE_MAX_LEVEL_POS) )\n\n#define SKEIN_CFG_TREE_INFO_SEQUENTIAL SKEIN_CFG_TREE_INFO(0,0,0) /* use as treeInfo in InitExt() call for sequential processing */\n\n/*\n**   Skein macros for getting/setting tweak words, etc.\n**   These are useful for partial input bytes, hash tree init/update, etc.\n**/\n#define Skein_Get_Tweak(ctxPtr,TWK_NUM)         ((ctxPtr)->h.T[TWK_NUM])\n#define Skein_Set_Tweak(ctxPtr,TWK_NUM,tVal)    {(ctxPtr)->h.T[TWK_NUM] = (tVal);}\n\n#define Skein_Get_T0(ctxPtr)    Skein_Get_Tweak(ctxPtr,0)\n#define Skein_Get_T1(ctxPtr)    Skein_Get_Tweak(ctxPtr,1)\n#define Skein_Set_T0(ctxPtr,T0) Skein_Set_Tweak(ctxPtr,0,T0)\n#define Skein_Set_T1(ctxPtr,T1) Skein_Set_Tweak(ctxPtr,1,T1)\n\n/* set both tweak words at once */\n#define Skein_Set_T0_T1(ctxPtr,T0,T1)           \\\n{                                           \\\n  Skein_Set_T0(ctxPtr,(T0));                  \\\n  Skein_Set_T1(ctxPtr,(T1));                  \\\n}\n\n#define Skein_Set_Type(ctxPtr,BLK_TYPE)         \\\n  Skein_Set_T1(ctxPtr,SKEIN_T1_BLK_TYPE_##BLK_TYPE)\n\n/* set up for starting with a new type: h.T[0]=0; h.T[1] = NEW_TYPE; h.bCnt=0; */\n#define Skein_Start_New_Type(ctxPtr,BLK_TYPE)   \\\n{ Skein_Set_T0_T1(ctxPtr,0,SKEIN_T1_FLAG_FIRST | SKEIN_T1_BLK_TYPE_##BLK_TYPE); (ctxPtr)->h.bCnt=0; }\n\n#define Skein_Clear_First_Flag(hdr)      { (hdr).T[1] &= ~SKEIN_T1_FLAG_FIRST;       }\n#define Skein_Set_Bit_Pad_Flag(hdr)      { (hdr).T[1] |=  SKEIN_T1_FLAG_BIT_PAD;     }\n\n#define Skein_Set_Tree_Level(hdr,height) { (hdr).T[1] |= SKEIN_T1_TREE_LEVEL(height);}\n\n/*****************************************************************\n** \"Internal\" Skein definitions for debugging and error checking\n******************************************************************/\n#define Skein_Show_Block(bits,ctx,X,blkPtr,wPtr,ksEvenPtr,ksOddPtr)\n#define Skein_Show_Round(bits,ctx,r,X)\n#define Skein_Show_R_Ptr(bits,ctx,r,X_ptr)\n#define Skein_Show_Final(bits,ctx,cnt,outPtr)\n#define Skein_Show_Key(bits,ctx,key,keyBytes)\n\n\n#ifndef SKEIN_ERR_CHECK        /* run-time checks (e.g., bad params, uninitialized context)? */\n#define Skein_Assert(x,retCode)/* default: ignore all Asserts, for performance */\n#define Skein_assert(x)\n#elif   defined(SKEIN_ASSERT)\n#include <assert.h>     \n#define Skein_Assert(x,retCode) assert(x) \n#define Skein_assert(x)         assert(x) \n#else\n#include <assert.h>     \n#define Skein_Assert(x,retCode) { if (!(x)) return retCode; } /*  caller  error */\n#define Skein_assert(x)         assert(x)                     /* internal error */\n#endif\n\n/*****************************************************************\n** Skein block function constants (shared across Ref and Opt code)\n******************************************************************/\nenum    \n{   \n  /* Skein_256 round rotation constants */\n  R_256_0_0=14, R_256_0_1=16,\n  R_256_1_0=52, R_256_1_1=57,\n  R_256_2_0=23, R_256_2_1=40,\n  R_256_3_0= 5, R_256_3_1=37,\n  R_256_4_0=25, R_256_4_1=33,\n  R_256_5_0=46, R_256_5_1=12,\n  R_256_6_0=58, R_256_6_1=22,\n  R_256_7_0=32, R_256_7_1=32,\n\n  /* Skein_512 round rotation constants */\n  R_512_0_0=46, R_512_0_1=36, R_512_0_2=19, R_512_0_3=37,\n  R_512_1_0=33, R_512_1_1=27, R_512_1_2=14, R_512_1_3=42,\n  R_512_2_0=17, R_512_2_1=49, R_512_2_2=36, R_512_2_3=39,\n  R_512_3_0=44, R_512_3_1= 9, R_512_3_2=54, R_512_3_3=56,\n  R_512_4_0=39, R_512_4_1=30, R_512_4_2=34, R_512_4_3=24,\n  R_512_5_0=13, R_512_5_1=50, R_512_5_2=10, R_512_5_3=17,\n  R_512_6_0=25, R_512_6_1=29, R_512_6_2=39, R_512_6_3=43,\n  R_512_7_0= 8, R_512_7_1=35, R_512_7_2=56, R_512_7_3=22,\n\n  /* Skein1024 round rotation constants */\n  R1024_0_0=24, R1024_0_1=13, R1024_0_2= 8, R1024_0_3=47, R1024_0_4= 8, R1024_0_5=17, R1024_0_6=22, R1024_0_7=37,\n  R1024_1_0=38, R1024_1_1=19, R1024_1_2=10, R1024_1_3=55, R1024_1_4=49, R1024_1_5=18, R1024_1_6=23, R1024_1_7=52,\n  R1024_2_0=33, R1024_2_1= 4, R1024_2_2=51, R1024_2_3=13, R1024_2_4=34, R1024_2_5=41, R1024_2_6=59, R1024_2_7=17,\n  R1024_3_0= 5, R1024_3_1=20, R1024_3_2=48, R1024_3_3=41, R1024_3_4=47, R1024_3_5=28, R1024_3_6=16, R1024_3_7=25,\n  R1024_4_0=41, R1024_4_1= 9, R1024_4_2=37, R1024_4_3=31, R1024_4_4=12, R1024_4_5=47, R1024_4_6=44, R1024_4_7=30,\n  R1024_5_0=16, R1024_5_1=34, R1024_5_2=56, R1024_5_3=51, R1024_5_4= 4, R1024_5_5=53, R1024_5_6=42, R1024_5_7=41,\n  R1024_6_0=31, R1024_6_1=44, R1024_6_2=47, R1024_6_3=46, R1024_6_4=19, R1024_6_5=42, R1024_6_6=44, R1024_6_7=25,\n  R1024_7_0= 9, R1024_7_1=48, R1024_7_2=35, R1024_7_3=52, R1024_7_4=23, R1024_7_5=31, R1024_7_6=37, R1024_7_7=20\n};\n\n#ifndef SKEIN_ROUNDS\n#define SKEIN_256_ROUNDS_TOTAL (72)          /* number of rounds for the different block sizes */\n#define SKEIN_512_ROUNDS_TOTAL (72)\n#define SKEIN1024_ROUNDS_TOTAL (80)\n#else                                        /* allow command-line define in range 8*(5..14)   */\n#define SKEIN_256_ROUNDS_TOTAL (8*((((SKEIN_ROUNDS/100) + 5) % 10) + 5))\n#define SKEIN_512_ROUNDS_TOTAL (8*((((SKEIN_ROUNDS/ 10) + 5) % 10) + 5))\n#define SKEIN1024_ROUNDS_TOTAL (8*((((SKEIN_ROUNDS    ) + 5) % 10) + 5))\n#endif\n\n\n/*\n***************** Pre-computed Skein IVs *******************\n**\n** NOTE: these values are not \"magic\" constants, but\n** are generated using the Threefish block function.\n** They are pre-computed here only for speed; i.e., to\n** avoid the need for a Threefish call during Init().\n**\n** The IV for any fixed hash length may be pre-computed.\n** Only the most common values are included here.\n**\n************************************************************\n**/\n\n#define MK_64 SKEIN_MK_64\n\n/* blkSize =  256 bits. hashSize =  128 bits */\nconst u64b_t SKEIN_256_IV_128[] =\n\t{\n\tMK_64(0xE1111906,0x964D7260),\n\tMK_64(0x883DAAA7,0x7C8D811C),\n\tMK_64(0x10080DF4,0x91960F7A),\n\tMK_64(0xCCF7DDE5,0xB45BC1C2)\n\t};\n\n/* blkSize =  256 bits. hashSize =  160 bits */\nconst u64b_t SKEIN_256_IV_160[] =\n\t{\n\tMK_64(0x14202314,0x72825E98),\n\tMK_64(0x2AC4E9A2,0x5A77E590),\n\tMK_64(0xD47A5856,0x8838D63E),\n\tMK_64(0x2DD2E496,0x8586AB7D)\n\t};\n\n/* blkSize =  256 bits. hashSize =  224 bits */\nconst u64b_t SKEIN_256_IV_224[] =\n\t{\n\tMK_64(0xC6098A8C,0x9AE5EA0B),\n\tMK_64(0x876D5686,0x08C5191C),\n\tMK_64(0x99CB88D7,0xD7F53884),\n\tMK_64(0x384BDDB1,0xAEDDB5DE)\n\t};\n\n/* blkSize =  256 bits. hashSize =  256 bits */\nconst u64b_t SKEIN_256_IV_256[] =\n\t{\n\tMK_64(0xFC9DA860,0xD048B449),\n\tMK_64(0x2FCA6647,0x9FA7D833),\n\tMK_64(0xB33BC389,0x6656840F),\n\tMK_64(0x6A54E920,0xFDE8DA69)\n\t};\n\n/* blkSize =  512 bits. hashSize =  128 bits */\nconst u64b_t SKEIN_512_IV_128[] =\n\t{\n\tMK_64(0xA8BC7BF3,0x6FBF9F52),\n\tMK_64(0x1E9872CE,0xBD1AF0AA),\n\tMK_64(0x309B1790,0xB32190D3),\n\tMK_64(0xBCFBB854,0x3F94805C),\n\tMK_64(0x0DA61BCD,0x6E31B11B),\n\tMK_64(0x1A18EBEA,0xD46A32E3),\n\tMK_64(0xA2CC5B18,0xCE84AA82),\n\tMK_64(0x6982AB28,0x9D46982D)\n\t};\n\n/* blkSize =  512 bits. hashSize =  160 bits */\nconst u64b_t SKEIN_512_IV_160[] =\n\t{\n\tMK_64(0x28B81A2A,0xE013BD91),\n\tMK_64(0xC2F11668,0xB5BDF78F),\n\tMK_64(0x1760D8F3,0xF6A56F12),\n\tMK_64(0x4FB74758,0x8239904F),\n\tMK_64(0x21EDE07F,0x7EAF5056),\n\tMK_64(0xD908922E,0x63ED70B8),\n\tMK_64(0xB8EC76FF,0xECCB52FA),\n\tMK_64(0x01A47BB8,0xA3F27A6E)\n\t};\n\n/* blkSize =  512 bits. hashSize =  224 bits */\nconst u64b_t SKEIN_512_IV_224[] =\n\t{\n\tMK_64(0xCCD06162,0x48677224),\n\tMK_64(0xCBA65CF3,0xA92339EF),\n\tMK_64(0x8CCD69D6,0x52FF4B64),\n\tMK_64(0x398AED7B,0x3AB890B4),\n\tMK_64(0x0F59D1B1,0x457D2BD0),\n\tMK_64(0x6776FE65,0x75D4EB3D),\n\tMK_64(0x99FBC70E,0x997413E9),\n\tMK_64(0x9E2CFCCF,0xE1C41EF7)\n\t};\n\n/* blkSize =  512 bits. hashSize =  256 bits */\nconst u64b_t SKEIN_512_IV_256[] =\n\t{\n\tMK_64(0xCCD044A1,0x2FDB3E13),\n\tMK_64(0xE8359030,0x1A79A9EB),\n\tMK_64(0x55AEA061,0x4F816E6F),\n\tMK_64(0x2A2767A4,0xAE9B94DB),\n\tMK_64(0xEC06025E,0x74DD7683),\n\tMK_64(0xE7A436CD,0xC4746251),\n\tMK_64(0xC36FBAF9,0x393AD185),\n\tMK_64(0x3EEDBA18,0x33EDFC13)\n\t};\n\n/* blkSize =  512 bits. hashSize =  384 bits */\nconst u64b_t SKEIN_512_IV_384[] =\n\t{\n\tMK_64(0xA3F6C6BF,0x3A75EF5F),\n\tMK_64(0xB0FEF9CC,0xFD84FAA4),\n\tMK_64(0x9D77DD66,0x3D770CFE),\n\tMK_64(0xD798CBF3,0xB468FDDA),\n\tMK_64(0x1BC4A666,0x8A0E4465),\n\tMK_64(0x7ED7D434,0xE5807407),\n\tMK_64(0x548FC1AC,0xD4EC44D6),\n\tMK_64(0x266E1754,0x6AA18FF8)\n\t};\n\n/* blkSize =  512 bits. hashSize =  512 bits */\nconst u64b_t SKEIN_512_IV_512[] =\n\t{\n\tMK_64(0x4903ADFF,0x749C51CE),\n\tMK_64(0x0D95DE39,0x9746DF03),\n\tMK_64(0x8FD19341,0x27C79BCE),\n\tMK_64(0x9A255629,0xFF352CB1),\n\tMK_64(0x5DB62599,0xDF6CA7B0),\n\tMK_64(0xEABE394C,0xA9D5C3F4),\n\tMK_64(0x991112C7,0x1A75B523),\n\tMK_64(0xAE18A40B,0x660FCC33)\n\t};\n\n/* blkSize = 1024 bits. hashSize =  384 bits */\nconst u64b_t SKEIN1024_IV_384[] =\n\t{\n\tMK_64(0x5102B6B8,0xC1894A35),\n\tMK_64(0xFEEBC9E3,0xFE8AF11A),\n\tMK_64(0x0C807F06,0xE32BED71),\n\tMK_64(0x60C13A52,0xB41A91F6),\n\tMK_64(0x9716D35D,0xD4917C38),\n\tMK_64(0xE780DF12,0x6FD31D3A),\n\tMK_64(0x797846B6,0xC898303A),\n\tMK_64(0xB172C2A8,0xB3572A3B),\n\tMK_64(0xC9BC8203,0xA6104A6C),\n\tMK_64(0x65909338,0xD75624F4),\n\tMK_64(0x94BCC568,0x4B3F81A0),\n\tMK_64(0x3EBBF51E,0x10ECFD46),\n\tMK_64(0x2DF50F0B,0xEEB08542),\n\tMK_64(0x3B5A6530,0x0DBC6516),\n\tMK_64(0x484B9CD2,0x167BBCE1),\n\tMK_64(0x2D136947,0xD4CBAFEA)\n\t};\n\n/* blkSize = 1024 bits. hashSize =  512 bits */\nconst u64b_t SKEIN1024_IV_512[] =\n\t{\n\tMK_64(0xCAEC0E5D,0x7C1B1B18),\n\tMK_64(0xA01B0E04,0x5F03E802),\n\tMK_64(0x33840451,0xED912885),\n\tMK_64(0x374AFB04,0xEAEC2E1C),\n\tMK_64(0xDF25A0E2,0x813581F7),\n\tMK_64(0xE4004093,0x8B12F9D2),\n\tMK_64(0xA662D539,0xC2ED39B6),\n\tMK_64(0xFA8B85CF,0x45D8C75A),\n\tMK_64(0x8316ED8E,0x29EDE796),\n\tMK_64(0x053289C0,0x2E9F91B8),\n\tMK_64(0xC3F8EF1D,0x6D518B73),\n\tMK_64(0xBDCEC3C4,0xD5EF332E),\n\tMK_64(0x549A7E52,0x22974487),\n\tMK_64(0x67070872,0x5B749816),\n\tMK_64(0xB9CD28FB,0xF0581BD1),\n\tMK_64(0x0E2940B8,0x15804974)\n\t};\n\n/* blkSize = 1024 bits. hashSize = 1024 bits */\nconst u64b_t SKEIN1024_IV_1024[] =\n\t{\n\tMK_64(0xD593DA07,0x41E72355),\n\tMK_64(0x15B5E511,0xAC73E00C),\n\tMK_64(0x5180E5AE,0xBAF2C4F0),\n\tMK_64(0x03BD41D3,0xFCBCAFAF),\n\tMK_64(0x1CAEC6FD,0x1983A898),\n\tMK_64(0x6E510B8B,0xCDD0589F),\n\tMK_64(0x77E2BDFD,0xC6394ADA),\n\tMK_64(0xC11E1DB5,0x24DCB0A3),\n\tMK_64(0xD6D14AF9,0xC6329AB5),\n\tMK_64(0x6A9B0BFC,0x6EB67E0D),\n\tMK_64(0x9243C60D,0xCCFF1332),\n\tMK_64(0x1A1F1DDE,0x743F02D4),\n\tMK_64(0x0996753C,0x10ED0BB8),\n\tMK_64(0x6572DD22,0xF2B4969A),\n\tMK_64(0x61FD3062,0xD00A579A),\n\tMK_64(0x1DE0536E,0x8682E539)\n\t};\n\n\n#ifndef SKEIN_USE_ASM\n#define SKEIN_USE_ASM   (0)                     /* default is all C code (no ASM) */\n#endif\n\n#ifndef SKEIN_LOOP\n#define SKEIN_LOOP 001                          /* default: unroll 256 and 512, but not 1024 */\n#endif\n\n#define BLK_BITS        (WCNT*64)               /* some useful definitions for code here */\n#define KW_TWK_BASE     (0)\n#define KW_KEY_BASE     (3)\n#define ks              (kw + KW_KEY_BASE)                \n#define ts              (kw + KW_TWK_BASE)\n\n#ifdef SKEIN_DEBUG\n#define DebugSaveTweak(ctx) { ctx->h.T[0] = ts[0]; ctx->h.T[1] = ts[1]; }\n#else\n#define DebugSaveTweak(ctx)\n#endif\n\n/*****************************  Skein_256 ******************************/\n#if !(SKEIN_USE_ASM & 256)\nstatic void Skein_256_Process_Block(Skein_256_Ctxt_t *ctx,const u08b_t *blkPtr,size_t blkCnt,size_t byteCntAdd)\n\t{ /* do it in C */\n\tenum\n\t\t{\n\t\tWCNT = SKEIN_256_STATE_WORDS\n\t\t};\n#undef  RCNT\n#define RCNT  (SKEIN_256_ROUNDS_TOTAL/8)\n\n#ifdef  SKEIN_LOOP                              /* configure how much to unroll the loop */\n#define SKEIN_UNROLL_256 (((SKEIN_LOOP)/100)%10)\n#else\n#define SKEIN_UNROLL_256 (0)\n#endif\n\n#if SKEIN_UNROLL_256\n#if (RCNT % SKEIN_UNROLL_256)\n#error \"Invalid SKEIN_UNROLL_256\"               /* sanity check on unroll count */\n#endif\n\tsize_t  r;\n\tu64b_t  kw[WCNT+4+RCNT*2];                  /* key schedule words : chaining vars + tweak + \"rotation\"*/\n#else\n\tu64b_t  kw[WCNT+4];                         /* key schedule words : chaining vars + tweak */\n#endif\n\tu64b_t  X0,X1,X2,X3;                        /* local copy of context vars, for speed */\n\tu64b_t  w [WCNT];                           /* local copy of input block */\n#ifdef SKEIN_DEBUG\n\tconst u64b_t *Xptr[4];                      /* use for debugging (help compiler put Xn in registers) */\n\tXptr[0] = &X0;  Xptr[1] = &X1;  Xptr[2] = &X2;  Xptr[3] = &X3;\n#endif\n\tSkein_assert(blkCnt != 0);                  /* never call with blkCnt == 0! */\n\tts[0] = ctx->h.T[0];\n\tts[1] = ctx->h.T[1];\n\tdo  {\n\t\t/* this implementation only supports 2**64 input bytes (no carry out here) */\n\t\tts[0] += byteCntAdd;                    /* update processed length */\n\n\t\t/* precompute the key schedule for this block */\n\t\tks[0] = ctx->X[0];     \n\t\tks[1] = ctx->X[1];\n\t\tks[2] = ctx->X[2];\n\t\tks[3] = ctx->X[3];\n\t\tks[4] = ks[0] ^ ks[1] ^ ks[2] ^ ks[3] ^ SKEIN_KS_PARITY;\n\n\t\tts[2] = ts[0] ^ ts[1];\n\n\t\tSkein_Get64_LSB_First(w,blkPtr,WCNT);   /* get input block in little-endian format */\n\t\tDebugSaveTweak(ctx);\n\t\tSkein_Show_Block(BLK_BITS,&ctx->h,ctx->X,blkPtr,w,ks,ts);\n\n\t\tX0 = w[0] + ks[0];                      /* do the first full key injection */\n\t\tX1 = w[1] + ks[1] + ts[0];\n\t\tX2 = w[2] + ks[2] + ts[1];\n\t\tX3 = w[3] + ks[3];\n\n\t\tSkein_Show_R_Ptr(BLK_BITS,&ctx->h,SKEIN_RND_KEY_INITIAL,Xptr);    /* show starting state values */\n\n\t\tblkPtr += SKEIN_256_BLOCK_BYTES;\n\n\t\t/* run the rounds */\n\n#define Round256(p0,p1,p2,p3,ROT,rNum)                              \\\n\tX##p0 += X##p1; X##p1 = RotL_64(X##p1,ROT##_0); X##p1 ^= X##p0; \\\n\tX##p2 += X##p3; X##p3 = RotL_64(X##p3,ROT##_1); X##p3 ^= X##p2; \\\n\n#if SKEIN_UNROLL_256 == 0                       \n#define R256(p0,p1,p2,p3,ROT,rNum)           /* fully unrolled */   \\\n\tRound256(p0,p1,p2,p3,ROT,rNum)                                  \\\n\tSkein_Show_R_Ptr(BLK_BITS,&ctx->h,rNum,Xptr);\n\n#define I256(R)                                                     \\\n\tX0   += ks[((R)+1) % 5];    /* inject the key schedule value */ \\\n\tX1   += ks[((R)+2) % 5] + ts[((R)+1) % 3];                      \\\n\tX2   += ks[((R)+3) % 5] + ts[((R)+2) % 3];                      \\\n\tX3   += ks[((R)+4) % 5] +     (R)+1;                            \\\n\tSkein_Show_R_Ptr(BLK_BITS,&ctx->h,SKEIN_RND_KEY_INJECT,Xptr);\n#else                                       /* looping version */\n#define R256(p0,p1,p2,p3,ROT,rNum)                                  \\\n\tRound256(p0,p1,p2,p3,ROT,rNum)                                  \\\n\tSkein_Show_R_Ptr(BLK_BITS,&ctx->h,4*(r-1)+rNum,Xptr);\n\n#define I256(R)                                                     \\\n\tX0   += ks[r+(R)+0];        /* inject the key schedule value */ \\\n\tX1   += ks[r+(R)+1] + ts[r+(R)+0];                              \\\n\tX2   += ks[r+(R)+2] + ts[r+(R)+1];                              \\\n\tX3   += ks[r+(R)+3] +    r+(R)   ;                              \\\n\tks[r + (R)+4    ]   = ks[r+(R)-1];     /* rotate key schedule */\\\n\tts[r + (R)+2    ]   = ts[r+(R)-1];                              \\\n\tSkein_Show_R_Ptr(BLK_BITS,&ctx->h,SKEIN_RND_KEY_INJECT,Xptr);\n\n\tfor (r=1;r < 2*RCNT;r+=2*SKEIN_UNROLL_256)  /* loop thru it */\n#endif  \n\t\t{    \n#define R256_8_rounds(R)                  \\\n\t\tR256(0,1,2,3,R_256_0,8*(R) + 1);  \\\n\t\tR256(0,3,2,1,R_256_1,8*(R) + 2);  \\\n\t\tR256(0,1,2,3,R_256_2,8*(R) + 3);  \\\n\t\tR256(0,3,2,1,R_256_3,8*(R) + 4);  \\\n\t\tI256(2*(R));                      \\\n\t\tR256(0,1,2,3,R_256_4,8*(R) + 5);  \\\n\t\tR256(0,3,2,1,R_256_5,8*(R) + 6);  \\\n\t\tR256(0,1,2,3,R_256_6,8*(R) + 7);  \\\n\t\tR256(0,3,2,1,R_256_7,8*(R) + 8);  \\\n\t\tI256(2*(R)+1);\n\n\t\tR256_8_rounds( 0);\n\n#define R256_Unroll_R(NN) ((SKEIN_UNROLL_256 == 0 && SKEIN_256_ROUNDS_TOTAL/8 > (NN)) || (SKEIN_UNROLL_256 > (NN)))\n\n  #if   R256_Unroll_R( 1)\n\t\tR256_8_rounds( 1);\n  #endif\n  #if   R256_Unroll_R( 2)\n\t\tR256_8_rounds( 2);\n  #endif\n  #if   R256_Unroll_R( 3)\n\t\tR256_8_rounds( 3);\n  #endif\n  #if   R256_Unroll_R( 4)\n\t\tR256_8_rounds( 4);\n  #endif\n  #if   R256_Unroll_R( 5)\n\t\tR256_8_rounds( 5);\n  #endif\n  #if   R256_Unroll_R( 6)\n\t\tR256_8_rounds( 6);\n  #endif\n  #if   R256_Unroll_R( 7)\n\t\tR256_8_rounds( 7);\n  #endif\n  #if   R256_Unroll_R( 8)\n\t\tR256_8_rounds( 8);\n  #endif\n  #if   R256_Unroll_R( 9)\n\t\tR256_8_rounds( 9);\n  #endif\n  #if   R256_Unroll_R(10)\n\t\tR256_8_rounds(10);\n  #endif\n  #if   R256_Unroll_R(11)\n\t\tR256_8_rounds(11);\n  #endif\n  #if   R256_Unroll_R(12)\n\t\tR256_8_rounds(12);\n  #endif\n  #if   R256_Unroll_R(13)\n\t\tR256_8_rounds(13);\n  #endif\n  #if   R256_Unroll_R(14)\n\t\tR256_8_rounds(14);\n  #endif\n  #if  (SKEIN_UNROLL_256 > 14)\n#error  \"need more unrolling in Skein_256_Process_Block\"\n  #endif\n\t\t}\n\t\t/* do the final \"feedforward\" xor, update context chaining vars */\n\t\tctx->X[0] = X0 ^ w[0];\n\t\tctx->X[1] = X1 ^ w[1];\n\t\tctx->X[2] = X2 ^ w[2];\n\t\tctx->X[3] = X3 ^ w[3];\n\n\t\tSkein_Show_Round(BLK_BITS,&ctx->h,SKEIN_RND_FEED_FWD,ctx->X);\n\n\t\tts[1] &= ~SKEIN_T1_FLAG_FIRST;\n\t\t}\n\twhile (--blkCnt);\n\tctx->h.T[0] = ts[0];\n\tctx->h.T[1] = ts[1];\n\t}\n\n#if defined(SKEIN_CODE_SIZE) || defined(SKEIN_PERF)\nstatic size_t Skein_256_Process_Block_CodeSize(void)\n\t{\n\treturn ((u08b_t *) Skein_256_Process_Block_CodeSize) -\n\t\t   ((u08b_t *) Skein_256_Process_Block);\n\t}\nstatic uint_t Skein_256_Unroll_Cnt(void)\n\t{\n\treturn SKEIN_UNROLL_256;\n\t}\n#endif\n#endif\n\n/*****************************  Skein_512 ******************************/\n#if !(SKEIN_USE_ASM & 512)\nstatic void Skein_512_Process_Block(Skein_512_Ctxt_t *ctx,const u08b_t *blkPtr,size_t blkCnt,size_t byteCntAdd)\n\t{ /* do it in C */\n\tenum\n\t\t{\n\t\tWCNT = SKEIN_512_STATE_WORDS\n\t\t};\n#undef  RCNT\n#define RCNT  (SKEIN_512_ROUNDS_TOTAL/8)\n\n#ifdef  SKEIN_LOOP                              /* configure how much to unroll the loop */\n#define SKEIN_UNROLL_512 (((SKEIN_LOOP)/10)%10)\n#else\n#define SKEIN_UNROLL_512 (0)\n#endif\n\n#if SKEIN_UNROLL_512\n#if (RCNT % SKEIN_UNROLL_512)\n#error \"Invalid SKEIN_UNROLL_512\"               /* sanity check on unroll count */\n#endif\n\tsize_t  r;\n\tu64b_t  kw[WCNT+4+RCNT*2];                  /* key schedule words : chaining vars + tweak + \"rotation\"*/\n#else\n\tu64b_t  kw[WCNT+4];                         /* key schedule words : chaining vars + tweak */\n#endif\n\tu64b_t  X0,X1,X2,X3,X4,X5,X6,X7;            /* local copy of vars, for speed */\n\tu64b_t  w [WCNT];                           /* local copy of input block */\n#ifdef SKEIN_DEBUG\n\tconst u64b_t *Xptr[8];                      /* use for debugging (help compiler put Xn in registers) */\n\tXptr[0] = &X0;  Xptr[1] = &X1;  Xptr[2] = &X2;  Xptr[3] = &X3;\n\tXptr[4] = &X4;  Xptr[5] = &X5;  Xptr[6] = &X6;  Xptr[7] = &X7;\n#endif\n\n\tSkein_assert(blkCnt != 0);                  /* never call with blkCnt == 0! */\n\tts[0] = ctx->h.T[0];\n\tts[1] = ctx->h.T[1];\n\tdo  {\n\t\t/* this implementation only supports 2**64 input bytes (no carry out here) */\n\t\tts[0] += byteCntAdd;                    /* update processed length */\n\n\t\t/* precompute the key schedule for this block */\n\t\tks[0] = ctx->X[0];\n\t\tks[1] = ctx->X[1];\n\t\tks[2] = ctx->X[2];\n\t\tks[3] = ctx->X[3];\n\t\tks[4] = ctx->X[4];\n\t\tks[5] = ctx->X[5];\n\t\tks[6] = ctx->X[6];\n\t\tks[7] = ctx->X[7];\n\t\tks[8] = ks[0] ^ ks[1] ^ ks[2] ^ ks[3] ^ \n\t\t\t\tks[4] ^ ks[5] ^ ks[6] ^ ks[7] ^ SKEIN_KS_PARITY;\n\n\t\tts[2] = ts[0] ^ ts[1];\n\n\t\tSkein_Get64_LSB_First(w,blkPtr,WCNT); /* get input block in little-endian format */\n\t\tDebugSaveTweak(ctx);\n\t\tSkein_Show_Block(BLK_BITS,&ctx->h,ctx->X,blkPtr,w,ks,ts);\n\n\t\tX0   = w[0] + ks[0];                    /* do the first full key injection */\n\t\tX1   = w[1] + ks[1];\n\t\tX2   = w[2] + ks[2];\n\t\tX3   = w[3] + ks[3];\n\t\tX4   = w[4] + ks[4];\n\t\tX5   = w[5] + ks[5] + ts[0];\n\t\tX6   = w[6] + ks[6] + ts[1];\n\t\tX7   = w[7] + ks[7];\n\n\t\tblkPtr += SKEIN_512_BLOCK_BYTES;\n\n\t\tSkein_Show_R_Ptr(BLK_BITS,&ctx->h,SKEIN_RND_KEY_INITIAL,Xptr);\n\t\t/* run the rounds */\n#define Round512(p0,p1,p2,p3,p4,p5,p6,p7,ROT,rNum)                  \\\n\tX##p0 += X##p1; X##p1 = RotL_64(X##p1,ROT##_0); X##p1 ^= X##p0; \\\n\tX##p2 += X##p3; X##p3 = RotL_64(X##p3,ROT##_1); X##p3 ^= X##p2; \\\n\tX##p4 += X##p5; X##p5 = RotL_64(X##p5,ROT##_2); X##p5 ^= X##p4; \\\n\tX##p6 += X##p7; X##p7 = RotL_64(X##p7,ROT##_3); X##p7 ^= X##p6; \\\n\n#if SKEIN_UNROLL_512 == 0                       \n#define R512(p0,p1,p2,p3,p4,p5,p6,p7,ROT,rNum)      /* unrolled */  \\\n\tRound512(p0,p1,p2,p3,p4,p5,p6,p7,ROT,rNum)                      \\\n\tSkein_Show_R_Ptr(BLK_BITS,&ctx->h,rNum,Xptr);\n\n#define I512(R)                                                     \\\n\tX0   += ks[((R)+1) % 9];   /* inject the key schedule value */  \\\n\tX1   += ks[((R)+2) % 9];                                        \\\n\tX2   += ks[((R)+3) % 9];                                        \\\n\tX3   += ks[((R)+4) % 9];                                        \\\n\tX4   += ks[((R)+5) % 9];                                        \\\n\tX5   += ks[((R)+6) % 9] + ts[((R)+1) % 3];                      \\\n\tX6   += ks[((R)+7) % 9] + ts[((R)+2) % 3];                      \\\n\tX7   += ks[((R)+8) % 9] +     (R)+1;                            \\\n\tSkein_Show_R_Ptr(BLK_BITS,&ctx->h,SKEIN_RND_KEY_INJECT,Xptr);\n#else                                       /* looping version */\n#define R512(p0,p1,p2,p3,p4,p5,p6,p7,ROT,rNum)                      \\\n\tRound512(p0,p1,p2,p3,p4,p5,p6,p7,ROT,rNum)                      \\\n\tSkein_Show_R_Ptr(BLK_BITS,&ctx->h,4*(r-1)+rNum,Xptr);\n\n#define I512(R)                                                     \\\n\tX0   += ks[r+(R)+0];        /* inject the key schedule value */ \\\n\tX1   += ks[r+(R)+1];                                            \\\n\tX2   += ks[r+(R)+2];                                            \\\n\tX3   += ks[r+(R)+3];                                            \\\n\tX4   += ks[r+(R)+4];                                            \\\n\tX5   += ks[r+(R)+5] + ts[r+(R)+0];                              \\\n\tX6   += ks[r+(R)+6] + ts[r+(R)+1];                              \\\n\tX7   += ks[r+(R)+7] +    r+(R)   ;                              \\\n\tks[r +       (R)+8] = ks[r+(R)-1];  /* rotate key schedule */   \\\n\tts[r +       (R)+2] = ts[r+(R)-1];                              \\\n\tSkein_Show_R_Ptr(BLK_BITS,&ctx->h,SKEIN_RND_KEY_INJECT,Xptr);\n\n\tfor (r=1;r < 2*RCNT;r+=2*SKEIN_UNROLL_512)   /* loop thru it */\n#endif                         /* end of looped code definitions */\n\t\t{\n#define R512_8_rounds(R)  /* do 8 full rounds */  \\\n\t\tR512(0,1,2,3,4,5,6,7,R_512_0,8*(R)+ 1);   \\\n\t\tR512(2,1,4,7,6,5,0,3,R_512_1,8*(R)+ 2);   \\\n\t\tR512(4,1,6,3,0,5,2,7,R_512_2,8*(R)+ 3);   \\\n\t\tR512(6,1,0,7,2,5,4,3,R_512_3,8*(R)+ 4);   \\\n\t\tI512(2*(R));                              \\\n\t\tR512(0,1,2,3,4,5,6,7,R_512_4,8*(R)+ 5);   \\\n\t\tR512(2,1,4,7,6,5,0,3,R_512_5,8*(R)+ 6);   \\\n\t\tR512(4,1,6,3,0,5,2,7,R_512_6,8*(R)+ 7);   \\\n\t\tR512(6,1,0,7,2,5,4,3,R_512_7,8*(R)+ 8);   \\\n\t\tI512(2*(R)+1);        /* and key injection */\n\n\t\tR512_8_rounds( 0);\n\n#define R512_Unroll_R(NN) ((SKEIN_UNROLL_512 == 0 && SKEIN_512_ROUNDS_TOTAL/8 > (NN)) || (SKEIN_UNROLL_512 > (NN)))\n\n  #if   R512_Unroll_R( 1)\n\t\tR512_8_rounds( 1);\n  #endif\n  #if   R512_Unroll_R( 2)\n\t\tR512_8_rounds( 2);\n  #endif\n  #if   R512_Unroll_R( 3)\n\t\tR512_8_rounds( 3);\n  #endif\n  #if   R512_Unroll_R( 4)\n\t\tR512_8_rounds( 4);\n  #endif\n  #if   R512_Unroll_R( 5)\n\t\tR512_8_rounds( 5);\n  #endif\n  #if   R512_Unroll_R( 6)\n\t\tR512_8_rounds( 6);\n  #endif\n  #if   R512_Unroll_R( 7)\n\t\tR512_8_rounds( 7);\n  #endif\n  #if   R512_Unroll_R( 8)\n\t\tR512_8_rounds( 8);\n  #endif\n  #if   R512_Unroll_R( 9)\n\t\tR512_8_rounds( 9);\n  #endif\n  #if   R512_Unroll_R(10)\n\t\tR512_8_rounds(10);\n  #endif\n  #if   R512_Unroll_R(11)\n\t\tR512_8_rounds(11);\n  #endif\n  #if   R512_Unroll_R(12)\n\t\tR512_8_rounds(12);\n  #endif\n  #if   R512_Unroll_R(13)\n\t\tR512_8_rounds(13);\n  #endif\n  #if   R512_Unroll_R(14)\n\t\tR512_8_rounds(14);\n  #endif\n  #if  (SKEIN_UNROLL_512 > 14)\n#error  \"need more unrolling in Skein_512_Process_Block\"\n  #endif\n\t\t}\n\n\t\t/* do the final \"feedforward\" xor, update context chaining vars */\n\t\tctx->X[0] = X0 ^ w[0];\n\t\tctx->X[1] = X1 ^ w[1];\n\t\tctx->X[2] = X2 ^ w[2];\n\t\tctx->X[3] = X3 ^ w[3];\n\t\tctx->X[4] = X4 ^ w[4];\n\t\tctx->X[5] = X5 ^ w[5];\n\t\tctx->X[6] = X6 ^ w[6];\n\t\tctx->X[7] = X7 ^ w[7];\n\t\tSkein_Show_Round(BLK_BITS,&ctx->h,SKEIN_RND_FEED_FWD,ctx->X);\n\n\t\tts[1] &= ~SKEIN_T1_FLAG_FIRST;\n\t\t}\n\twhile (--blkCnt);\n\tctx->h.T[0] = ts[0];\n\tctx->h.T[1] = ts[1];\n\t}\n\n#if defined(SKEIN_CODE_SIZE) || defined(SKEIN_PERF)\nstatic size_t Skein_512_Process_Block_CodeSize(void)\n\t{\n\treturn ((u08b_t *) Skein_512_Process_Block_CodeSize) -\n\t\t   ((u08b_t *) Skein_512_Process_Block);\n\t}\nstatic uint_t Skein_512_Unroll_Cnt(void)\n\t{\n\treturn SKEIN_UNROLL_512;\n\t}\n#endif\n#endif\n\n/*****************************  Skein1024 ******************************/\n#if !(SKEIN_USE_ASM & 1024)\nstatic void Skein1024_Process_Block(Skein1024_Ctxt_t *ctx,const u08b_t *blkPtr,size_t blkCnt,size_t byteCntAdd)\n\t{ /* do it in C, always looping (unrolled is bigger AND slower!) */\n\tenum\n\t\t{\n\t\tWCNT = SKEIN1024_STATE_WORDS\n\t\t};\n#undef  RCNT\n#define RCNT  (SKEIN1024_ROUNDS_TOTAL/8)\n\n#ifdef  SKEIN_LOOP                              /* configure how much to unroll the loop */\n#define SKEIN_UNROLL_1024 ((SKEIN_LOOP)%10)\n#else\n#define SKEIN_UNROLL_1024 (0)\n#endif\n\n#if (SKEIN_UNROLL_1024 != 0)\n#if (RCNT % SKEIN_UNROLL_1024)\n#error \"Invalid SKEIN_UNROLL_1024\"              /* sanity check on unroll count */\n#endif\n\tsize_t  r;\n\tu64b_t  kw[WCNT+4+RCNT*2];                  /* key schedule words : chaining vars + tweak + \"rotation\"*/\n#else\n\tu64b_t  kw[WCNT+4];                         /* key schedule words : chaining vars + tweak */\n#endif\n\n\tu64b_t  X00,X01,X02,X03,X04,X05,X06,X07,    /* local copy of vars, for speed */\n\t\t\tX08,X09,X10,X11,X12,X13,X14,X15;\n\tu64b_t  w [WCNT];                           /* local copy of input block */\n#ifdef SKEIN_DEBUG\n\tconst u64b_t *Xptr[16];                     /* use for debugging (help compiler put Xn in registers) */\n\tXptr[ 0] = &X00;  Xptr[ 1] = &X01;  Xptr[ 2] = &X02;  Xptr[ 3] = &X03;\n\tXptr[ 4] = &X04;  Xptr[ 5] = &X05;  Xptr[ 6] = &X06;  Xptr[ 7] = &X07;\n\tXptr[ 8] = &X08;  Xptr[ 9] = &X09;  Xptr[10] = &X10;  Xptr[11] = &X11;\n\tXptr[12] = &X12;  Xptr[13] = &X13;  Xptr[14] = &X14;  Xptr[15] = &X15;\n#endif\n\n\tSkein_assert(blkCnt != 0);                  /* never call with blkCnt == 0! */\n\tts[0] = ctx->h.T[0];\n\tts[1] = ctx->h.T[1];\n\tdo  {\n\t\t/* this implementation only supports 2**64 input bytes (no carry out here) */\n\t\tts[0] += byteCntAdd;                    /* update processed length */\n\n\t\t/* precompute the key schedule for this block */\n\t\tks[ 0] = ctx->X[ 0];\n\t\tks[ 1] = ctx->X[ 1];\n\t\tks[ 2] = ctx->X[ 2];\n\t\tks[ 3] = ctx->X[ 3];\n\t\tks[ 4] = ctx->X[ 4];\n\t\tks[ 5] = ctx->X[ 5];\n\t\tks[ 6] = ctx->X[ 6];\n\t\tks[ 7] = ctx->X[ 7];\n\t\tks[ 8] = ctx->X[ 8];\n\t\tks[ 9] = ctx->X[ 9];\n\t\tks[10] = ctx->X[10];\n\t\tks[11] = ctx->X[11];\n\t\tks[12] = ctx->X[12];\n\t\tks[13] = ctx->X[13];\n\t\tks[14] = ctx->X[14];\n\t\tks[15] = ctx->X[15];\n\t\tks[16] = ks[ 0] ^ ks[ 1] ^ ks[ 2] ^ ks[ 3] ^\n\t\t\t\t ks[ 4] ^ ks[ 5] ^ ks[ 6] ^ ks[ 7] ^\n\t\t\t\t ks[ 8] ^ ks[ 9] ^ ks[10] ^ ks[11] ^\n\t\t\t\t ks[12] ^ ks[13] ^ ks[14] ^ ks[15] ^ SKEIN_KS_PARITY;\n\n\t\tts[2]  = ts[0] ^ ts[1];\n\n\t\tSkein_Get64_LSB_First(w,blkPtr,WCNT); /* get input block in little-endian format */\n\t\tDebugSaveTweak(ctx);\n\t\tSkein_Show_Block(BLK_BITS,&ctx->h,ctx->X,blkPtr,w,ks,ts);\n\n\t\tX00    = w[ 0] + ks[ 0];                 /* do the first full key injection */\n\t\tX01    = w[ 1] + ks[ 1];\n\t\tX02    = w[ 2] + ks[ 2];\n\t\tX03    = w[ 3] + ks[ 3];\n\t\tX04    = w[ 4] + ks[ 4];\n\t\tX05    = w[ 5] + ks[ 5];\n\t\tX06    = w[ 6] + ks[ 6];\n\t\tX07    = w[ 7] + ks[ 7];\n\t\tX08    = w[ 8] + ks[ 8];\n\t\tX09    = w[ 9] + ks[ 9];\n\t\tX10    = w[10] + ks[10];\n\t\tX11    = w[11] + ks[11];\n\t\tX12    = w[12] + ks[12];\n\t\tX13    = w[13] + ks[13] + ts[0];\n\t\tX14    = w[14] + ks[14] + ts[1];\n\t\tX15    = w[15] + ks[15];\n\n\t\tSkein_Show_R_Ptr(BLK_BITS,&ctx->h,SKEIN_RND_KEY_INITIAL,Xptr);\n\n#define Round1024(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,pA,pB,pC,pD,pE,pF,ROT,rNum) \\\n\tX##p0 += X##p1; X##p1 = RotL_64(X##p1,ROT##_0); X##p1 ^= X##p0;   \\\n\tX##p2 += X##p3; X##p3 = RotL_64(X##p3,ROT##_1); X##p3 ^= X##p2;   \\\n\tX##p4 += X##p5; X##p5 = RotL_64(X##p5,ROT##_2); X##p5 ^= X##p4;   \\\n\tX##p6 += X##p7; X##p7 = RotL_64(X##p7,ROT##_3); X##p7 ^= X##p6;   \\\n\tX##p8 += X##p9; X##p9 = RotL_64(X##p9,ROT##_4); X##p9 ^= X##p8;   \\\n\tX##pA += X##pB; X##pB = RotL_64(X##pB,ROT##_5); X##pB ^= X##pA;   \\\n\tX##pC += X##pD; X##pD = RotL_64(X##pD,ROT##_6); X##pD ^= X##pC;   \\\n\tX##pE += X##pF; X##pF = RotL_64(X##pF,ROT##_7); X##pF ^= X##pE;   \\\n\n#if SKEIN_UNROLL_1024 == 0                      \n#define R1024(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,pA,pB,pC,pD,pE,pF,ROT,rn) \\\n\tRound1024(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,pA,pB,pC,pD,pE,pF,ROT,rn) \\\n\tSkein_Show_R_Ptr(BLK_BITS,&ctx->h,rn,Xptr);\n\n#define I1024(R)                                                      \\\n\tX00   += ks[((R)+ 1) % 17]; /* inject the key schedule value */   \\\n\tX01   += ks[((R)+ 2) % 17];                                       \\\n\tX02   += ks[((R)+ 3) % 17];                                       \\\n\tX03   += ks[((R)+ 4) % 17];                                       \\\n\tX04   += ks[((R)+ 5) % 17];                                       \\\n\tX05   += ks[((R)+ 6) % 17];                                       \\\n\tX06   += ks[((R)+ 7) % 17];                                       \\\n\tX07   += ks[((R)+ 8) % 17];                                       \\\n\tX08   += ks[((R)+ 9) % 17];                                       \\\n\tX09   += ks[((R)+10) % 17];                                       \\\n\tX10   += ks[((R)+11) % 17];                                       \\\n\tX11   += ks[((R)+12) % 17];                                       \\\n\tX12   += ks[((R)+13) % 17];                                       \\\n\tX13   += ks[((R)+14) % 17] + ts[((R)+1) % 3];                     \\\n\tX14   += ks[((R)+15) % 17] + ts[((R)+2) % 3];                     \\\n\tX15   += ks[((R)+16) % 17] +     (R)+1;                           \\\n\tSkein_Show_R_Ptr(BLK_BITS,&ctx->h,SKEIN_RND_KEY_INJECT,Xptr); \n#else                                       /* looping version */\n#define R1024(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,pA,pB,pC,pD,pE,pF,ROT,rn) \\\n\tRound1024(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,pA,pB,pC,pD,pE,pF,ROT,rn) \\\n\tSkein_Show_R_Ptr(BLK_BITS,&ctx->h,4*(r-1)+rn,Xptr);\n\n#define I1024(R)                                                      \\\n\tX00   += ks[r+(R)+ 0];    /* inject the key schedule value */     \\\n\tX01   += ks[r+(R)+ 1];                                            \\\n\tX02   += ks[r+(R)+ 2];                                            \\\n\tX03   += ks[r+(R)+ 3];                                            \\\n\tX04   += ks[r+(R)+ 4];                                            \\\n\tX05   += ks[r+(R)+ 5];                                            \\\n\tX06   += ks[r+(R)+ 6];                                            \\\n\tX07   += ks[r+(R)+ 7];                                            \\\n\tX08   += ks[r+(R)+ 8];                                            \\\n\tX09   += ks[r+(R)+ 9];                                            \\\n\tX10   += ks[r+(R)+10];                                            \\\n\tX11   += ks[r+(R)+11];                                            \\\n\tX12   += ks[r+(R)+12];                                            \\\n\tX13   += ks[r+(R)+13] + ts[r+(R)+0];                              \\\n\tX14   += ks[r+(R)+14] + ts[r+(R)+1];                              \\\n\tX15   += ks[r+(R)+15] +    r+(R)   ;                              \\\n\tks[r  +       (R)+16] = ks[r+(R)-1];  /* rotate key schedule */   \\\n\tts[r  +       (R)+ 2] = ts[r+(R)-1];                              \\\n\tSkein_Show_R_Ptr(BLK_BITS,&ctx->h,SKEIN_RND_KEY_INJECT,Xptr);\n\n\tfor (r=1;r <= 2*RCNT;r+=2*SKEIN_UNROLL_1024)    /* loop thru it */\n#endif  \n\t\t{\n#define R1024_8_rounds(R)    /* do 8 full rounds */                               \\\n\t\tR1024(00,01,02,03,04,05,06,07,08,09,10,11,12,13,14,15,R1024_0,8*(R) + 1); \\\n\t\tR1024(00,09,02,13,06,11,04,15,10,07,12,03,14,05,08,01,R1024_1,8*(R) + 2); \\\n\t\tR1024(00,07,02,05,04,03,06,01,12,15,14,13,08,11,10,09,R1024_2,8*(R) + 3); \\\n\t\tR1024(00,15,02,11,06,13,04,09,14,01,08,05,10,03,12,07,R1024_3,8*(R) + 4); \\\n\t\tI1024(2*(R));                                                             \\\n\t\tR1024(00,01,02,03,04,05,06,07,08,09,10,11,12,13,14,15,R1024_4,8*(R) + 5); \\\n\t\tR1024(00,09,02,13,06,11,04,15,10,07,12,03,14,05,08,01,R1024_5,8*(R) + 6); \\\n\t\tR1024(00,07,02,05,04,03,06,01,12,15,14,13,08,11,10,09,R1024_6,8*(R) + 7); \\\n\t\tR1024(00,15,02,11,06,13,04,09,14,01,08,05,10,03,12,07,R1024_7,8*(R) + 8); \\\n\t\tI1024(2*(R)+1);\n\n\t\tR1024_8_rounds( 0);\n\n#define R1024_Unroll_R(NN) ((SKEIN_UNROLL_1024 == 0 && SKEIN1024_ROUNDS_TOTAL/8 > (NN)) || (SKEIN_UNROLL_1024 > (NN)))\n\n  #if   R1024_Unroll_R( 1)\n\t\tR1024_8_rounds( 1);\n  #endif\n  #if   R1024_Unroll_R( 2)\n\t\tR1024_8_rounds( 2);\n  #endif\n  #if   R1024_Unroll_R( 3)\n\t\tR1024_8_rounds( 3);\n  #endif\n  #if   R1024_Unroll_R( 4)\n\t\tR1024_8_rounds( 4);\n  #endif\n  #if   R1024_Unroll_R( 5)\n\t\tR1024_8_rounds( 5);\n  #endif\n  #if   R1024_Unroll_R( 6)\n\t\tR1024_8_rounds( 6);\n  #endif\n  #if   R1024_Unroll_R( 7)\n\t\tR1024_8_rounds( 7);\n  #endif\n  #if   R1024_Unroll_R( 8)\n\t\tR1024_8_rounds( 8);\n  #endif\n  #if   R1024_Unroll_R( 9)\n\t\tR1024_8_rounds( 9);\n  #endif\n  #if   R1024_Unroll_R(10)\n\t\tR1024_8_rounds(10);\n  #endif\n  #if   R1024_Unroll_R(11)\n\t\tR1024_8_rounds(11);\n  #endif\n  #if   R1024_Unroll_R(12)\n\t\tR1024_8_rounds(12);\n  #endif\n  #if   R1024_Unroll_R(13)\n\t\tR1024_8_rounds(13);\n  #endif\n  #if   R1024_Unroll_R(14)\n\t\tR1024_8_rounds(14);\n  #endif\n  #if  (SKEIN_UNROLL_1024 > 14)\n#error  \"need more unrolling in Skein_1024_Process_Block\"\n  #endif\n\t\t}\n\t\t/* do the final \"feedforward\" xor, update context chaining vars */\n\n\t\tctx->X[ 0] = X00 ^ w[ 0];\n\t\tctx->X[ 1] = X01 ^ w[ 1];\n\t\tctx->X[ 2] = X02 ^ w[ 2];\n\t\tctx->X[ 3] = X03 ^ w[ 3];\n\t\tctx->X[ 4] = X04 ^ w[ 4];\n\t\tctx->X[ 5] = X05 ^ w[ 5];\n\t\tctx->X[ 6] = X06 ^ w[ 6];\n\t\tctx->X[ 7] = X07 ^ w[ 7];\n\t\tctx->X[ 8] = X08 ^ w[ 8];\n\t\tctx->X[ 9] = X09 ^ w[ 9];\n\t\tctx->X[10] = X10 ^ w[10];\n\t\tctx->X[11] = X11 ^ w[11];\n\t\tctx->X[12] = X12 ^ w[12];\n\t\tctx->X[13] = X13 ^ w[13];\n\t\tctx->X[14] = X14 ^ w[14];\n\t\tctx->X[15] = X15 ^ w[15];\n\n\t\tSkein_Show_Round(BLK_BITS,&ctx->h,SKEIN_RND_FEED_FWD,ctx->X);\n\t\t\n\t\tts[1] &= ~SKEIN_T1_FLAG_FIRST;\n\t\tblkPtr += SKEIN1024_BLOCK_BYTES;\n\t\t}\n\twhile (--blkCnt);\n\tctx->h.T[0] = ts[0];\n\tctx->h.T[1] = ts[1];\n\t}\n\n#if defined(SKEIN_CODE_SIZE) || defined(SKEIN_PERF)\nstatic size_t Skein1024_Process_Block_CodeSize(void)\n\t{\n\treturn ((u08b_t *) Skein1024_Process_Block_CodeSize) -\n\t\t   ((u08b_t *) Skein1024_Process_Block);\n\t}\nstatic uint_t Skein1024_Unroll_Cnt(void)\n\t{\n\treturn SKEIN_UNROLL_1024;\n\t}\n#endif\n#endif\n\n\n#if 0\n/*****************************************************************/\n/*     256-bit Skein                                             */\n/*****************************************************************/\n\n/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\n/* init the context for a straight hashing operation  */\nstatic int Skein_256_Init(Skein_256_Ctxt_t *ctx, size_t hashBitLen)\n\t{\n\tunion\n\t\t{\n\t\tu08b_t  b[SKEIN_256_STATE_BYTES];\n\t\tu64b_t  w[SKEIN_256_STATE_WORDS];\n\t\t} cfg;                              /* config block */\n\t\t\n\tSkein_Assert(hashBitLen > 0,SKEIN_BAD_HASHLEN);\n\tctx->h.hashBitLen = hashBitLen;         /* output hash bit count */\n\n\tswitch (hashBitLen)\n\t\t{             /* use pre-computed values, where available */\n#ifndef SKEIN_NO_PRECOMP\n\t\tcase  256: memcpy(ctx->X,SKEIN_256_IV_256,sizeof(ctx->X));  break;\n\t\tcase  224: memcpy(ctx->X,SKEIN_256_IV_224,sizeof(ctx->X));  break;\n\t\tcase  160: memcpy(ctx->X,SKEIN_256_IV_160,sizeof(ctx->X));  break;\n\t\tcase  128: memcpy(ctx->X,SKEIN_256_IV_128,sizeof(ctx->X));  break;\n#endif\n\t\tdefault:\n\t\t\t/* here if there is no precomputed IV value available */\n\t\t\t/* build/process the config block, type == CONFIG (could be precomputed) */\n\t\t\tSkein_Start_New_Type(ctx,CFG_FINAL);        /* set tweaks: T0=0; T1=CFG | FINAL */\n\n\t\t\tcfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER);  /* set the schema, version */\n\t\t\tcfg.w[1] = Skein_Swap64(hashBitLen);        /* hash result length in bits */\n\t\t\tcfg.w[2] = Skein_Swap64(SKEIN_CFG_TREE_INFO_SEQUENTIAL);\n\t\t\tmemset(&cfg.w[3],0,sizeof(cfg) - 3*sizeof(cfg.w[0])); /* zero pad config block */\n\n\t\t\t/* compute the initial chaining values from config block */\n\t\t\tmemset(ctx->X,0,sizeof(ctx->X));            /* zero the chaining variables */\n\t\t\tSkein_256_Process_Block(ctx,cfg.b,1,SKEIN_CFG_STR_LEN);\n\t\t\tbreak;\n\t\t}\n\t/* The chaining vars ctx->X are now initialized for the given hashBitLen. */\n\t/* Set up to process the data message portion of the hash (default) */\n\tSkein_Start_New_Type(ctx,MSG);              /* T0=0, T1= MSG type */\n\n\treturn SKEIN_SUCCESS;\n\t}\n\n/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\n/* init the context for a MAC and/or tree hash operation */\n/* [identical to Skein_256_Init() when keyBytes == 0 && treeInfo == SKEIN_CFG_TREE_INFO_SEQUENTIAL] */\nstatic int Skein_256_InitExt(Skein_256_Ctxt_t *ctx,size_t hashBitLen,u64b_t treeInfo, const u08b_t *key, size_t keyBytes)\n\t{\n\tunion\n\t\t{\n\t\tu08b_t  b[SKEIN_256_STATE_BYTES];\n\t\tu64b_t  w[SKEIN_256_STATE_WORDS];\n\t\t} cfg;                              /* config block */\n\t\t\n\tSkein_Assert(hashBitLen > 0,SKEIN_BAD_HASHLEN);\n\tSkein_Assert(keyBytes == 0 || key != NULL,SKEIN_FAIL);\n\n\t/* compute the initial chaining values ctx->X[], based on key */\n\tif (keyBytes == 0)                          /* is there a key? */\n\t\t{                                   \n\t\tmemset(ctx->X,0,sizeof(ctx->X));        /* no key: use all zeroes as key for config block */\n\t\t}\n\telse                                        /* here to pre-process a key */\n\t\t{\n\t\tSkein_assert(sizeof(cfg.b) >= sizeof(ctx->X));\n\t\t/* do a mini-Init right here */\n\t\tctx->h.hashBitLen=8*sizeof(ctx->X);     /* set output hash bit count = state size */\n\t\tSkein_Start_New_Type(ctx,KEY);          /* set tweaks: T0 = 0; T1 = KEY type */\n\t\tmemset(ctx->X,0,sizeof(ctx->X));        /* zero the initial chaining variables */\n\t\tSkein_256_Update(ctx,key,keyBytes);     /* hash the key */\n\t\tSkein_256_Final_Pad(ctx,cfg.b);         /* put result into cfg.b[] */\n\t\tmemcpy(ctx->X,cfg.b,sizeof(cfg.b));     /* copy over into ctx->X[] */\n#if SKEIN_NEED_SWAP\n\t\t{\n\t\tuint_t i;\n\t\tfor (i=0;i<SKEIN_256_STATE_WORDS;i++)   /* convert key bytes to context words */\n\t\t\tctx->X[i] = Skein_Swap64(ctx->X[i]);\n\t\t}\n#endif\n\t\t}\n\t/* build/process the config block, type == CONFIG (could be precomputed for each key) */\n\tctx->h.hashBitLen = hashBitLen;             /* output hash bit count */\n\tSkein_Start_New_Type(ctx,CFG_FINAL);\n\n\tmemset(&cfg.w,0,sizeof(cfg.w));             /* pre-pad cfg.w[] with zeroes */\n\tcfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER);\n\tcfg.w[1] = Skein_Swap64(hashBitLen);        /* hash result length in bits */\n\tcfg.w[2] = Skein_Swap64(treeInfo);          /* tree hash config info (or SKEIN_CFG_TREE_INFO_SEQUENTIAL) */\n\n\tSkein_Show_Key(256,&ctx->h,key,keyBytes);\n\n\t/* compute the initial chaining values from config block */\n\tSkein_256_Process_Block(ctx,cfg.b,1,SKEIN_CFG_STR_LEN);\n\n\t/* The chaining vars ctx->X are now initialized */\n\t/* Set up to process the data message portion of the hash (default) */\n\tctx->h.bCnt = 0;                            /* buffer b[] starts out empty */\n\tSkein_Start_New_Type(ctx,MSG);\n\t\n\treturn SKEIN_SUCCESS;\n\t}\n#endif\n\n/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\n/* process the input bytes */\nstatic int Skein_256_Update(Skein_256_Ctxt_t *ctx, const u08b_t *msg, size_t msgByteCnt)\n\t{\n\tsize_t n;\n\n\tSkein_Assert(ctx->h.bCnt <= SKEIN_256_BLOCK_BYTES,SKEIN_FAIL);    /* catch uninitialized context */\n\n\t/* process full blocks, if any */\n\tif (msgByteCnt + ctx->h.bCnt > SKEIN_256_BLOCK_BYTES)\n\t\t{\n\t\tif (ctx->h.bCnt)                              /* finish up any buffered message data */\n\t\t\t{\n\t\t\tn = SKEIN_256_BLOCK_BYTES - ctx->h.bCnt;  /* # bytes free in buffer b[] */\n\t\t\tif (n)\n\t\t\t\t{\n\t\t\t\tSkein_assert(n < msgByteCnt);         /* check on our logic here */\n\t\t\t\tmemcpy(&ctx->b[ctx->h.bCnt],msg,n);\n\t\t\t\tmsgByteCnt  -= n;\n\t\t\t\tmsg         += n;\n\t\t\t\tctx->h.bCnt += n;\n\t\t\t\t}\n\t\t\tSkein_assert(ctx->h.bCnt == SKEIN_256_BLOCK_BYTES);\n\t\t\tSkein_256_Process_Block(ctx,ctx->b,1,SKEIN_256_BLOCK_BYTES);\n\t\t\tctx->h.bCnt = 0;\n\t\t\t}\n\t\t/* now process any remaining full blocks, directly from input message data */\n\t\tif (msgByteCnt > SKEIN_256_BLOCK_BYTES)\n\t\t\t{\n\t\t\tn = (msgByteCnt-1) / SKEIN_256_BLOCK_BYTES;   /* number of full blocks to process */\n\t\t\tSkein_256_Process_Block(ctx,msg,n,SKEIN_256_BLOCK_BYTES);\n\t\t\tmsgByteCnt -= n * SKEIN_256_BLOCK_BYTES;\n\t\t\tmsg        += n * SKEIN_256_BLOCK_BYTES;\n\t\t\t}\n\t\tSkein_assert(ctx->h.bCnt == 0);\n\t\t}\n\n\t/* copy any remaining source message data bytes into b[] */\n\tif (msgByteCnt)\n\t\t{\n\t\tSkein_assert(msgByteCnt + ctx->h.bCnt <= SKEIN_256_BLOCK_BYTES);\n\t\tmemcpy(&ctx->b[ctx->h.bCnt],msg,msgByteCnt);\n\t\tctx->h.bCnt += msgByteCnt;\n\t\t}\n\n\treturn SKEIN_SUCCESS;\n\t}\n   \n/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\n/* finalize the hash computation and output the result */\nstatic int Skein_256_Final(Skein_256_Ctxt_t *ctx, u08b_t *hashVal)\n\t{\n\tsize_t i,n,byteCnt;\n\tu64b_t X[SKEIN_256_STATE_WORDS];\n\tSkein_Assert(ctx->h.bCnt <= SKEIN_256_BLOCK_BYTES,SKEIN_FAIL);    /* catch uninitialized context */\n\n\tctx->h.T[1] |= SKEIN_T1_FLAG_FINAL;                 /* tag as the final block */\n\tif (ctx->h.bCnt < SKEIN_256_BLOCK_BYTES)            /* zero pad b[] if necessary */\n\t\tmemset(&ctx->b[ctx->h.bCnt],0,SKEIN_256_BLOCK_BYTES - ctx->h.bCnt);\n\n\tSkein_256_Process_Block(ctx,ctx->b,1,ctx->h.bCnt);  /* process the final block */\n\t\n\t/* now output the result */\n\tbyteCnt = (ctx->h.hashBitLen + 7) >> 3;             /* total number of output bytes */\n\n\t/* run Threefish in \"counter mode\" to generate output */\n\tmemset(ctx->b,0,sizeof(ctx->b));  /* zero out b[], so it can hold the counter */\n\tmemcpy(X,ctx->X,sizeof(X));       /* keep a local copy of counter mode \"key\" */\n\tfor (i=0;i < byteCnt;i += SKEIN_256_BLOCK_BYTES)\n\t\t{\n\t\t((u64b_t *)ctx->b)[0]= Skein_Swap64((u64b_t) i); /* build the counter block */\n\t\tSkein_Start_New_Type(ctx,OUT_FINAL);\n\t\tSkein_256_Process_Block(ctx,ctx->b,1,sizeof(u64b_t)); /* run \"counter mode\" */\n\t\tn = byteCnt - i;   /* number of output bytes left to go */\n\t\tif (n >= SKEIN_256_BLOCK_BYTES)\n\t\t\tn  = SKEIN_256_BLOCK_BYTES;\n\t\tSkein_Put64_LSB_First(hashVal+i,ctx->X,n);   /* \"output\" the ctr mode bytes */\n\t\tSkein_Show_Final(256,&ctx->h,n,hashVal+i*SKEIN_256_BLOCK_BYTES);\n\t\tmemcpy(ctx->X,X,sizeof(X));   /* restore the counter mode key for next time */\n\t\t}\n\treturn SKEIN_SUCCESS;\n\t}\n\n#if defined(SKEIN_CODE_SIZE) || defined(SKEIN_PERF)\nstatic size_t Skein_256_API_CodeSize(void)\n\t{\n\treturn ((u08b_t *) Skein_256_API_CodeSize) -\n\t\t   ((u08b_t *) Skein_256_Init);\n\t}\n#endif\n\n/*****************************************************************/\n/*     512-bit Skein                                             */\n/*****************************************************************/\n\n/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\n/* init the context for a straight hashing operation  */\nstatic int Skein_512_Init(Skein_512_Ctxt_t *ctx, size_t hashBitLen)\n\t{\n\tunion\n\t\t{\n\t\tu08b_t  b[SKEIN_512_STATE_BYTES];\n\t\tu64b_t  w[SKEIN_512_STATE_WORDS];\n\t\t} cfg;                              /* config block */\n\t\t\n\tSkein_Assert(hashBitLen > 0,SKEIN_BAD_HASHLEN);\n\tctx->h.hashBitLen = hashBitLen;         /* output hash bit count */\n\n\tswitch (hashBitLen)\n\t\t{             /* use pre-computed values, where available */\n#ifndef SKEIN_NO_PRECOMP\n\t\tcase  512: memcpy(ctx->X,SKEIN_512_IV_512,sizeof(ctx->X));  break;\n\t\tcase  384: memcpy(ctx->X,SKEIN_512_IV_384,sizeof(ctx->X));  break;\n\t\tcase  256: memcpy(ctx->X,SKEIN_512_IV_256,sizeof(ctx->X));  break;\n\t\tcase  224: memcpy(ctx->X,SKEIN_512_IV_224,sizeof(ctx->X));  break;\n#endif\n\t\tdefault:\n\t\t\t/* here if there is no precomputed IV value available */\n\t\t\t/* build/process the config block, type == CONFIG (could be precomputed) */\n\t\t\tSkein_Start_New_Type(ctx,CFG_FINAL);        /* set tweaks: T0=0; T1=CFG | FINAL */\n\n\t\t\tcfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER);  /* set the schema, version */\n\t\t\tcfg.w[1] = Skein_Swap64(hashBitLen);        /* hash result length in bits */\n\t\t\tcfg.w[2] = Skein_Swap64(SKEIN_CFG_TREE_INFO_SEQUENTIAL);\n\t\t\tmemset(&cfg.w[3],0,sizeof(cfg) - 3*sizeof(cfg.w[0])); /* zero pad config block */\n\n\t\t\t/* compute the initial chaining values from config block */\n\t\t\tmemset(ctx->X,0,sizeof(ctx->X));            /* zero the chaining variables */\n\t\t\tSkein_512_Process_Block(ctx,cfg.b,1,SKEIN_CFG_STR_LEN);\n\t\t\tbreak;\n\t\t}\n\n\t/* The chaining vars ctx->X are now initialized for the given hashBitLen. */\n\t/* Set up to process the data message portion of the hash (default) */\n\tSkein_Start_New_Type(ctx,MSG);              /* T0=0, T1= MSG type */\n\n\treturn SKEIN_SUCCESS;\n\t}\n\n#if 0\n/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\n/* init the context for a MAC and/or tree hash operation */\n/* [identical to Skein_512_Init() when keyBytes == 0 && treeInfo == SKEIN_CFG_TREE_INFO_SEQUENTIAL] */\nstatic int Skein_512_InitExt(Skein_512_Ctxt_t *ctx,size_t hashBitLen,u64b_t treeInfo, const u08b_t *key, size_t keyBytes)\n\t{\n\tunion\n\t\t{\n\t\tu08b_t  b[SKEIN_512_STATE_BYTES];\n\t\tu64b_t  w[SKEIN_512_STATE_WORDS];\n\t\t} cfg;                              /* config block */\n\t\t\n\tSkein_Assert(hashBitLen > 0,SKEIN_BAD_HASHLEN);\n\tSkein_Assert(keyBytes == 0 || key != NULL,SKEIN_FAIL);\n\n\t/* compute the initial chaining values ctx->X[], based on key */\n\tif (keyBytes == 0)                          /* is there a key? */\n\t\t{                                   \n\t\tmemset(ctx->X,0,sizeof(ctx->X));        /* no key: use all zeroes as key for config block */\n\t\t}\n\telse                                        /* here to pre-process a key */\n\t\t{\n\t\tSkein_assert(sizeof(cfg.b) >= sizeof(ctx->X));\n\t\t/* do a mini-Init right here */\n\t\tctx->h.hashBitLen=8*sizeof(ctx->X);     /* set output hash bit count = state size */\n\t\tSkein_Start_New_Type(ctx,KEY);          /* set tweaks: T0 = 0; T1 = KEY type */\n\t\tmemset(ctx->X,0,sizeof(ctx->X));        /* zero the initial chaining variables */\n\t\tSkein_512_Update(ctx,key,keyBytes);     /* hash the key */\n\t\tSkein_512_Final_Pad(ctx,cfg.b);         /* put result into cfg.b[] */\n\t\tmemcpy(ctx->X,cfg.b,sizeof(cfg.b));     /* copy over into ctx->X[] */\n#if SKEIN_NEED_SWAP\n\t\t{\n\t\tuint_t i;\n\t\tfor (i=0;i<SKEIN_512_STATE_WORDS;i++)   /* convert key bytes to context words */\n\t\t\tctx->X[i] = Skein_Swap64(ctx->X[i]);\n\t\t}\n#endif\n\t\t}\n\t/* build/process the config block, type == CONFIG (could be precomputed for each key) */\n\tctx->h.hashBitLen = hashBitLen;             /* output hash bit count */\n\tSkein_Start_New_Type(ctx,CFG_FINAL);\n\n\tmemset(&cfg.w,0,sizeof(cfg.w));             /* pre-pad cfg.w[] with zeroes */\n\tcfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER);\n\tcfg.w[1] = Skein_Swap64(hashBitLen);        /* hash result length in bits */\n\tcfg.w[2] = Skein_Swap64(treeInfo);          /* tree hash config info (or SKEIN_CFG_TREE_INFO_SEQUENTIAL) */\n\n\tSkein_Show_Key(512,&ctx->h,key,keyBytes);\n\n\t/* compute the initial chaining values from config block */\n\tSkein_512_Process_Block(ctx,cfg.b,1,SKEIN_CFG_STR_LEN);\n\n\t/* The chaining vars ctx->X are now initialized */\n\t/* Set up to process the data message portion of the hash (default) */\n\tctx->h.bCnt = 0;                            /* buffer b[] starts out empty */\n\tSkein_Start_New_Type(ctx,MSG);\n\t\n\treturn SKEIN_SUCCESS;\n\t}\n#endif\n\n/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\n/* process the input bytes */\nstatic int Skein_512_Update(Skein_512_Ctxt_t *ctx, const u08b_t *msg, size_t msgByteCnt)\n\t{\n\tsize_t n;\n\n\tSkein_Assert(ctx->h.bCnt <= SKEIN_512_BLOCK_BYTES,SKEIN_FAIL);    /* catch uninitialized context */\n\n\t/* process full blocks, if any */\n\tif (msgByteCnt + ctx->h.bCnt > SKEIN_512_BLOCK_BYTES)\n\t\t{\n\t\tif (ctx->h.bCnt)                              /* finish up any buffered message data */\n\t\t\t{\n\t\t\tn = SKEIN_512_BLOCK_BYTES - ctx->h.bCnt;  /* # bytes free in buffer b[] */\n\t\t\tif (n)\n\t\t\t\t{\n\t\t\t\tSkein_assert(n < msgByteCnt);         /* check on our logic here */\n\t\t\t\tmemcpy(&ctx->b[ctx->h.bCnt],msg,n);\n\t\t\t\tmsgByteCnt  -= n;\n\t\t\t\tmsg         += n;\n\t\t\t\tctx->h.bCnt += n;\n\t\t\t\t}\n\t\t\tSkein_assert(ctx->h.bCnt == SKEIN_512_BLOCK_BYTES);\n\t\t\tSkein_512_Process_Block(ctx,ctx->b,1,SKEIN_512_BLOCK_BYTES);\n\t\t\tctx->h.bCnt = 0;\n\t\t\t}\n\t\t/* now process any remaining full blocks, directly from input message data */\n\t\tif (msgByteCnt > SKEIN_512_BLOCK_BYTES)\n\t\t\t{\n\t\t\tn = (msgByteCnt-1) / SKEIN_512_BLOCK_BYTES;   /* number of full blocks to process */\n\t\t\tSkein_512_Process_Block(ctx,msg,n,SKEIN_512_BLOCK_BYTES);\n\t\t\tmsgByteCnt -= n * SKEIN_512_BLOCK_BYTES;\n\t\t\tmsg        += n * SKEIN_512_BLOCK_BYTES;\n\t\t\t}\n\t\tSkein_assert(ctx->h.bCnt == 0);\n\t\t}\n\n\t/* copy any remaining source message data bytes into b[] */\n\tif (msgByteCnt)\n\t\t{\n\t\tSkein_assert(msgByteCnt + ctx->h.bCnt <= SKEIN_512_BLOCK_BYTES);\n\t\tmemcpy(&ctx->b[ctx->h.bCnt],msg,msgByteCnt);\n\t\tctx->h.bCnt += msgByteCnt;\n\t\t}\n\n\treturn SKEIN_SUCCESS;\n\t}\n   \n/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\n/* finalize the hash computation and output the result */\nstatic int Skein_512_Final(Skein_512_Ctxt_t *ctx, u08b_t *hashVal)\n\t{\n\tsize_t i,n,byteCnt;\n\tu64b_t X[SKEIN_512_STATE_WORDS];\n\tSkein_Assert(ctx->h.bCnt <= SKEIN_512_BLOCK_BYTES,SKEIN_FAIL);    /* catch uninitialized context */\n\n\tctx->h.T[1] |= SKEIN_T1_FLAG_FINAL;                 /* tag as the final block */\n\tif (ctx->h.bCnt < SKEIN_512_BLOCK_BYTES)            /* zero pad b[] if necessary */\n\t\tmemset(&ctx->b[ctx->h.bCnt],0,SKEIN_512_BLOCK_BYTES - ctx->h.bCnt);\n\n\tSkein_512_Process_Block(ctx,ctx->b,1,ctx->h.bCnt);  /* process the final block */\n\t\n\t/* now output the result */\n\tbyteCnt = (ctx->h.hashBitLen + 7) >> 3;             /* total number of output bytes */\n\n\t/* run Threefish in \"counter mode\" to generate output */\n\tmemset(ctx->b,0,sizeof(ctx->b));  /* zero out b[], so it can hold the counter */\n\tmemcpy(X,ctx->X,sizeof(X));       /* keep a local copy of counter mode \"key\" */\n\tfor (i=0;i*SKEIN_512_BLOCK_BYTES < byteCnt;i++)\n\t\t{\n\t\t((u64b_t *)ctx->b)[0]= Skein_Swap64((u64b_t) i); /* build the counter block */\n\t\tSkein_Start_New_Type(ctx,OUT_FINAL);\n\t\tSkein_512_Process_Block(ctx,ctx->b,1,sizeof(u64b_t)); /* run \"counter mode\" */\n\t\tn = byteCnt - i*SKEIN_512_BLOCK_BYTES;   /* number of output bytes left to go */\n\t\tif (n >= SKEIN_512_BLOCK_BYTES)\n\t\t\tn  = SKEIN_512_BLOCK_BYTES;\n\t\tSkein_Put64_LSB_First(hashVal+i*SKEIN_512_BLOCK_BYTES,ctx->X,n);   /* \"output\" the ctr mode bytes */\n\t\tSkein_Show_Final(512,&ctx->h,n,hashVal+i*SKEIN_512_BLOCK_BYTES);\n\t\tmemcpy(ctx->X,X,sizeof(X));   /* restore the counter mode key for next time */\n\t\t}\n\treturn SKEIN_SUCCESS;\n\t}\n\n#if defined(SKEIN_CODE_SIZE) || defined(SKEIN_PERF)\nstatic size_t Skein_512_API_CodeSize(void)\n\t{\n\treturn ((u08b_t *) Skein_512_API_CodeSize) -\n\t\t   ((u08b_t *) Skein_512_Init);\n\t}\n#endif\n\n/*****************************************************************/\n/*    1024-bit Skein                                             */\n/*****************************************************************/\n/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\n/* init the context for a straight hashing operation  */\nstatic int Skein1024_Init(Skein1024_Ctxt_t *ctx, size_t hashBitLen)\n\t{\n\tunion\n\t\t{\n\t\tu08b_t  b[SKEIN1024_STATE_BYTES];\n\t\tu64b_t  w[SKEIN1024_STATE_WORDS];\n\t\t} cfg;                              /* config block */\n\t\t\n\tSkein_Assert(hashBitLen > 0,SKEIN_BAD_HASHLEN);\n\tctx->h.hashBitLen = hashBitLen;         /* output hash bit count */\n\n\tswitch (hashBitLen)\n\t\t{              /* use pre-computed values, where available */\n#ifndef SKEIN_NO_PRECOMP\n\t\tcase  512: memcpy(ctx->X,SKEIN1024_IV_512 ,sizeof(ctx->X)); break;\n\t\tcase  384: memcpy(ctx->X,SKEIN1024_IV_384 ,sizeof(ctx->X)); break;\n\t\tcase 1024: memcpy(ctx->X,SKEIN1024_IV_1024,sizeof(ctx->X)); break;\n#endif\n\t\tdefault:\n\t\t\t/* here if there is no precomputed IV value available */\n\t\t\t/* build/process the config block, type == CONFIG (could be precomputed) */\n\t\t\tSkein_Start_New_Type(ctx,CFG_FINAL);        /* set tweaks: T0=0; T1=CFG | FINAL */\n\n\t\t\tcfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER);  /* set the schema, version */\n\t\t\tcfg.w[1] = Skein_Swap64(hashBitLen);        /* hash result length in bits */\n\t\t\tcfg.w[2] = Skein_Swap64(SKEIN_CFG_TREE_INFO_SEQUENTIAL);\n\t\t\tmemset(&cfg.w[3],0,sizeof(cfg) - 3*sizeof(cfg.w[0])); /* zero pad config block */\n\n\t\t\t/* compute the initial chaining values from config block */\n\t\t\tmemset(ctx->X,0,sizeof(ctx->X));            /* zero the chaining variables */\n\t\t\tSkein1024_Process_Block(ctx,cfg.b,1,SKEIN_CFG_STR_LEN);\n\t\t\tbreak;\n\t\t}\n\n\t/* The chaining vars ctx->X are now initialized for the given hashBitLen. */\n\t/* Set up to process the data message portion of the hash (default) */\n\tSkein_Start_New_Type(ctx,MSG);              /* T0=0, T1= MSG type */\n\n\treturn SKEIN_SUCCESS;\n\t}\n\n#if 0\n/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\n/* init the context for a MAC and/or tree hash operation */\n/* [identical to Skein1024_Init() when keyBytes == 0 && treeInfo == SKEIN_CFG_TREE_INFO_SEQUENTIAL] */\nstatic int Skein1024_InitExt(Skein1024_Ctxt_t *ctx,size_t hashBitLen,u64b_t treeInfo, const u08b_t *key, size_t keyBytes)\n\t{\n\tunion\n\t\t{\n\t\tu08b_t  b[SKEIN1024_STATE_BYTES];\n\t\tu64b_t  w[SKEIN1024_STATE_WORDS];\n\t\t} cfg;                              /* config block */\n\t\t\n\tSkein_Assert(hashBitLen > 0,SKEIN_BAD_HASHLEN);\n\tSkein_Assert(keyBytes == 0 || key != NULL,SKEIN_FAIL);\n\n\t/* compute the initial chaining values ctx->X[], based on key */\n\tif (keyBytes == 0)                          /* is there a key? */\n\t\t{                                   \n\t\tmemset(ctx->X,0,sizeof(ctx->X));        /* no key: use all zeroes as key for config block */\n\t\t}\n\telse                                        /* here to pre-process a key */\n\t\t{\n\t\tSkein_assert(sizeof(cfg.b) >= sizeof(ctx->X));\n\t\t/* do a mini-Init right here */\n\t\tctx->h.hashBitLen=8*sizeof(ctx->X);     /* set output hash bit count = state size */\n\t\tSkein_Start_New_Type(ctx,KEY);          /* set tweaks: T0 = 0; T1 = KEY type */\n\t\tmemset(ctx->X,0,sizeof(ctx->X));        /* zero the initial chaining variables */\n\t\tSkein1024_Update(ctx,key,keyBytes);     /* hash the key */\n\t\tSkein1024_Final_Pad(ctx,cfg.b);         /* put result into cfg.b[] */\n\t\tmemcpy(ctx->X,cfg.b,sizeof(cfg.b));     /* copy over into ctx->X[] */\n#if SKEIN_NEED_SWAP\n\t\t{\n\t\tuint_t i;\n\t\tfor (i=0;i<SKEIN1024_STATE_WORDS;i++)   /* convert key bytes to context words */\n\t\t\tctx->X[i] = Skein_Swap64(ctx->X[i]);\n\t\t}\n#endif\n\t\t}\n\t/* build/process the config block, type == CONFIG (could be precomputed for each key) */\n\tctx->h.hashBitLen = hashBitLen;             /* output hash bit count */\n\tSkein_Start_New_Type(ctx,CFG_FINAL);\n\n\tmemset(&cfg.w,0,sizeof(cfg.w));             /* pre-pad cfg.w[] with zeroes */\n\tcfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER);\n\tcfg.w[1] = Skein_Swap64(hashBitLen);        /* hash result length in bits */\n\tcfg.w[2] = Skein_Swap64(treeInfo);          /* tree hash config info (or SKEIN_CFG_TREE_INFO_SEQUENTIAL) */\n\n\tSkein_Show_Key(1024,&ctx->h,key,keyBytes);\n\n\t/* compute the initial chaining values from config block */\n\tSkein1024_Process_Block(ctx,cfg.b,1,SKEIN_CFG_STR_LEN);\n\n\t/* The chaining vars ctx->X are now initialized */\n\t/* Set up to process the data message portion of the hash (default) */\n\tctx->h.bCnt = 0;                            /* buffer b[] starts out empty */\n\tSkein_Start_New_Type(ctx,MSG);\n\t\n\treturn SKEIN_SUCCESS;\n\t}\n#endif\n\n/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\n/* process the input bytes */\nstatic int Skein1024_Update(Skein1024_Ctxt_t *ctx, const u08b_t *msg, size_t msgByteCnt)\n\t{\n\tsize_t n;\n\n\tSkein_Assert(ctx->h.bCnt <= SKEIN1024_BLOCK_BYTES,SKEIN_FAIL);    /* catch uninitialized context */\n\n\t/* process full blocks, if any */\n\tif (msgByteCnt + ctx->h.bCnt > SKEIN1024_BLOCK_BYTES)\n\t\t{\n\t\tif (ctx->h.bCnt)                              /* finish up any buffered message data */\n\t\t\t{\n\t\t\tn = SKEIN1024_BLOCK_BYTES - ctx->h.bCnt;  /* # bytes free in buffer b[] */\n\t\t\tif (n)\n\t\t\t\t{\n\t\t\t\tSkein_assert(n < msgByteCnt);         /* check on our logic here */\n\t\t\t\tmemcpy(&ctx->b[ctx->h.bCnt],msg,n);\n\t\t\t\tmsgByteCnt  -= n;\n\t\t\t\tmsg         += n;\n\t\t\t\tctx->h.bCnt += n;\n\t\t\t\t}\n\t\t\tSkein_assert(ctx->h.bCnt == SKEIN1024_BLOCK_BYTES);\n\t\t\tSkein1024_Process_Block(ctx,ctx->b,1,SKEIN1024_BLOCK_BYTES);\n\t\t\tctx->h.bCnt = 0;\n\t\t\t}\n\t\t/* now process any remaining full blocks, directly from input message data */\n\t\tif (msgByteCnt > SKEIN1024_BLOCK_BYTES)\n\t\t\t{\n\t\t\tn = (msgByteCnt-1) / SKEIN1024_BLOCK_BYTES;   /* number of full blocks to process */\n\t\t\tSkein1024_Process_Block(ctx,msg,n,SKEIN1024_BLOCK_BYTES);\n\t\t\tmsgByteCnt -= n * SKEIN1024_BLOCK_BYTES;\n\t\t\tmsg        += n * SKEIN1024_BLOCK_BYTES;\n\t\t\t}\n\t\tSkein_assert(ctx->h.bCnt == 0);\n\t\t}\n\n\t/* copy any remaining source message data bytes into b[] */\n\tif (msgByteCnt)\n\t\t{\n\t\tSkein_assert(msgByteCnt + ctx->h.bCnt <= SKEIN1024_BLOCK_BYTES);\n\t\tmemcpy(&ctx->b[ctx->h.bCnt],msg,msgByteCnt);\n\t\tctx->h.bCnt += msgByteCnt;\n\t\t}\n\n\treturn SKEIN_SUCCESS;\n\t}\n   \n/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\n/* finalize the hash computation and output the result */\nstatic int Skein1024_Final(Skein1024_Ctxt_t *ctx, u08b_t *hashVal)\n\t{\n\tsize_t i,n,byteCnt;\n\tu64b_t X[SKEIN1024_STATE_WORDS];\n\tSkein_Assert(ctx->h.bCnt <= SKEIN1024_BLOCK_BYTES,SKEIN_FAIL);    /* catch uninitialized context */\n\n\tctx->h.T[1] |= SKEIN_T1_FLAG_FINAL;                 /* tag as the final block */\n\tif (ctx->h.bCnt < SKEIN1024_BLOCK_BYTES)            /* zero pad b[] if necessary */\n\t\tmemset(&ctx->b[ctx->h.bCnt],0,SKEIN1024_BLOCK_BYTES - ctx->h.bCnt);\n\n\tSkein1024_Process_Block(ctx,ctx->b,1,ctx->h.bCnt);  /* process the final block */\n\t\n\t/* now output the result */\n\tbyteCnt = (ctx->h.hashBitLen + 7) >> 3;             /* total number of output bytes */\n\n\t/* run Threefish in \"counter mode\" to generate output */\n\tmemset(ctx->b,0,sizeof(ctx->b));  /* zero out b[], so it can hold the counter */\n\tmemcpy(X,ctx->X,sizeof(X));       /* keep a local copy of counter mode \"key\" */\n\tfor (i=0;i*SKEIN1024_BLOCK_BYTES < byteCnt;i++)\n\t\t{\n\t\t((u64b_t *)ctx->b)[0]= Skein_Swap64((u64b_t) i); /* build the counter block */\n\t\tSkein_Start_New_Type(ctx,OUT_FINAL);\n\t\tSkein1024_Process_Block(ctx,ctx->b,1,sizeof(u64b_t)); /* run \"counter mode\" */\n\t\tn = byteCnt - i*SKEIN1024_BLOCK_BYTES;   /* number of output bytes left to go */\n\t\tif (n >= SKEIN1024_BLOCK_BYTES)\n\t\t\tn  = SKEIN1024_BLOCK_BYTES;\n\t\tSkein_Put64_LSB_First(hashVal+i*SKEIN1024_BLOCK_BYTES,ctx->X,n);   /* \"output\" the ctr mode bytes */\n\t\tSkein_Show_Final(1024,&ctx->h,n,hashVal+i*SKEIN1024_BLOCK_BYTES);\n\t\tmemcpy(ctx->X,X,sizeof(X));   /* restore the counter mode key for next time */\n\t\t}\n\treturn SKEIN_SUCCESS;\n\t}\n\n#if defined(SKEIN_CODE_SIZE) || defined(SKEIN_PERF)\nstatic size_t Skein1024_API_CodeSize(void)\n\t{\n\treturn ((u08b_t *) Skein1024_API_CodeSize) -\n\t\t   ((u08b_t *) Skein1024_Init);\n\t}\n#endif\n\n/**************** Functions to support MAC/tree hashing ***************/\n/*   (this code is identical for Optimized and Reference versions)    */\n\n#if 0\n/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\n/* finalize the hash computation and output the block, no OUTPUT stage */\nstatic int Skein_256_Final_Pad(Skein_256_Ctxt_t *ctx, u08b_t *hashVal)\n\t{\n\tSkein_Assert(ctx->h.bCnt <= SKEIN_256_BLOCK_BYTES,SKEIN_FAIL);    /* catch uninitialized context */\n\n\tctx->h.T[1] |= SKEIN_T1_FLAG_FINAL;        /* tag as the final block */\n\tif (ctx->h.bCnt < SKEIN_256_BLOCK_BYTES)   /* zero pad b[] if necessary */\n\t\tmemset(&ctx->b[ctx->h.bCnt],0,SKEIN_256_BLOCK_BYTES - ctx->h.bCnt);\n\tSkein_256_Process_Block(ctx,ctx->b,1,ctx->h.bCnt);    /* process the final block */\n\t\n\tSkein_Put64_LSB_First(hashVal,ctx->X,SKEIN_256_BLOCK_BYTES);   /* \"output\" the state bytes */\n\t\n\treturn SKEIN_SUCCESS;\n\t}\n\n/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\n/* finalize the hash computation and output the block, no OUTPUT stage */\nstatic int Skein_512_Final_Pad(Skein_512_Ctxt_t *ctx, u08b_t *hashVal)\n\t{\n\tSkein_Assert(ctx->h.bCnt <= SKEIN_512_BLOCK_BYTES,SKEIN_FAIL);    /* catch uninitialized context */\n\n\tctx->h.T[1] |= SKEIN_T1_FLAG_FINAL;        /* tag as the final block */\n\tif (ctx->h.bCnt < SKEIN_512_BLOCK_BYTES)   /* zero pad b[] if necessary */\n\t\tmemset(&ctx->b[ctx->h.bCnt],0,SKEIN_512_BLOCK_BYTES - ctx->h.bCnt);\n\tSkein_512_Process_Block(ctx,ctx->b,1,ctx->h.bCnt);    /* process the final block */\n\t\n\tSkein_Put64_LSB_First(hashVal,ctx->X,SKEIN_512_BLOCK_BYTES);   /* \"output\" the state bytes */\n\t\n\treturn SKEIN_SUCCESS;\n\t}\n\n/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\n/* finalize the hash computation and output the block, no OUTPUT stage */\nstatic int Skein1024_Final_Pad(Skein1024_Ctxt_t *ctx, u08b_t *hashVal)\n\t{\n\tSkein_Assert(ctx->h.bCnt <= SKEIN1024_BLOCK_BYTES,SKEIN_FAIL);    /* catch uninitialized context */\n\n\tctx->h.T[1] |= SKEIN_T1_FLAG_FINAL;        /* tag as the final block */\n\tif (ctx->h.bCnt < SKEIN1024_BLOCK_BYTES)   /* zero pad b[] if necessary */\n\t\tmemset(&ctx->b[ctx->h.bCnt],0,SKEIN1024_BLOCK_BYTES - ctx->h.bCnt);\n\tSkein1024_Process_Block(ctx,ctx->b,1,ctx->h.bCnt);    /* process the final block */\n\t\n\tSkein_Put64_LSB_First(hashVal,ctx->X,SKEIN1024_BLOCK_BYTES);   /* \"output\" the state bytes */\n\t\n\treturn SKEIN_SUCCESS;\n\t}\n\n\n#if SKEIN_TREE_HASH\n/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\n/* just do the OUTPUT stage                                       */\nstatic int Skein_256_Output(Skein_256_Ctxt_t *ctx, u08b_t *hashVal)\n\t{\n\tsize_t i,n,byteCnt;\n\tu64b_t X[SKEIN_256_STATE_WORDS];\n\tSkein_Assert(ctx->h.bCnt <= SKEIN_256_BLOCK_BYTES,SKEIN_FAIL);    /* catch uninitialized context */\n\n\t/* now output the result */\n\tbyteCnt = (ctx->h.hashBitLen + 7) >> 3;    /* total number of output bytes */\n\n\t/* run Threefish in \"counter mode\" to generate output */\n\tmemset(ctx->b,0,sizeof(ctx->b));  /* zero out b[], so it can hold the counter */\n\tmemcpy(X,ctx->X,sizeof(X));       /* keep a local copy of counter mode \"key\" */\n\tfor (i=0;i*SKEIN_256_BLOCK_BYTES < byteCnt;i++)\n\t\t{\n\t\t((u64b_t *)ctx->b)[0]= Skein_Swap64((u64b_t) i); /* build the counter block */\n\t\tSkein_Start_New_Type(ctx,OUT_FINAL);\n\t\tSkein_256_Process_Block(ctx,ctx->b,1,sizeof(u64b_t)); /* run \"counter mode\" */\n\t\tn = byteCnt - i*SKEIN_256_BLOCK_BYTES;   /* number of output bytes left to go */\n\t\tif (n >= SKEIN_256_BLOCK_BYTES)\n\t\t\tn  = SKEIN_256_BLOCK_BYTES;\n\t\tSkein_Put64_LSB_First(hashVal+i*SKEIN_256_BLOCK_BYTES,ctx->X,n);   /* \"output\" the ctr mode bytes */\n\t\tSkein_Show_Final(256,&ctx->h,n,hashVal+i*SKEIN_256_BLOCK_BYTES);\n\t\tmemcpy(ctx->X,X,sizeof(X));   /* restore the counter mode key for next time */\n\t\t}\n\treturn SKEIN_SUCCESS;\n\t}\n\n/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\n/* just do the OUTPUT stage                                       */\nstatic int Skein_512_Output(Skein_512_Ctxt_t *ctx, u08b_t *hashVal)\n\t{\n\tsize_t i,n,byteCnt;\n\tu64b_t X[SKEIN_512_STATE_WORDS];\n\tSkein_Assert(ctx->h.bCnt <= SKEIN_512_BLOCK_BYTES,SKEIN_FAIL);    /* catch uninitialized context */\n\n\t/* now output the result */\n\tbyteCnt = (ctx->h.hashBitLen + 7) >> 3;    /* total number of output bytes */\n\n\t/* run Threefish in \"counter mode\" to generate output */\n\tmemset(ctx->b,0,sizeof(ctx->b));  /* zero out b[], so it can hold the counter */\n\tmemcpy(X,ctx->X,sizeof(X));       /* keep a local copy of counter mode \"key\" */\n\tfor (i=0;i*SKEIN_512_BLOCK_BYTES < byteCnt;i++)\n\t\t{\n\t\t((u64b_t *)ctx->b)[0]= Skein_Swap64((u64b_t) i); /* build the counter block */\n\t\tSkein_Start_New_Type(ctx,OUT_FINAL);\n\t\tSkein_512_Process_Block(ctx,ctx->b,1,sizeof(u64b_t)); /* run \"counter mode\" */\n\t\tn = byteCnt - i*SKEIN_512_BLOCK_BYTES;   /* number of output bytes left to go */\n\t\tif (n >= SKEIN_512_BLOCK_BYTES)\n\t\t\tn  = SKEIN_512_BLOCK_BYTES;\n\t\tSkein_Put64_LSB_First(hashVal+i*SKEIN_512_BLOCK_BYTES,ctx->X,n);   /* \"output\" the ctr mode bytes */\n\t\tSkein_Show_Final(256,&ctx->h,n,hashVal+i*SKEIN_512_BLOCK_BYTES);\n\t\tmemcpy(ctx->X,X,sizeof(X));   /* restore the counter mode key for next time */\n\t\t}\n\treturn SKEIN_SUCCESS;\n\t}\n\n/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\n/* just do the OUTPUT stage                                       */\nstatic int Skein1024_Output(Skein1024_Ctxt_t *ctx, u08b_t *hashVal)\n\t{\n\tsize_t i,n,byteCnt;\n\tu64b_t X[SKEIN1024_STATE_WORDS];\n\tSkein_Assert(ctx->h.bCnt <= SKEIN1024_BLOCK_BYTES,SKEIN_FAIL);    /* catch uninitialized context */\n\n\t/* now output the result */\n\tbyteCnt = (ctx->h.hashBitLen + 7) >> 3;    /* total number of output bytes */\n\n\t/* run Threefish in \"counter mode\" to generate output */\n\tmemset(ctx->b,0,sizeof(ctx->b));  /* zero out b[], so it can hold the counter */\n\tmemcpy(X,ctx->X,sizeof(X));       /* keep a local copy of counter mode \"key\" */\n\tfor (i=0;i*SKEIN1024_BLOCK_BYTES < byteCnt;i++)\n\t\t{\n\t\t((u64b_t *)ctx->b)[0]= Skein_Swap64((u64b_t) i); /* build the counter block */\n\t\tSkein_Start_New_Type(ctx,OUT_FINAL);\n\t\tSkein1024_Process_Block(ctx,ctx->b,1,sizeof(u64b_t)); /* run \"counter mode\" */\n\t\tn = byteCnt - i*SKEIN1024_BLOCK_BYTES;   /* number of output bytes left to go */\n\t\tif (n >= SKEIN1024_BLOCK_BYTES)\n\t\t\tn  = SKEIN1024_BLOCK_BYTES;\n\t\tSkein_Put64_LSB_First(hashVal+i*SKEIN1024_BLOCK_BYTES,ctx->X,n);   /* \"output\" the ctr mode bytes */\n\t\tSkein_Show_Final(256,&ctx->h,n,hashVal+i*SKEIN1024_BLOCK_BYTES);\n\t\tmemcpy(ctx->X,X,sizeof(X));   /* restore the counter mode key for next time */\n\t\t}\n\treturn SKEIN_SUCCESS;\n\t}\n#endif\n#endif\n\ntypedef struct\n{\n  uint_t  statebits;                      /* 256, 512, or 1024 */\n  union\n  {\n\tSkein_Ctxt_Hdr_t h;                 /* common header \"overlay\" */\n\tSkein_256_Ctxt_t ctx_256;\n\tSkein_512_Ctxt_t ctx_512;\n\tSkein1024_Ctxt_t ctx1024;\n  } u;\n}\nhashState;\n\n/* \"incremental\" hashing API */\nstatic SkeinHashReturn Init  (hashState *state, int hashbitlen);\nstatic SkeinHashReturn Update(hashState *state, const SkeinBitSequence *data, SkeinDataLength databitlen);\nstatic SkeinHashReturn Final (hashState *state,       SkeinBitSequence *hashval);\n\n/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\n/* select the context size and init the context */\nstatic SkeinHashReturn Init(hashState *state, int hashbitlen)\n{\n#if SKEIN_256_NIST_MAX_HASH_BITS\n  if (hashbitlen <= SKEIN_256_NIST_MAX_HASHBITS)\n  {\n\tSkein_Assert(hashbitlen > 0,BAD_HASHLEN);\n\tstate->statebits = 64*SKEIN_256_STATE_WORDS;\n\treturn Skein_256_Init(&state->u.ctx_256,(size_t) hashbitlen);\n  }\n#endif\n  if (hashbitlen <= SKEIN_512_NIST_MAX_HASHBITS)\n  {\n\tstate->statebits = 64*SKEIN_512_STATE_WORDS;\n\treturn Skein_512_Init(&state->u.ctx_512,(size_t) hashbitlen);\n  }\n  else\n  {\n\tstate->statebits = 64*SKEIN1024_STATE_WORDS;\n\treturn Skein1024_Init(&state->u.ctx1024,(size_t) hashbitlen);\n  }\n}\n\n/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\n/* process data to be hashed */\nstatic SkeinHashReturn Update(hashState *state, const SkeinBitSequence *data, SkeinDataLength databitlen)\n{\n  /* only the final Update() call is allowed do partial bytes, else assert an error */\n  Skein_Assert((state->u.h.T[1] & SKEIN_T1_FLAG_BIT_PAD) == 0 || databitlen == 0, SKEIN_FAIL);\n\n  Skein_Assert(state->statebits % 256 == 0 && (state->statebits-256) < 1024,SKEIN_FAIL);\n  if ((databitlen & 7) == 0)  /* partial bytes? */\n  {\n\tswitch ((state->statebits >> 8) & 3)\n\t{\n\tcase 2:  return Skein_512_Update(&state->u.ctx_512,data,databitlen >> 3);\n\tcase 1:  return Skein_256_Update(&state->u.ctx_256,data,databitlen >> 3);\n\tcase 0:  return Skein1024_Update(&state->u.ctx1024,data,databitlen >> 3);\n\tdefault: return SKEIN_FAIL;\n\t}\n  }\n  else\n  {   /* handle partial final byte */\n\tsize_t bCnt = (databitlen >> 3) + 1;                  /* number of bytes to handle (nonzero here!) */\n\tu08b_t b,mask;\n\n\tmask = (u08b_t) (1u << (7 - (databitlen & 7)));       /* partial byte bit mask */\n\tb    = (u08b_t) ((data[bCnt-1] & (0-mask)) | mask);   /* apply bit padding on final byte */\n\n\tswitch ((state->statebits >> 8) & 3)\n\t{\n\tcase 2:  Skein_512_Update(&state->u.ctx_512,data,bCnt-1); /* process all but the final byte    */\n\t  Skein_512_Update(&state->u.ctx_512,&b  ,  1   ); /* process the (masked) partial byte */\n\t  break;\n\tcase 1:  Skein_256_Update(&state->u.ctx_256,data,bCnt-1); /* process all but the final byte    */\n\t  Skein_256_Update(&state->u.ctx_256,&b  ,  1   ); /* process the (masked) partial byte */\n\t  break;\n\tcase 0:  Skein1024_Update(&state->u.ctx1024,data,bCnt-1); /* process all but the final byte    */\n\t  Skein1024_Update(&state->u.ctx1024,&b  ,  1   ); /* process the (masked) partial byte */\n\t  break;\n\tdefault: return SKEIN_FAIL;\n\t}\n\tSkein_Set_Bit_Pad_Flag(state->u.h);                    /* set tweak flag for the final call */\n\n\treturn SKEIN_SUCCESS;\n  }\n}\n\n/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\n/* finalize hash computation and output the result (hashbitlen bits) */\nstatic SkeinHashReturn Final(hashState *state, SkeinBitSequence *hashval)\n{\n  Skein_Assert(state->statebits % 256 == 0 && (state->statebits-256) < 1024,FAIL);\n  switch ((state->statebits >> 8) & 3)\n  {\n  case 2:  return Skein_512_Final(&state->u.ctx_512,hashval);\n  case 1:  return Skein_256_Final(&state->u.ctx_256,hashval);\n  case 0:  return Skein1024_Final(&state->u.ctx1024,hashval);\n  default: return SKEIN_FAIL;\n  }\n}\n\n/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\n/* all-in-one hash function */\nSkeinHashReturn skein_hash(int hashbitlen, const SkeinBitSequence *data, /* all-in-one call */\n\t\t\t\tSkeinDataLength databitlen,SkeinBitSequence *hashval)\n{\n  hashState  state;\n  SkeinHashReturn r = Init(&state,hashbitlen);\n  if (r == SKEIN_SUCCESS)\n  { /* these calls do not fail when called properly */\n\tr = Update(&state,data,databitlen);\n\tFinal(&state,hashval);\n  }\n  return r;\n}\n"
  },
  {
    "path": "crypto/c_skein.h",
    "content": "#ifndef _SKEIN_H_\n#define _SKEIN_H_     1\n/**************************************************************************\n**\n** Interface declarations and internal definitions for Skein hashing.\n**\n** Source code author: Doug Whiting, 2008.\n**\n** This algorithm and source code is released to the public domain.\n**\n***************************************************************************\n** \n** The following compile-time switches may be defined to control some\n** tradeoffs between speed, code size, error checking, and security.\n**\n** The \"default\" note explains what happens when the switch is not defined.\n**\n**  SKEIN_DEBUG            -- make callouts from inside Skein code\n**                            to examine/display intermediate values.\n**                            [default: no callouts (no overhead)]\n**\n**  SKEIN_ERR_CHECK        -- how error checking is handled inside Skein\n**                            code. If not defined, most error checking \n**                            is disabled (for performance). Otherwise, \n**                            the switch value is interpreted as:\n**                                0: use assert()      to flag errors\n**                                1: return SKEIN_FAIL to flag errors\n**\n***************************************************************************/\n#include \"skein_port.h\"                      /* get platform-specific definitions */\n\ntypedef enum\n{\n  SKEIN_SUCCESS         =      0,          /* return codes from Skein calls */\n  SKEIN_FAIL            =      1,\n  SKEIN_BAD_HASHLEN     =      2\n}\nSkeinHashReturn;\n\ntypedef size_t   SkeinDataLength;                /* bit count  type */\ntypedef u08b_t   SkeinBitSequence;               /* bit stream type */\n\n/* \"all-in-one\" call */\nSkeinHashReturn skein_hash(int hashbitlen,   const SkeinBitSequence *data,\n\t\tSkeinDataLength databitlen, SkeinBitSequence *hashval);\n\n#endif  /* ifndef _SKEIN_H_ */\n"
  },
  {
    "path": "crypto/cryptonight.h",
    "content": "#ifndef __CRYPTONIGHT_H_INCLUDED\n#define __CRYPTONIGHT_H_INCLUDED\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stddef.h>\n#include <inttypes.h>\n\n#define MEMORY  2097152\n\ntypedef struct {\n\tuint8_t hash_state[224]; // Need only 200, explicit align\n\tuint8_t long_state[MEMORY];\n} cryptonight_ctx;\n\nvoid cryptonight_hash_ctx(const void* input, size_t len, void* output, cryptonight_ctx* ctx);\nvoid cryptonight_hash_ctx_soft(const void* input, size_t len, void* output, cryptonight_ctx* ctx);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "crypto/cryptonight_aesni.h",
    "content": "/*\n  * This program is free software: you can redistribute it and/or modify\n  * it under the terms of the GNU General Public License as published by\n  * the Free Software Foundation, either version 3 of the License, or\n  * any later version.\n  *\n  * This program is distributed in the hope that it will be useful,\n  * but WITHOUT ANY WARRANTY; without even the implied warranty of\n  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n  * GNU General Public License for more details.\n  *\n  * You should have received a copy of the GNU General Public License\n  * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n  *\n  */\n#pragma once\n\n#include \"cryptonight.h\"\n#include <memory.h>\n#include <stdio.h>\n\n#ifdef __GNUC__\n#include <x86intrin.h>\nstatic inline uint64_t _umul128(uint64_t a, uint64_t b, uint64_t* hi)\n{\n\tunsigned __int128 r = (unsigned __int128)a * (unsigned __int128)b;\n\t*hi = r >> 64;\n\treturn (uint64_t)r;\n}\n\n#define _mm256_set_m128i(v0, v1)  _mm256_insertf128_si256(_mm256_castsi128_si256(v1), (v0), 1)\n#else\n#include <intrin.h>\n#endif // __GNUC__\n\n#if !defined(_LP64) && !defined(_WIN64)\n#error You are trying to do a 32-bit build. This will all end in tears. I know it.\n#endif\n\nextern \"C\"\n{\n\tvoid keccak(const uint8_t *in, int inlen, uint8_t *md, int mdlen);\n\tvoid keccakf(uint64_t st[25], int rounds);\n\textern void(*const extra_hashes[4])(const void *, size_t, char *);\n\n\t__m128i soft_aesenc(__m128i in, __m128i key);\n\t__m128i soft_aeskeygenassist(__m128i key, uint8_t rcon);\n}\n\n// This will shift and xor tmp1 into itself as 4 32-bit vals such as\n// sl_xor(a1 a2 a3 a4) = a1 (a2^a1) (a3^a2^a1) (a4^a3^a2^a1)\nstatic inline __m128i sl_xor(__m128i tmp1)\n{\n\t__m128i tmp4;\n\ttmp4 = _mm_slli_si128(tmp1, 0x04);\n\ttmp1 = _mm_xor_si128(tmp1, tmp4);\n\ttmp4 = _mm_slli_si128(tmp4, 0x04);\n\ttmp1 = _mm_xor_si128(tmp1, tmp4);\n\ttmp4 = _mm_slli_si128(tmp4, 0x04);\n\ttmp1 = _mm_xor_si128(tmp1, tmp4);\n\treturn tmp1;\n}\n\ntemplate<uint8_t rcon>\nstatic inline void aes_genkey_sub(__m128i* xout0, __m128i* xout2)\n{\n\t__m128i xout1 = _mm_aeskeygenassist_si128(*xout2, rcon);\n\txout1 = _mm_shuffle_epi32(xout1, 0xFF); // see PSHUFD, set all elems to 4th elem\n\t*xout0 = sl_xor(*xout0);\n\t*xout0 = _mm_xor_si128(*xout0, xout1);\n\txout1 = _mm_aeskeygenassist_si128(*xout0, 0x00);\n\txout1 = _mm_shuffle_epi32(xout1, 0xAA); // see PSHUFD, set all elems to 3rd elem\n\t*xout2 = sl_xor(*xout2);\n\t*xout2 = _mm_xor_si128(*xout2, xout1);\n}\n\nstatic inline void soft_aes_genkey_sub(__m128i* xout0, __m128i* xout2, uint8_t rcon)\n{\n\t__m128i xout1 = soft_aeskeygenassist(*xout2, rcon);\n\txout1 = _mm_shuffle_epi32(xout1, 0xFF); // see PSHUFD, set all elems to 4th elem\n\t*xout0 = sl_xor(*xout0);\n\t*xout0 = _mm_xor_si128(*xout0, xout1);\n\txout1 = soft_aeskeygenassist(*xout0, 0x00);\n\txout1 = _mm_shuffle_epi32(xout1, 0xAA); // see PSHUFD, set all elems to 3rd elem\n\t*xout2 = sl_xor(*xout2);\n\t*xout2 = _mm_xor_si128(*xout2, xout1);\n}\n\ntemplate<bool SOFT_AES>\nstatic inline void aes_genkey(const __m128i* memory, __m128i* k0, __m128i* k1, __m128i* k2, __m128i* k3,\n\t__m128i* k4, __m128i* k5, __m128i* k6, __m128i* k7, __m128i* k8, __m128i* k9)\n{\n\t__m128i xout0, xout2;\n\n\txout0 = _mm_load_si128(memory);\n\txout2 = _mm_load_si128(memory+1);\n\t*k0 = xout0;\n\t*k1 = xout2;\n\n\tif(SOFT_AES)\n\t\tsoft_aes_genkey_sub(&xout0, &xout2, 0x01);\n\telse\n\t\taes_genkey_sub<0x01>(&xout0, &xout2);\n\t*k2 = xout0;\n\t*k3 = xout2;\n\n\tif(SOFT_AES)\n\t\tsoft_aes_genkey_sub(&xout0, &xout2, 0x02);\n\telse\n\t\taes_genkey_sub<0x02>(&xout0, &xout2);\n\t*k4 = xout0;\n\t*k5 = xout2;\n\n\tif(SOFT_AES)\n\t\tsoft_aes_genkey_sub(&xout0, &xout2, 0x04);\n\telse\n\t\taes_genkey_sub<0x04>(&xout0, &xout2);\n\t*k6 = xout0;\n\t*k7 = xout2;\n\n\tif(SOFT_AES)\n\t\tsoft_aes_genkey_sub(&xout0, &xout2, 0x08);\n\telse\n\t\taes_genkey_sub<0x08>(&xout0, &xout2);\n\t*k8 = xout0;\n\t*k9 = xout2;\n}\n\nstatic inline void aes_round(__m128i key, __m128i* x0, __m128i* x1, __m128i* x2, __m128i* x3, __m128i* x4, __m128i* x5, __m128i* x6, __m128i* x7)\n{\n\t*x0 = _mm_aesenc_si128(*x0, key);\n\t*x1 = _mm_aesenc_si128(*x1, key);\n\t*x2 = _mm_aesenc_si128(*x2, key);\n\t*x3 = _mm_aesenc_si128(*x3, key);\n\t*x4 = _mm_aesenc_si128(*x4, key);\n\t*x5 = _mm_aesenc_si128(*x5, key);\n\t*x6 = _mm_aesenc_si128(*x6, key);\n\t*x7 = _mm_aesenc_si128(*x7, key);\n}\n\nstatic inline void soft_aes_round(__m128i key, __m128i* x0, __m128i* x1, __m128i* x2, __m128i* x3, __m128i* x4, __m128i* x5, __m128i* x6, __m128i* x7)\n{\n\t*x0 = soft_aesenc(*x0, key);\n\t*x1 = soft_aesenc(*x1, key);\n\t*x2 = soft_aesenc(*x2, key);\n\t*x3 = soft_aesenc(*x3, key);\n\t*x4 = soft_aesenc(*x4, key);\n\t*x5 = soft_aesenc(*x5, key);\n\t*x6 = soft_aesenc(*x6, key);\n\t*x7 = soft_aesenc(*x7, key);\n}\n\ntemplate<size_t MEM, bool SOFT_AES>\nvoid cn_explode_scratchpad(const __m128i* input, __m128i* output)\n{\n\t// This is more than we have registers, compiler will assign 2 keys on the stack\n\t__m128i xin0, xin1, xin2, xin3, xin4, xin5, xin6, xin7;\n\t__m128i k0, k1, k2, k3, k4, k5, k6, k7, k8, k9;\n\n\taes_genkey<SOFT_AES>(input, &k0, &k1, &k2, &k3, &k4, &k5, &k6, &k7, &k8, &k9);\n\n\txin0 = _mm_load_si128(input + 4);\n\txin1 = _mm_load_si128(input + 5);\n\txin2 = _mm_load_si128(input + 6);\n\txin3 = _mm_load_si128(input + 7);\n\txin4 = _mm_load_si128(input + 8);\n\txin5 = _mm_load_si128(input + 9);\n\txin6 = _mm_load_si128(input + 10);\n\txin7 = _mm_load_si128(input + 11);\n\n\tfor (size_t i = 0; i < MEM / sizeof(__m128i); i += 8)\n\t{\n\t\tif(SOFT_AES)\n\t\t{\n\t\t\tsoft_aes_round(k0, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);\n\t\t\tsoft_aes_round(k1, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);\n\t\t\tsoft_aes_round(k2, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);\n\t\t\tsoft_aes_round(k3, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);\n\t\t\tsoft_aes_round(k4, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);\n\t\t\tsoft_aes_round(k5, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);\n\t\t\tsoft_aes_round(k6, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);\n\t\t\tsoft_aes_round(k7, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);\n\t\t\tsoft_aes_round(k8, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);\n\t\t\tsoft_aes_round(k9, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);\n\t\t}\n\t\telse\n\t\t{\n\t\t\taes_round(k0, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);\n\t\t\taes_round(k1, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);\n\t\t\taes_round(k2, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);\n\t\t\taes_round(k3, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);\n\t\t\taes_round(k4, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);\n\t\t\taes_round(k5, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);\n\t\t\taes_round(k6, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);\n\t\t\taes_round(k7, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);\n\t\t\taes_round(k8, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);\n\t\t\taes_round(k9, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);\n\t\t}\n\n\t\t_mm_store_si128(output + i + 0, xin0);\n\t\t_mm_store_si128(output + i + 1, xin1);\n\t\t_mm_store_si128(output + i + 2, xin2);\n\t\t_mm_store_si128(output + i + 3, xin3);\n\t\t_mm_prefetch((const char*)output + i + 0, _MM_HINT_T2);\n\t\t_mm_store_si128(output + i + 4, xin4);\n\t\t_mm_store_si128(output + i + 5, xin5);\n\t\t_mm_store_si128(output + i + 6, xin6);\n\t\t_mm_store_si128(output + i + 7, xin7);\n\t\t_mm_prefetch((const char*)output + i + 4, _MM_HINT_T2);\n\t}\n}\n\ntemplate<size_t MEM, bool SOFT_AES>\nvoid cn_implode_scratchpad(const __m128i* input, __m128i* output)\n{\n\t// This is more than we have registers, compiler will assign 2 keys on the stack\n\t__m128i xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7;\n\t__m128i k0, k1, k2, k3, k4, k5, k6, k7, k8, k9;\n\n\taes_genkey<SOFT_AES>(output + 2, &k0, &k1, &k2, &k3, &k4, &k5, &k6, &k7, &k8, &k9);\n\n\txout0 = _mm_load_si128(output + 4);\n\txout1 = _mm_load_si128(output + 5);\n\txout2 = _mm_load_si128(output + 6);\n\txout3 = _mm_load_si128(output + 7);\n\txout4 = _mm_load_si128(output + 8);\n\txout5 = _mm_load_si128(output + 9);\n\txout6 = _mm_load_si128(output + 10);\n\txout7 = _mm_load_si128(output + 11);\n\n\tfor (size_t i = 0; i < MEM / sizeof(__m128i); i += 8)\n\t{\n\t\t_mm_prefetch((const char*)input + i + 0, _MM_HINT_NTA);\n\t\txout0 = _mm_xor_si128(_mm_load_si128(input + i + 0), xout0);\n\t\txout1 = _mm_xor_si128(_mm_load_si128(input + i + 1), xout1);\n\t\txout2 = _mm_xor_si128(_mm_load_si128(input + i + 2), xout2);\n\t\txout3 = _mm_xor_si128(_mm_load_si128(input + i + 3), xout3);\n\t\t_mm_prefetch((const char*)input + i + 4, _MM_HINT_NTA);\n\t\txout4 = _mm_xor_si128(_mm_load_si128(input + i + 4), xout4);\n\t\txout5 = _mm_xor_si128(_mm_load_si128(input + i + 5), xout5);\n\t\txout6 = _mm_xor_si128(_mm_load_si128(input + i + 6), xout6);\n\t\txout7 = _mm_xor_si128(_mm_load_si128(input + i + 7), xout7);\n\n\t\tif(SOFT_AES)\n\t\t{\n\t\t\tsoft_aes_round(k0, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);\n\t\t\tsoft_aes_round(k1, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);\n\t\t\tsoft_aes_round(k2, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);\n\t\t\tsoft_aes_round(k3, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);\n\t\t\tsoft_aes_round(k4, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);\n\t\t\tsoft_aes_round(k5, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);\n\t\t\tsoft_aes_round(k6, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);\n\t\t\tsoft_aes_round(k7, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);\n\t\t\tsoft_aes_round(k8, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);\n\t\t\tsoft_aes_round(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);\n\t\t}\n\t\telse\n\t\t{\n\t\t\taes_round(k0, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);\n\t\t\taes_round(k1, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);\n\t\t\taes_round(k2, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);\n\t\t\taes_round(k3, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);\n\t\t\taes_round(k4, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);\n\t\t\taes_round(k5, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);\n\t\t\taes_round(k6, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);\n\t\t\taes_round(k7, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);\n\t\t\taes_round(k8, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);\n\t\t\taes_round(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);\n\t\t}\n\t}\n\n\t_mm_store_si128(output + 4, xout0);\n\t_mm_store_si128(output + 5, xout1);\n\t_mm_store_si128(output + 6, xout2);\n\t_mm_store_si128(output + 7, xout3);\n\t_mm_store_si128(output + 8, xout4);\n\t_mm_store_si128(output + 9, xout5);\n\t_mm_store_si128(output + 10, xout6);\n\t_mm_store_si128(output + 11, xout7);\n}\n\ntemplate<size_t ITERATIONS, size_t MEM, bool PREFETCH, bool SOFT_AES>\nvoid cryptonight_hash(const void* input, size_t len, void* output, cryptonight_ctx* ctx0)\n{\n\tkeccak((const uint8_t *)input, len, ctx0->hash_state, 200);\n\n\t// Optim - 99% time boundary\n\tcn_explode_scratchpad<MEM, SOFT_AES>((__m128i*)ctx0->hash_state, (__m128i*)ctx0->long_state);\n\n\tuint8_t* l0 = ctx0->long_state;\n\tuint64_t* h0 = (uint64_t*)ctx0->hash_state;\n\n\tuint64_t al0 = h0[0] ^ h0[4];\n\tuint64_t ah0 = h0[1] ^ h0[5];\n\t__m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]);\n\n\tuint64_t idx0 = h0[0] ^ h0[4];\n\n\t// Optim - 90% time boundary\n\tfor(size_t i = 0; i < ITERATIONS; i++)\n\t{\n\t\t__m128i cx;\n\t\tcx = _mm_load_si128((__m128i *)&l0[idx0 & 0x1FFFF0]);\n\t\tif(SOFT_AES)\n\t\t\tcx = soft_aesenc(cx, _mm_set_epi64x(ah0, al0));\n\t\telse\n\t\t\tcx = _mm_aesenc_si128(cx, _mm_set_epi64x(ah0, al0));\n\t\t_mm_store_si128((__m128i *)&l0[idx0 & 0x1FFFF0], _mm_xor_si128(bx0, cx));\n\t\tidx0 = _mm_cvtsi128_si64(cx);\n\t\tbx0 = cx;\n\t\tif(PREFETCH)\n\t\t\t_mm_prefetch((const char*)&l0[idx0 & 0x1FFFF0], _MM_HINT_T0);\n\n\t\tuint64_t hi, lo, cl, ch;\n\t\tcl = ((uint64_t*)&l0[idx0 & 0x1FFFF0])[0];\n\t\tch = ((uint64_t*)&l0[idx0 & 0x1FFFF0])[1];\n\t\tlo = _umul128(idx0, cl, &hi);\n\t\tal0 += hi;\n\t\tah0 += lo;\n\t\t((uint64_t*)&l0[idx0 & 0x1FFFF0])[0] = al0;\n\t\t((uint64_t*)&l0[idx0 & 0x1FFFF0])[1] = ah0;\n\t\tah0 ^= ch;\n\t\tal0 ^= cl;\n\t\tidx0 = al0;\n\t\tif(PREFETCH)\n\t\t\t_mm_prefetch((const char*)&l0[idx0 & 0x1FFFF0], _MM_HINT_T0);\n\t}\n\n\t// Optim - 90% time boundary\n\tcn_implode_scratchpad<MEM, SOFT_AES>((__m128i*)ctx0->long_state, (__m128i*)ctx0->hash_state);\n\n\t// Optim - 99% time boundary\n\n\tkeccakf((uint64_t*)ctx0->hash_state, 24);\n\textra_hashes[ctx0->hash_state[0] & 3](ctx0->hash_state, 200, (char*)output);\n}\n\n// This lovely creation will do 2 cn hashes at a time. We have plenty of space on silicon\n// to fit temporary vars for two contexts. Function will read len*2 from input and write 64 bytes to output\n// We are still limited by L3 cache, so doubling will only work with CPUs where we have more than 2MB to core (Xeons)\ntemplate<size_t ITERATIONS, size_t MEM, bool PREFETCH, bool SOFT_AES>\nvoid cryptonight_double_hash(const void* input, size_t len, void* output, cryptonight_ctx* __restrict ctx0, cryptonight_ctx* __restrict ctx1)\n{\n\tkeccak((const uint8_t *)input, len, ctx0->hash_state, 200);\n\tkeccak((const uint8_t *)input+len, len, ctx1->hash_state, 200);\n\n\t// Optim - 99% time boundary\n\tcn_explode_scratchpad<MEM, SOFT_AES>((__m128i*)ctx0->hash_state, (__m128i*)ctx0->long_state);\n\tcn_explode_scratchpad<MEM, SOFT_AES>((__m128i*)ctx1->hash_state, (__m128i*)ctx1->long_state);\n\n\tuint8_t* l0 = ctx0->long_state;\n\tuint64_t* h0 = (uint64_t*)ctx0->hash_state;\n\tuint8_t* l1 = ctx1->long_state;\n\tuint64_t* h1 = (uint64_t*)ctx1->hash_state;\n\n\t__m128i ax0 = _mm_set_epi64x(h0[1] ^ h0[5], h0[0] ^ h0[4]);\n\t__m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]);\n\t__m128i ax1 = _mm_set_epi64x(h1[1] ^ h1[5], h1[0] ^ h1[4]);\n\t__m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]);\n\n\tuint64_t idx0 = h0[0] ^ h0[4];\n\tuint64_t idx1 = h1[0] ^ h1[4];\n\n\t// Optim - 90% time boundary\n\tfor (size_t i = 0; i < ITERATIONS; i++)\n\t{\n\t\t__m128i cx;\n\t\tcx = _mm_load_si128((__m128i *)&l0[idx0 & 0x1FFFF0]);\n\t\tif(SOFT_AES)\n\t\t\tcx = soft_aesenc(cx, ax0);\n\t\telse\n\t\t\tcx = _mm_aesenc_si128(cx, ax0);\n\t\t_mm_store_si128((__m128i *)&l0[idx0 & 0x1FFFF0], _mm_xor_si128(bx0, cx));\n\t\tidx0 = _mm_cvtsi128_si64(cx);\n\t\tbx0 = cx;\n\t\tif(PREFETCH)\n\t\t\t_mm_prefetch((const char*)&l0[idx0 & 0x1FFFF0], _MM_HINT_T0);\n\n\t\tcx = _mm_load_si128((__m128i *)&l1[idx1 & 0x1FFFF0]);\n\t\tif(SOFT_AES)\n\t\t\tcx = soft_aesenc(cx, ax1);\n\t\telse\n\t\t\tcx = _mm_aesenc_si128(cx, ax1);\n\t\t_mm_store_si128((__m128i *)&l1[idx1 & 0x1FFFF0], _mm_xor_si128(bx1, cx));\n\t\tidx1 = _mm_cvtsi128_si64(cx);\n\t\tbx1 = cx;\n\t\tif(PREFETCH)\n\t\t\t_mm_prefetch((const char*)&l1[idx1 & 0x1FFFF0], _MM_HINT_T0);\n\n\t\tuint64_t hi, lo;\n\t\tcx = _mm_load_si128((__m128i *)&l0[idx0 & 0x1FFFF0]);\n\t\tlo = _umul128(idx0, _mm_cvtsi128_si64(cx), &hi);\n\t\tax0 = _mm_add_epi64(ax0, _mm_set_epi64x(lo, hi));\n\t\t_mm_store_si128((__m128i*)&l0[idx0 & 0x1FFFF0], ax0);\n\t\tax0 = _mm_xor_si128(ax0, cx);\n\t\tidx0 = _mm_cvtsi128_si64(ax0);\n\t\tif(PREFETCH)\n\t\t\t_mm_prefetch((const char*)&l0[idx0 & 0x1FFFF0], _MM_HINT_T0);\n\n\t\tcx = _mm_load_si128((__m128i *)&l1[idx1 & 0x1FFFF0]);\n\t\tlo = _umul128(idx1, _mm_cvtsi128_si64(cx), &hi);\n\t\tax1 = _mm_add_epi64(ax1, _mm_set_epi64x(lo, hi));\n\t\t_mm_store_si128((__m128i*)&l1[idx1 & 0x1FFFF0], ax1);\n\t\tax1 = _mm_xor_si128(ax1, cx);\n\t\tidx1 = _mm_cvtsi128_si64(ax1);\n\t\tif(PREFETCH)\n\t\t\t_mm_prefetch((const char*)&l1[idx1 & 0x1FFFF0], _MM_HINT_T0);\n\t}\n\n\t// Optim - 90% time boundary\n\tcn_implode_scratchpad<MEM, SOFT_AES>((__m128i*)ctx0->long_state, (__m128i*)ctx0->hash_state);\n\tcn_implode_scratchpad<MEM, SOFT_AES>((__m128i*)ctx1->long_state, (__m128i*)ctx1->hash_state);\n\n\t// Optim - 99% time boundary\n\n\tkeccakf((uint64_t*)ctx0->hash_state, 24);\n\textra_hashes[ctx0->hash_state[0] & 3](ctx0->hash_state, 200, (char*)output);\n\tkeccakf((uint64_t*)ctx1->hash_state, 24);\n\textra_hashes[ctx1->hash_state[0] & 3](ctx1->hash_state, 200, (char*)output + 32);\n}\n"
  },
  {
    "path": "crypto/cryptonight_common.cpp",
    "content": "/*\n  * This program is free software: you can redistribute it and/or modify\n  * it under the terms of the GNU General Public License as published by\n  * the Free Software Foundation, either version 3 of the License, or\n  * any later version.\n  *\n  * This program is distributed in the hope that it will be useful,\n  * but WITHOUT ANY WARRANTY; without even the implied warranty of\n  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n  * GNU General Public License for more details.\n  *\n  * You should have received a copy of the GNU General Public License\n  * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n  *\n  * Additional permission under GNU GPL version 3 section 7\n  *\n  * If you modify this Program, or any covered work, by linking or combining\n  * it with OpenSSL (or a modified version of that library), containing parts\n  * covered by the terms of OpenSSL License and SSLeay License, the licensors\n  * of this Program grant you additional permission to convey the resulting work.\n  *\n  */\n\nextern \"C\"\n{\n#include \"c_groestl.h\"\n#include \"c_blake256.h\"\n#include \"c_jh.h\"\n#include \"c_skein.h\"\n}\n#include \"cryptonight.h\"\n#include \"cryptonight_aesni.h\"\n#include <stdio.h>\n#include <stdlib.h>\n\n#ifdef __GNUC__\n#include <mm_malloc.h>\n#else\n#include <malloc.h>\n#endif // __GNUC__\n\n#ifdef _WIN32\n#include <windows.h>\n#else\n#include <sys/mman.h>\n#include <errno.h>\n#include <string.h>\n#endif // _WIN32\n\nvoid do_blake_hash(const void* input, size_t len, char* output) {\n\tblake256_hash((uint8_t*)output, (const uint8_t*)input, len);\n}\n\nvoid do_groestl_hash(const void* input, size_t len, char* output) {\n\tgroestl((const uint8_t*)input, len * 8, (uint8_t*)output);\n}\n\nvoid do_jh_hash(const void* input, size_t len, char* output) {\n\tjh_hash(32 * 8, (const uint8_t*)input, 8 * len, (uint8_t*)output);\n}\n\nvoid do_skein_hash(const void* input, size_t len, char* output) {\n\tskein_hash(8 * 32, (const uint8_t*)input, 8 * len, (uint8_t*)output);\n}\n\nvoid (* const extra_hashes[4])(const void *, size_t, char *) = {do_blake_hash, do_groestl_hash, do_jh_hash, do_skein_hash};\n\n\nvoid cryptonight_hash_ctx(const void* input, size_t len, void* output, cryptonight_ctx* ctx)\n{\n\tcryptonight_hash<0x80000, MEMORY, true, false>(input, len, output, ctx);\n}\n\nvoid cryptonight_hash_ctx_soft(const void* input, size_t len, void* output, cryptonight_ctx* ctx)\n{\n\tcryptonight_hash<0x80000, MEMORY, true, true>(input, len, output, ctx);\n}\n\n"
  },
  {
    "path": "crypto/groestl_tables.h",
    "content": "#ifndef __tables_h\n#define __tables_h\n\n\nconst uint32_t T[512] = {0xa5f432c6, 0xc6a597f4, 0x84976ff8, 0xf884eb97, 0x99b05eee, 0xee99c7b0, 0x8d8c7af6, 0xf68df78c, 0xd17e8ff, 0xff0de517, 0xbddc0ad6, 0xd6bdb7dc, 0xb1c816de, 0xdeb1a7c8, 0x54fc6d91, 0x915439fc\n, 0x50f09060, 0x6050c0f0, 0x3050702, 0x2030405, 0xa9e02ece, 0xcea987e0, 0x7d87d156, 0x567dac87, 0x192bcce7, 0xe719d52b, 0x62a613b5, 0xb56271a6, 0xe6317c4d, 0x4de69a31, 0x9ab559ec, 0xec9ac3b5\n, 0x45cf408f, 0x8f4505cf, 0x9dbca31f, 0x1f9d3ebc, 0x40c04989, 0x894009c0, 0x879268fa, 0xfa87ef92, 0x153fd0ef, 0xef15c53f, 0xeb2694b2, 0xb2eb7f26, 0xc940ce8e, 0x8ec90740, 0xb1de6fb, 0xfb0bed1d\n, 0xec2f6e41, 0x41ec822f, 0x67a91ab3, 0xb3677da9, 0xfd1c435f, 0x5ffdbe1c, 0xea256045, 0x45ea8a25, 0xbfdaf923, 0x23bf46da, 0xf7025153, 0x53f7a602, 0x96a145e4, 0xe496d3a1, 0x5bed769b, 0x9b5b2ded\n, 0xc25d2875, 0x75c2ea5d, 0x1c24c5e1, 0xe11cd924, 0xaee9d43d, 0x3dae7ae9, 0x6abef24c, 0x4c6a98be, 0x5aee826c, 0x6c5ad8ee, 0x41c3bd7e, 0x7e41fcc3, 0x206f3f5, 0xf502f106, 0x4fd15283, 0x834f1dd1\n, 0x5ce48c68, 0x685cd0e4, 0xf4075651, 0x51f4a207, 0x345c8dd1, 0xd134b95c, 0x818e1f9, 0xf908e918, 0x93ae4ce2, 0xe293dfae, 0x73953eab, 0xab734d95, 0x53f59762, 0x6253c4f5, 0x3f416b2a, 0x2a3f5441\n, 0xc141c08, 0x80c1014, 0x52f66395, 0x955231f6, 0x65afe946, 0x46658caf, 0x5ee27f9d, 0x9d5e21e2, 0x28784830, 0x30286078, 0xa1f8cf37, 0x37a16ef8, 0xf111b0a, 0xa0f1411, 0xb5c4eb2f, 0x2fb55ec4\n, 0x91b150e, 0xe091c1b, 0x365a7e24, 0x2436485a, 0x9bb6ad1b, 0x1b9b36b6, 0x3d4798df, 0xdf3da547, 0x266aa7cd, 0xcd26816a, 0x69bbf54e, 0x4e699cbb, 0xcd4c337f, 0x7fcdfe4c, 0x9fba50ea, 0xea9fcfba\n, 0x1b2d3f12, 0x121b242d, 0x9eb9a41d, 0x1d9e3ab9, 0x749cc458, 0x5874b09c, 0x2e724634, 0x342e6872, 0x2d774136, 0x362d6c77, 0xb2cd11dc, 0xdcb2a3cd, 0xee299db4, 0xb4ee7329, 0xfb164d5b, 0x5bfbb616\n, 0xf601a5a4, 0xa4f65301, 0x4dd7a176, 0x764decd7, 0x61a314b7, 0xb76175a3, 0xce49347d, 0x7dcefa49, 0x7b8ddf52, 0x527ba48d, 0x3e429fdd, 0xdd3ea142, 0x7193cd5e, 0x5e71bc93, 0x97a2b113, 0x139726a2\n, 0xf504a2a6, 0xa6f55704, 0x68b801b9, 0xb96869b8, 0x0, 0x0, 0x2c74b5c1, 0xc12c9974, 0x60a0e040, 0x406080a0, 0x1f21c2e3, 0xe31fdd21, 0xc8433a79, 0x79c8f243, 0xed2c9ab6, 0xb6ed772c\n, 0xbed90dd4, 0xd4beb3d9, 0x46ca478d, 0x8d4601ca, 0xd9701767, 0x67d9ce70, 0x4bddaf72, 0x724be4dd, 0xde79ed94, 0x94de3379, 0xd467ff98, 0x98d42b67, 0xe82393b0, 0xb0e87b23, 0x4ade5b85, 0x854a11de\n, 0x6bbd06bb, 0xbb6b6dbd, 0x2a7ebbc5, 0xc52a917e, 0xe5347b4f, 0x4fe59e34, 0x163ad7ed, 0xed16c13a, 0xc554d286, 0x86c51754, 0xd762f89a, 0x9ad72f62, 0x55ff9966, 0x6655ccff, 0x94a7b611, 0x119422a7\n, 0xcf4ac08a, 0x8acf0f4a, 0x1030d9e9, 0xe910c930, 0x60a0e04, 0x406080a, 0x819866fe, 0xfe81e798, 0xf00baba0, 0xa0f05b0b, 0x44ccb478, 0x7844f0cc, 0xbad5f025, 0x25ba4ad5, 0xe33e754b, 0x4be3963e\n, 0xf30eaca2, 0xa2f35f0e, 0xfe19445d, 0x5dfeba19, 0xc05bdb80, 0x80c01b5b, 0x8a858005, 0x58a0a85, 0xadecd33f, 0x3fad7eec, 0xbcdffe21, 0x21bc42df, 0x48d8a870, 0x7048e0d8, 0x40cfdf1, 0xf104f90c\n, 0xdf7a1963, 0x63dfc67a, 0xc1582f77, 0x77c1ee58, 0x759f30af, 0xaf75459f, 0x63a5e742, 0x426384a5, 0x30507020, 0x20304050, 0x1a2ecbe5, 0xe51ad12e, 0xe12effd, 0xfd0ee112, 0x6db708bf, 0xbf6d65b7\n, 0x4cd45581, 0x814c19d4, 0x143c2418, 0x1814303c, 0x355f7926, 0x26354c5f, 0x2f71b2c3, 0xc32f9d71, 0xe13886be, 0xbee16738, 0xa2fdc835, 0x35a26afd, 0xcc4fc788, 0x88cc0b4f, 0x394b652e, 0x2e395c4b\n, 0x57f96a93, 0x93573df9, 0xf20d5855, 0x55f2aa0d, 0x829d61fc, 0xfc82e39d, 0x47c9b37a, 0x7a47f4c9, 0xacef27c8, 0xc8ac8bef, 0xe73288ba, 0xbae76f32, 0x2b7d4f32, 0x322b647d, 0x95a442e6, 0xe695d7a4\n, 0xa0fb3bc0, 0xc0a09bfb, 0x98b3aa19, 0x199832b3, 0xd168f69e, 0x9ed12768, 0x7f8122a3, 0xa37f5d81, 0x66aaee44, 0x446688aa, 0x7e82d654, 0x547ea882, 0xabe6dd3b, 0x3bab76e6, 0x839e950b, 0xb83169e\n, 0xca45c98c, 0x8cca0345, 0x297bbcc7, 0xc729957b, 0xd36e056b, 0x6bd3d66e, 0x3c446c28, 0x283c5044, 0x798b2ca7, 0xa779558b, 0xe23d81bc, 0xbce2633d, 0x1d273116, 0x161d2c27, 0x769a37ad, 0xad76419a\n, 0x3b4d96db, 0xdb3bad4d, 0x56fa9e64, 0x6456c8fa, 0x4ed2a674, 0x744ee8d2, 0x1e223614, 0x141e2822, 0xdb76e492, 0x92db3f76, 0xa1e120c, 0xc0a181e, 0x6cb4fc48, 0x486c90b4, 0xe4378fb8, 0xb8e46b37\n, 0x5de7789f, 0x9f5d25e7, 0x6eb20fbd, 0xbd6e61b2, 0xef2a6943, 0x43ef862a, 0xa6f135c4, 0xc4a693f1, 0xa8e3da39, 0x39a872e3, 0xa4f7c631, 0x31a462f7, 0x37598ad3, 0xd337bd59, 0x8b8674f2, 0xf28bff86\n, 0x325683d5, 0xd532b156, 0x43c54e8b, 0x8b430dc5, 0x59eb856e, 0x6e59dceb, 0xb7c218da, 0xdab7afc2, 0x8c8f8e01, 0x18c028f, 0x64ac1db1, 0xb16479ac, 0xd26df19c, 0x9cd2236d, 0xe03b7249, 0x49e0923b\n, 0xb4c71fd8, 0xd8b4abc7, 0xfa15b9ac, 0xacfa4315, 0x709faf3, 0xf307fd09, 0x256fa0cf, 0xcf25856f, 0xafea20ca, 0xcaaf8fea, 0x8e897df4, 0xf48ef389, 0xe9206747, 0x47e98e20, 0x18283810, 0x10182028\n, 0xd5640b6f, 0x6fd5de64, 0x888373f0, 0xf088fb83, 0x6fb1fb4a, 0x4a6f94b1, 0x7296ca5c, 0x5c72b896, 0x246c5438, 0x3824706c, 0xf1085f57, 0x57f1ae08, 0xc7522173, 0x73c7e652, 0x51f36497, 0x975135f3\n, 0x2365aecb, 0xcb238d65, 0x7c8425a1, 0xa17c5984, 0x9cbf57e8, 0xe89ccbbf, 0x21635d3e, 0x3e217c63, 0xdd7cea96, 0x96dd377c, 0xdc7f1e61, 0x61dcc27f, 0x86919c0d, 0xd861a91, 0x85949b0f, 0xf851e94\n, 0x90ab4be0, 0xe090dbab, 0x42c6ba7c, 0x7c42f8c6, 0xc4572671, 0x71c4e257, 0xaae529cc, 0xccaa83e5, 0xd873e390, 0x90d83b73, 0x50f0906, 0x6050c0f, 0x103f4f7, 0xf701f503, 0x12362a1c, 0x1c123836\n, 0xa3fe3cc2, 0xc2a39ffe, 0x5fe18b6a, 0x6a5fd4e1, 0xf910beae, 0xaef94710, 0xd06b0269, 0x69d0d26b, 0x91a8bf17, 0x17912ea8, 0x58e87199, 0x995829e8, 0x2769533a, 0x3a277469, 0xb9d0f727, 0x27b94ed0\n, 0x384891d9, 0xd938a948, 0x1335deeb, 0xeb13cd35, 0xb3cee52b, 0x2bb356ce, 0x33557722, 0x22334455, 0xbbd604d2, 0xd2bbbfd6, 0x709039a9, 0xa9704990, 0x89808707, 0x7890e80, 0xa7f2c133, 0x33a766f2\n, 0xb6c1ec2d, 0x2db65ac1, 0x22665a3c, 0x3c227866, 0x92adb815, 0x15922aad, 0x2060a9c9, 0xc9208960, 0x49db5c87, 0x874915db, 0xff1ab0aa, 0xaaff4f1a, 0x7888d850, 0x5078a088, 0x7a8e2ba5, 0xa57a518e\n, 0x8f8a8903, 0x38f068a, 0xf8134a59, 0x59f8b213, 0x809b9209, 0x980129b, 0x1739231a, 0x1a173439, 0xda751065, 0x65daca75, 0x315384d7, 0xd731b553, 0xc651d584, 0x84c61351, 0xb8d303d0, 0xd0b8bbd3\n, 0xc35edc82, 0x82c31f5e, 0xb0cbe229, 0x29b052cb, 0x7799c35a, 0x5a77b499, 0x11332d1e, 0x1e113c33, 0xcb463d7b, 0x7bcbf646, 0xfc1fb7a8, 0xa8fc4b1f, 0xd6610c6d, 0x6dd6da61, 0x3a4e622c, 0x2c3a584e};\n\n#endif /* __tables_h */\n"
  },
  {
    "path": "crypto/hash.h",
    "content": "#pragma once\n\ntypedef unsigned char BitSequence;\ntypedef unsigned long long DataLength;\ntypedef enum {SUCCESS = 0, FAIL = 1, BAD_HASHLEN = 2} HashReturn;\n"
  },
  {
    "path": "crypto/int-util.h",
    "content": "// Copyright(c) 2012 - 2013 The Cryptonote developers\n// Distributed under the MIT/X11 software license, see the accompanying\n// file COPYING or http://www.opensource.org/licenses/mit-license.php.\n\n#pragma once\n\n#include <assert.h>\n#include <stdbool.h>\n#include <stdint.h>\n#include <string.h>\n\n#if defined(_MSC_VER)\n#include <stdlib.h>\n\nstatic inline uint32_t rol32(uint32_t x, int r) {\n\tstatic_assert(sizeof(uint32_t) == sizeof(unsigned int), \"this code assumes 32-bit integers\");\n\treturn _rotl(x, r);\n}\n\nstatic inline uint64_t rol64(uint64_t x, int r) {\n\treturn _rotl64(x, r);\n}\n\n#else\n\nstatic inline uint32_t rol32(uint32_t x, int r) {\n\treturn (x << (r & 31)) | (x >> (-r & 31));\n}\n\nstatic inline uint64_t rol64(uint64_t x, int r) {\n\treturn (x << (r & 63)) | (x >> (-r & 63));\n}\n\n#endif\n\nstatic inline uint64_t hi_dword(uint64_t val) {\n\treturn val >> 32;\n}\n\nstatic inline uint64_t lo_dword(uint64_t val) {\n\treturn val & 0xFFFFFFFF;\n}\n\nstatic inline uint64_t div_with_reminder(uint64_t dividend, uint32_t divisor, uint32_t* remainder) {\n\tdividend |= ((uint64_t)*remainder) << 32;\n\t*remainder = dividend % divisor;\n\treturn dividend / divisor;\n}\n\n// Long division with 2^32 base\nstatic inline uint32_t div128_32(uint64_t dividend_hi, uint64_t dividend_lo, uint32_t divisor, uint64_t* quotient_hi, uint64_t* quotient_lo) {\n\tuint64_t dividend_dwords[4];\n\tuint32_t remainder = 0;\n\n\tdividend_dwords[3] = hi_dword(dividend_hi);\n\tdividend_dwords[2] = lo_dword(dividend_hi);\n\tdividend_dwords[1] = hi_dword(dividend_lo);\n\tdividend_dwords[0] = lo_dword(dividend_lo);\n\n\t*quotient_hi = div_with_reminder(dividend_dwords[3], divisor, &remainder) << 32;\n\t*quotient_hi |= div_with_reminder(dividend_dwords[2], divisor, &remainder);\n\t*quotient_lo = div_with_reminder(dividend_dwords[1], divisor, &remainder) << 32;\n\t*quotient_lo |= div_with_reminder(dividend_dwords[0], divisor, &remainder);\n\n\treturn remainder;\n}\n\n#define IDENT32(x) ((uint32_t) (x))\n#define IDENT64(x) ((uint64_t) (x))\n\n#define SWAP32(x) ((((uint32_t) (x) & 0x000000ff) << 24) | \\\n  (((uint32_t) (x) & 0x0000ff00) <<  8) | \\\n  (((uint32_t) (x) & 0x00ff0000) >>  8) | \\\n  (((uint32_t) (x) & 0xff000000) >> 24))\n#define SWAP64(x) ((((uint64_t) (x) & 0x00000000000000ff) << 56) | \\\n  (((uint64_t) (x) & 0x000000000000ff00) << 40) | \\\n  (((uint64_t) (x) & 0x0000000000ff0000) << 24) | \\\n  (((uint64_t) (x) & 0x00000000ff000000) <<  8) | \\\n  (((uint64_t) (x) & 0x000000ff00000000) >>  8) | \\\n  (((uint64_t) (x) & 0x0000ff0000000000) >> 24) | \\\n  (((uint64_t) (x) & 0x00ff000000000000) >> 40) | \\\n  (((uint64_t) (x) & 0xff00000000000000) >> 56))\n\nstatic inline uint32_t ident32(uint32_t x) { return x; }\nstatic inline uint64_t ident64(uint64_t x) { return x; }\n\nstatic inline uint32_t swap32(uint32_t x) {\n\tx = ((x & 0x00ff00ff) << 8) | ((x & 0xff00ff00) >> 8);\n\treturn (x << 16) | (x >> 16);\n}\nstatic inline uint64_t swap64(uint64_t x) {\n\tx = ((x & 0x00ff00ff00ff00ff) << 8) | ((x & 0xff00ff00ff00ff00) >> 8);\n\tx = ((x & 0x0000ffff0000ffff) << 16) | ((x & 0xffff0000ffff0000) >> 16);\n\treturn (x << 32) | (x >> 32);\n}\n\n#if defined(__GNUC__)\n#define UNUSED __attribute__((unused))\n#else\n#define UNUSED\n#endif\nstatic inline void mem_inplace_ident(void *mem UNUSED, size_t n UNUSED) { }\n#undef UNUSED\n\nstatic inline void mem_inplace_swap32(void *mem, size_t n) {\n\tsize_t i;\n\tfor (i = 0; i < n; i++) {\n\t\t((uint32_t *)mem)[i] = swap32(((const uint32_t *)mem)[i]);\n\t}\n}\nstatic inline void mem_inplace_swap64(void *mem, size_t n) {\n\tsize_t i;\n\tfor (i = 0; i < n; i++) {\n\t\t((uint64_t *)mem)[i] = swap64(((const uint64_t *)mem)[i]);\n\t}\n}\n\nstatic inline void memcpy_ident32(void *dst, const void *src, size_t n) {\n\tmemcpy(dst, src, 4 * n);\n}\nstatic inline void memcpy_ident64(void *dst, const void *src, size_t n) {\n\tmemcpy(dst, src, 8 * n);\n}\n\nstatic inline void memcpy_swap32(void *dst, const void *src, size_t n) {\n\tsize_t i;\n\tfor (i = 0; i < n; i++) {\n\t\t((uint32_t *)dst)[i] = swap32(((const uint32_t *)src)[i]);\n\t}\n}\nstatic inline void memcpy_swap64(void *dst, const void *src, size_t n) {\n\tsize_t i;\n\tfor (i = 0; i < n; i++) {\n\t\t((uint64_t *)dst)[i] = swap64(((const uint64_t *)src)[i]);\n\t}\n}\n\n#define SWAP32LE IDENT32\n#define SWAP32BE SWAP32\n#define swap32le ident32\n#define swap32be swap32\n#define mem_inplace_swap32le mem_inplace_ident\n#define mem_inplace_swap32be mem_inplace_swap32\n#define memcpy_swap32le memcpy_ident32\n#define memcpy_swap32be memcpy_swap32\n#define SWAP64LE IDENT64\n#define SWAP64BE SWAP64\n#define swap64le ident64\n#define swap64be swap64\n#define mem_inplace_swap64le mem_inplace_ident\n#define mem_inplace_swap64be mem_inplace_swap64\n#define memcpy_swap64le memcpy_ident64\n#define memcpy_swap64be memcpy_swap64"
  },
  {
    "path": "crypto/skein_port.h",
    "content": "#ifndef _SKEIN_PORT_H_\n#define _SKEIN_PORT_H_\n\n#include <limits.h>\n#include <stdint.h>\n#include <stddef.h>\n\n#ifndef RETURN_VALUES\n#  define RETURN_VALUES\n#  if defined( DLL_EXPORT )\n#    if defined( _MSC_VER ) || defined ( __INTEL_COMPILER )\n#      define VOID_RETURN    __declspec( dllexport ) void __stdcall\n#      define INT_RETURN     __declspec( dllexport ) int  __stdcall\n#    elif defined( __GNUC__ )\n#      define VOID_RETURN    __declspec( __dllexport__ ) void\n#      define INT_RETURN     __declspec( __dllexport__ ) int\n#    else\n#      error Use of the DLL is only available on the Microsoft, Intel and GCC compilers\n#    endif\n#  elif defined( DLL_IMPORT )\n#    if defined( _MSC_VER ) || defined ( __INTEL_COMPILER )\n#      define VOID_RETURN    __declspec( dllimport ) void __stdcall\n#      define INT_RETURN     __declspec( dllimport ) int  __stdcall\n#    elif defined( __GNUC__ )\n#      define VOID_RETURN    __declspec( __dllimport__ ) void\n#      define INT_RETURN     __declspec( __dllimport__ ) int\n#    else\n#      error Use of the DLL is only available on the Microsoft, Intel and GCC compilers\n#    endif\n#  elif defined( __WATCOMC__ )\n#    define VOID_RETURN  void __cdecl\n#    define INT_RETURN   int  __cdecl\n#  else\n#    define VOID_RETURN  void\n#    define INT_RETURN   int\n#  endif\n#endif\n\n/*  These defines are used to declare buffers in a way that allows\n\tfaster operations on longer variables to be used.  In all these\n\tdefines 'size' must be a power of 2 and >= 8\n\n\tdec_unit_type(size,x)       declares a variable 'x' of length\n\t\t\t\t\t\t\t\t'size' bits\n\n\tdec_bufr_type(size,bsize,x) declares a buffer 'x' of length 'bsize'\n\t\t\t\t\t\t\t\tbytes defined as an array of variables\n\t\t\t\t\t\t\t\teach of 'size' bits (bsize must be a\n\t\t\t\t\t\t\t\tmultiple of size / 8)\n\n\tptr_cast(x,size)            casts a pointer to a pointer to a\n\t\t\t\t\t\t\t\tvaraiable of length 'size' bits\n*/\n\n#define ui_type(size)               uint##size##_t\n#define dec_unit_type(size,x)       typedef ui_type(size) x\n#define dec_bufr_type(size,bsize,x) typedef ui_type(size) x[bsize / (size >> 3)]\n#define ptr_cast(x,size)            ((ui_type(size)*)(x))\n\ntypedef unsigned int    uint_t;             /* native unsigned integer */\ntypedef uint8_t         u08b_t;             /*  8-bit unsigned integer */\ntypedef uint64_t        u64b_t;             /* 64-bit unsigned integer */\n\n#ifndef RotL_64\n#define RotL_64(x,N)    (((x) << (N)) | ((x) >> (64-(N))))\n#endif\n\n/*\n * Skein is \"natively\" little-endian (unlike SHA-xxx), for optimal\n * performance on x86 CPUs.  The Skein code requires the following\n * definitions for dealing with endianness:\n *\n *    SKEIN_NEED_SWAP:  0 for little-endian, 1 for big-endian\n *    Skein_Put64_LSB_First\n *    Skein_Get64_LSB_First\n *    Skein_Swap64\n *\n * If SKEIN_NEED_SWAP is defined at compile time, it is used here\n * along with the portable versions of Put64/Get64/Swap64, which\n * are slow in general.\n *\n * Otherwise, an \"auto-detect\" of endianness is attempted below.\n * If the default handling doesn't work well, the user may insert\n * platform-specific code instead (e.g., for big-endian CPUs).\n *\n */\n#ifndef SKEIN_NEED_SWAP /* compile-time \"override\" for endianness? */\n\n#define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN\n\n/* special handler for IA64, which may be either endianness (?)  */\n/* here we assume little-endian, but this may need to be changed */\n#if defined(__ia64) || defined(__ia64__) || defined(_M_IA64)\n#  define PLATFORM_MUST_ALIGN (1)\n#ifndef PLATFORM_BYTE_ORDER\n#  define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN\n#endif\n#endif\n\n#ifndef   PLATFORM_MUST_ALIGN\n#  define PLATFORM_MUST_ALIGN (0)\n#endif\n\n\n#if   PLATFORM_BYTE_ORDER == IS_BIG_ENDIAN\n\t/* here for big-endian CPUs */\n#define SKEIN_NEED_SWAP   (1)\n#elif PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN\n\t/* here for x86 and x86-64 CPUs (and other detected little-endian CPUs) */\n#define SKEIN_NEED_SWAP   (0)\n#if   PLATFORM_MUST_ALIGN == 0              /* ok to use \"fast\" versions? */\n#define Skein_Put64_LSB_First(dst08,src64,bCnt) memcpy(dst08,src64,bCnt)\n#define Skein_Get64_LSB_First(dst64,src08,wCnt) memcpy(dst64,src08,8*(wCnt))\n#endif\n#else\n#error \"Skein needs endianness setting!\"\n#endif\n\n#endif /* ifndef SKEIN_NEED_SWAP */\n\n/*\n ******************************************************************\n *      Provide any definitions still needed.\n ******************************************************************\n */\n#ifndef Skein_Swap64  /* swap for big-endian, nop for little-endian */\n#if     SKEIN_NEED_SWAP\n#define Skein_Swap64(w64)                       \\\n  ( (( ((u64b_t)(w64))       & 0xFF) << 56) |   \\\n\t(((((u64b_t)(w64)) >> 8) & 0xFF) << 48) |   \\\n\t(((((u64b_t)(w64)) >>16) & 0xFF) << 40) |   \\\n\t(((((u64b_t)(w64)) >>24) & 0xFF) << 32) |   \\\n\t(((((u64b_t)(w64)) >>32) & 0xFF) << 24) |   \\\n\t(((((u64b_t)(w64)) >>40) & 0xFF) << 16) |   \\\n\t(((((u64b_t)(w64)) >>48) & 0xFF) <<  8) |   \\\n\t(((((u64b_t)(w64)) >>56) & 0xFF)      ) )\n#else\n#define Skein_Swap64(w64)  (w64)\n#endif\n#endif  /* ifndef Skein_Swap64 */\n\n\n#ifndef Skein_Put64_LSB_First\nvoid    Skein_Put64_LSB_First(u08b_t *dst,const u64b_t *src,size_t bCnt)\n#ifdef  SKEIN_PORT_CODE /* instantiate the function code here? */\n\t{ /* this version is fully portable (big-endian or little-endian), but slow */\n\tsize_t n;\n\n\tfor (n=0;n<bCnt;n++)\n\t\tdst[n] = (u08b_t) (src[n>>3] >> (8*(n&7)));\n\t}\n#else\n\t;    /* output only the function prototype */\n#endif\n#endif   /* ifndef Skein_Put64_LSB_First */\n\n\n#ifndef Skein_Get64_LSB_First\nvoid    Skein_Get64_LSB_First(u64b_t *dst,const u08b_t *src,size_t wCnt)\n#ifdef  SKEIN_PORT_CODE /* instantiate the function code here? */\n\t{ /* this version is fully portable (big-endian or little-endian), but slow */\n\tsize_t n;\n\n\tfor (n=0;n<8*wCnt;n+=8)\n\t\tdst[n/8] = (((u64b_t) src[n  ])      ) +\n\t\t\t\t   (((u64b_t) src[n+1]) <<  8) +\n\t\t\t\t   (((u64b_t) src[n+2]) << 16) +\n\t\t\t\t   (((u64b_t) src[n+3]) << 24) +\n\t\t\t\t   (((u64b_t) src[n+4]) << 32) +\n\t\t\t\t   (((u64b_t) src[n+5]) << 40) +\n\t\t\t\t   (((u64b_t) src[n+6]) << 48) +\n\t\t\t\t   (((u64b_t) src[n+7]) << 56) ;\n\t}\n#else\n\t;    /* output only the function prototype */\n#endif\n#endif   /* ifndef Skein_Get64_LSB_First */\n\n#endif   /* ifndef _SKEIN_PORT_H_ */\n"
  },
  {
    "path": "crypto/soft_aes.c",
    "content": "/*\n  * This program is free software: you can redistribute it and/or modify\n  * it under the terms of the GNU General Public License as published by\n  * the Free Software Foundation, either version 3 of the License, or\n  * any later version.\n  *\n  * This program is distributed in the hope that it will be useful,\n  * but WITHOUT ANY WARRANTY; without even the implied warranty of\n  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n  * GNU General Public License for more details.\n  *\n  * You should have received a copy of the GNU General Public License\n  * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n  *\n  * Additional permission under GNU GPL version 3 section 7\n  *\n  * If you modify this Program, or any covered work, by linking or combining\n  * it with OpenSSL (or a modified version of that library), containing parts\n  * covered by the terms of OpenSSL License and SSLeay License, the licensors\n  * of this Program grant you additional permission to convey the resulting work.\n  *\n  */\n\n/*\n * The orginal author of this AES implementation is Karl Malbrain.\n */\n\n#ifdef __GNUC__\n#include <x86intrin.h>\n#else\n#include <intrin.h>\n#endif // __GNUC__\n\n#include <inttypes.h>\n\n#define TABLE_ALIGN     32\n#define WPOLY           0x011b\n#define N_COLS          4\n#define AES_BLOCK_SIZE  16\n#define RC_LENGTH       (5 * (AES_BLOCK_SIZE / 4 - 2))\n\n#if defined(_MSC_VER)\n#define ALIGN __declspec(align(TABLE_ALIGN))\n#elif defined(__GNUC__)\n#define ALIGN __attribute__ ((aligned(16)))\n#else\n#define ALIGN\n#endif\n\n#define rf1(r,c) (r)\n#define word_in(x,c) (*((uint32_t*)(x)+(c)))\n#define word_out(x,c,v) (*((uint32_t*)(x)+(c)) = (v))\n\n#define s(x,c) x[c]\n#define si(y,x,c) (s(y,c) = word_in(x, c))\n#define so(y,x,c) word_out(y, c, s(x,c))\n#define state_in(y,x) si(y,x,0); si(y,x,1); si(y,x,2); si(y,x,3)\n#define state_out(y,x)  so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)\n#define round(y,x,k) \\\ny[0] = (k)[0]  ^ (t_fn[0][x[0] & 0xff] ^ t_fn[1][(x[1] >> 8) & 0xff] ^ t_fn[2][(x[2] >> 16) & 0xff] ^ t_fn[3][x[3] >> 24]); \\\ny[1] = (k)[1]  ^ (t_fn[0][x[1] & 0xff] ^ t_fn[1][(x[2] >> 8) & 0xff] ^ t_fn[2][(x[3] >> 16) & 0xff] ^ t_fn[3][x[0] >> 24]); \\\ny[2] = (k)[2]  ^ (t_fn[0][x[2] & 0xff] ^ t_fn[1][(x[3] >> 8) & 0xff] ^ t_fn[2][(x[0] >> 16) & 0xff] ^ t_fn[3][x[1] >> 24]); \\\ny[3] = (k)[3]  ^ (t_fn[0][x[3] & 0xff] ^ t_fn[1][(x[0] >> 8) & 0xff] ^ t_fn[2][(x[1] >> 16) & 0xff] ^ t_fn[3][x[2] >> 24]);\n#define to_byte(x) ((x) & 0xff)\n#define bval(x,n) to_byte((x) >> (8 * (n)))\n\n#define fwd_var(x,r,c)\\\n ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\\\n : r == 1 ? ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))\\\n : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\\\n :          ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2)))\n\n#define fwd_rnd(y,x,k,c)  (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,n),fwd_var,rf1,c))\n\n#define sb_data(w) {\\\n    w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\\\n    w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), w(0xab), w(0x76),\\\n    w(0xca), w(0x82), w(0xc9), w(0x7d), w(0xfa), w(0x59), w(0x47), w(0xf0),\\\n    w(0xad), w(0xd4), w(0xa2), w(0xaf), w(0x9c), w(0xa4), w(0x72), w(0xc0),\\\n    w(0xb7), w(0xfd), w(0x93), w(0x26), w(0x36), w(0x3f), w(0xf7), w(0xcc),\\\n    w(0x34), w(0xa5), w(0xe5), w(0xf1), w(0x71), w(0xd8), w(0x31), w(0x15),\\\n    w(0x04), w(0xc7), w(0x23), w(0xc3), w(0x18), w(0x96), w(0x05), w(0x9a),\\\n    w(0x07), w(0x12), w(0x80), w(0xe2), w(0xeb), w(0x27), w(0xb2), w(0x75),\\\n    w(0x09), w(0x83), w(0x2c), w(0x1a), w(0x1b), w(0x6e), w(0x5a), w(0xa0),\\\n    w(0x52), w(0x3b), w(0xd6), w(0xb3), w(0x29), w(0xe3), w(0x2f), w(0x84),\\\n    w(0x53), w(0xd1), w(0x00), w(0xed), w(0x20), w(0xfc), w(0xb1), w(0x5b),\\\n    w(0x6a), w(0xcb), w(0xbe), w(0x39), w(0x4a), w(0x4c), w(0x58), w(0xcf),\\\n    w(0xd0), w(0xef), w(0xaa), w(0xfb), w(0x43), w(0x4d), w(0x33), w(0x85),\\\n    w(0x45), w(0xf9), w(0x02), w(0x7f), w(0x50), w(0x3c), w(0x9f), w(0xa8),\\\n    w(0x51), w(0xa3), w(0x40), w(0x8f), w(0x92), w(0x9d), w(0x38), w(0xf5),\\\n    w(0xbc), w(0xb6), w(0xda), w(0x21), w(0x10), w(0xff), w(0xf3), w(0xd2),\\\n    w(0xcd), w(0x0c), w(0x13), w(0xec), w(0x5f), w(0x97), w(0x44), w(0x17),\\\n    w(0xc4), w(0xa7), w(0x7e), w(0x3d), w(0x64), w(0x5d), w(0x19), w(0x73),\\\n    w(0x60), w(0x81), w(0x4f), w(0xdc), w(0x22), w(0x2a), w(0x90), w(0x88),\\\n    w(0x46), w(0xee), w(0xb8), w(0x14), w(0xde), w(0x5e), w(0x0b), w(0xdb),\\\n    w(0xe0), w(0x32), w(0x3a), w(0x0a), w(0x49), w(0x06), w(0x24), w(0x5c),\\\n    w(0xc2), w(0xd3), w(0xac), w(0x62), w(0x91), w(0x95), w(0xe4), w(0x79),\\\n    w(0xe7), w(0xc8), w(0x37), w(0x6d), w(0x8d), w(0xd5), w(0x4e), w(0xa9),\\\n    w(0x6c), w(0x56), w(0xf4), w(0xea), w(0x65), w(0x7a), w(0xae), w(0x08),\\\n    w(0xba), w(0x78), w(0x25), w(0x2e), w(0x1c), w(0xa6), w(0xb4), w(0xc6),\\\n    w(0xe8), w(0xdd), w(0x74), w(0x1f), w(0x4b), w(0xbd), w(0x8b), w(0x8a),\\\n    w(0x70), w(0x3e), w(0xb5), w(0x66), w(0x48), w(0x03), w(0xf6), w(0x0e),\\\n    w(0x61), w(0x35), w(0x57), w(0xb9), w(0x86), w(0xc1), w(0x1d), w(0x9e),\\\n    w(0xe1), w(0xf8), w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), w(0x94),\\\n    w(0x9b), w(0x1e), w(0x87), w(0xe9), w(0xce), w(0x55), w(0x28), w(0xdf),\\\n    w(0x8c), w(0xa1), w(0x89), w(0x0d), w(0xbf), w(0xe6), w(0x42), w(0x68),\\\n    w(0x41), w(0x99), w(0x2d), w(0x0f), w(0xb0), w(0x54), w(0xbb), w(0x16) }\n\n#define rc_data(w) {\\\n    w(0x01), w(0x02), w(0x04), w(0x08), w(0x10),w(0x20), w(0x40), w(0x80),\\\n    w(0x1b), w(0x36) }\n\n#define bytes2word(b0, b1, b2, b3) (((uint32_t)(b3) << 24) | \\\n    ((uint32_t)(b2) << 16) | ((uint32_t)(b1) << 8) | (b0))\n\n#define h0(x)   (x)\n#define w0(p)   bytes2word(p, 0, 0, 0)\n#define w1(p)   bytes2word(0, p, 0, 0)\n#define w2(p)   bytes2word(0, 0, p, 0)\n#define w3(p)   bytes2word(0, 0, 0, p)\n\n#define u0(p)   bytes2word(f2(p), p, p, f3(p))\n#define u1(p)   bytes2word(f3(p), f2(p), p, p)\n#define u2(p)   bytes2word(p, f3(p), f2(p), p)\n#define u3(p)   bytes2word(p, p, f3(p), f2(p))\n\n#define v0(p)   bytes2word(fe(p), f9(p), fd(p), fb(p))\n#define v1(p)   bytes2word(fb(p), fe(p), f9(p), fd(p))\n#define v2(p)   bytes2word(fd(p), fb(p), fe(p), f9(p))\n#define v3(p)   bytes2word(f9(p), fd(p), fb(p), fe(p))\n\n#define f2(x)   ((x<<1) ^ (((x>>7) & 1) * WPOLY))\n#define f4(x)   ((x<<2) ^ (((x>>6) & 1) * WPOLY) ^ (((x>>6) & 2) * WPOLY))\n#define f8(x)   ((x<<3) ^ (((x>>5) & 1) * WPOLY) ^ (((x>>5) & 2) * WPOLY) ^ (((x>>5) & 4) * WPOLY))\n#define f3(x)   (f2(x) ^ x)\n#define f9(x)   (f8(x) ^ x)\n#define fb(x)   (f8(x) ^ f2(x) ^ x)\n#define fd(x)   (f8(x) ^ f4(x) ^ x)\n#define fe(x)   (f8(x) ^ f4(x) ^ f2(x))\n\n#define t_dec(m,n) t_##m##n\n#define t_set(m,n) t_##m##n\n#define t_use(m,n) t_##m##n\n\n#define d_4(t,n,b,e,f,g,h) ALIGN const t n[4][256] = { b(e), b(f), b(g), b(h) }\n\n#define four_tables(x,tab,vf,rf,c) \\\n    (tab[0][bval(vf(x,0,c),rf(0,c))] \\\n    ^ tab[1][bval(vf(x,1,c),rf(1,c))] \\\n    ^ tab[2][bval(vf(x,2,c),rf(2,c))] \\\n    ^ tab[3][bval(vf(x,3,c),rf(3,c))])\n\nd_4(uint32_t, t_dec(f,n), sb_data, u0, u1, u2, u3);\n\n__m128i soft_aesenc(__m128i in, __m128i key)\n{\n\tuint32_t x0, x1, x2, x3;\n\tx0 = _mm_cvtsi128_si32(in);\n\tx1 = _mm_cvtsi128_si32(_mm_shuffle_epi32(in, 0x55));\n\tx2 = _mm_cvtsi128_si32(_mm_shuffle_epi32(in, 0xAA));\n\tx3 = _mm_cvtsi128_si32(_mm_shuffle_epi32(in, 0xFF));\n\n\t__m128i out = _mm_set_epi32(\n\t\t(t_fn[0][x3 & 0xff] ^ t_fn[1][(x0 >> 8) & 0xff] ^ t_fn[2][(x1 >> 16) & 0xff] ^ t_fn[3][x2 >> 24]),\n\t\t(t_fn[0][x2 & 0xff] ^ t_fn[1][(x3 >> 8) & 0xff] ^ t_fn[2][(x0 >> 16) & 0xff] ^ t_fn[3][x1 >> 24]),\n\t\t(t_fn[0][x1 & 0xff] ^ t_fn[1][(x2 >> 8) & 0xff] ^ t_fn[2][(x3 >> 16) & 0xff] ^ t_fn[3][x0 >> 24]),\n\t\t(t_fn[0][x0 & 0xff] ^ t_fn[1][(x1 >> 8) & 0xff] ^ t_fn[2][(x2 >> 16) & 0xff] ^ t_fn[3][x3 >> 24]));\n\n\treturn _mm_xor_si128(out, key);\n}\n\nuint8_t Sbox[256] = {\t\t// forward s-box\n0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,\n0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,\n0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,\n0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,\n0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,\n0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,\n0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,\n0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,\n0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,\n0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,\n0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,\n0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,\n0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,\n0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,\n0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,\n0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16};\n\nstatic inline void sub_word(uint8_t* key)\n{\n\tkey[0] = Sbox[key[0]];\n\tkey[1] = Sbox[key[1]];\n\tkey[2] = Sbox[key[2]];\n\tkey[3] = Sbox[key[3]];\n}\n\n#ifdef __clang__\nuint32_t _rotr(uint32_t value, uint32_t amount)\n{\n\treturn (value >> amount) | (value << ((32 - amount) & 31));\n}\n#endif\n\n__m128i soft_aeskeygenassist(__m128i key, uint8_t rcon)\n{\n\tuint32_t X1 = _mm_cvtsi128_si32(_mm_shuffle_epi32(key, 0x55));\n\tuint32_t X3 = _mm_cvtsi128_si32(_mm_shuffle_epi32(key, 0xFF));\n\tsub_word((uint8_t*)&X1);\n\tsub_word((uint8_t*)&X3);\n\treturn _mm_set_epi32(_rotr(X3, 8) ^ rcon, X3,_rotr(X1, 8) ^ rcon, X1);\n}\n"
  },
  {
    "path": "donate-level.h",
    "content": "#pragma once\n\n/*\n * Dev donation.\n * Percentage of your hashing power that you want to donate to the developer, can be 0.0 if you don't want to do that.\n * Example of how it works for the default setting of 1.0:\n * You miner will mine into your usual pool for 99 minutes, then switch to the developer's pool for 1.0 minute.\n * Switching is instant, and only happens after a successful connection, so you never loose any hashes.\n *\n * If you plan on changing this setting to 0.0 please consider making a one off donation to my wallet:\n * 4581HhZkQHgZrZjKeCfCJxZff9E3xCgHGF25zABZz7oR71TnbbgiS7sK9jveE6Dx6uMs2LwszDuvQJgRZQotdpHt1fTdDhk\n *\n */\n\nconstexpr double fDevDonationLevel = 1.0 / 100.0;\n"
  },
  {
    "path": "executor.cpp",
    "content": "/*\n  * This program is free software: you can redistribute it and/or modify\n  * it under the terms of the GNU General Public License as published by\n  * the Free Software Foundation, either version 3 of the License, or\n  * any later version.\n  *\n  * This program is distributed in the hope that it will be useful,\n  * but WITHOUT ANY WARRANTY; without even the implied warranty of\n  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n  * GNU General Public License for more details.\n  *\n  * You should have received a copy of the GNU General Public License\n  * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n  *\n  * Additional permission under GNU GPL version 3 section 7\n  *\n  * If you modify this Program, or any covered work, by linking or combining\n  * it with OpenSSL (or a modified version of that library), containing parts\n  * covered by the terms of OpenSSL License and SSLeay License, the licensors\n  * of this Program grant you additional permission to convey the resulting work.\n  *\n  */\n\n#include <thread>\n#include <string>\n#include <cmath>\n#include <algorithm>\n#include <assert.h>\n#include <time.h>\n#include \"executor.h\"\n#include \"jpsock.h\"\n#include \"minethd.h\"\n#include \"jconf.h\"\n#include \"console.h\"\n#include \"donate-level.h\"\n#include \"webdesign.h\"\n\n#ifdef __GNUC__\n#include <mm_malloc.h>\n#else\n#include <malloc.h>\n#endif // __GNUC__\n\n#ifdef _WIN32\n#define strncasecmp _strnicmp\n#endif // _WIN32\n\nexecutor* executor::oInst = NULL;\n\nexecutor::executor()\n{\n\tcpu_ctx = (cryptonight_ctx*)_mm_malloc(sizeof(cryptonight_ctx), 4096);\n}\n\nvoid executor::push_timed_event(ex_event&& ev, size_t sec)\n{\n\tstd::unique_lock<std::mutex> lck(timed_event_mutex);\n\tlTimedEvents.emplace_back(std::move(ev), sec_to_ticks(sec));\n}\n\nvoid executor::ex_clock_thd()\n{\n\tsize_t iSwitchPeriod = sec_to_ticks(iDevDonatePeriod);\n\tsize_t iDevPortion = (size_t)floor(((double)iSwitchPeriod) * fDevDonationLevel);\n\n\t//No point in bothering with less than 10 sec\n\tif(iDevPortion < sec_to_ticks(10))\n\t\tiDevPortion = 0;\n\n\t//Add 2 seconds to compensate for connect\n\tif(iDevPortion != 0)\n\t\tiDevPortion += sec_to_ticks(2);\n\n\twhile (true)\n\t{\n\t\tstd::this_thread::sleep_for(std::chrono::milliseconds(size_t(iTickTime)));\n\n\t\tpush_event(ex_event(EV_PERF_TICK));\n\n\t\t// Service timed events\n\t\tstd::unique_lock<std::mutex> lck(timed_event_mutex);\n\t\tstd::list<timed_event>::iterator ev = lTimedEvents.begin();\n\t\twhile (ev != lTimedEvents.end())\n\t\t{\n\t\t\tev->ticks_left--;\n\t\t\tif(ev->ticks_left == 0)\n\t\t\t{\n\t\t\t\tpush_event(std::move(ev->event));\n\t\t\t\tev = lTimedEvents.erase(ev);\n\t\t\t}\n\t\t\telse\n\t\t\t\tev++;\n\t\t}\n\t\tlck.unlock();\n\n\t\tif(iDevPortion == 0)\n\t\t\tcontinue;\n\n\t\tiSwitchPeriod--;\n\t\tif(iSwitchPeriod == 0)\n\t\t{\n\t\t\tpush_event(ex_event(EV_SWITCH_POOL, usr_pool_id));\n\t\t\tiSwitchPeriod = sec_to_ticks(iDevDonatePeriod);\n\t\t}\n\t\telse if(iSwitchPeriod == iDevPortion)\n\t\t{\n\t\t\tpush_event(ex_event(EV_SWITCH_POOL, dev_pool_id));\n\t\t}\n\t}\n}\n\nvoid executor::sched_reconnect()\n{\n\tiReconnectAttempts++;\n\tsize_t iLimit = jconf::inst()->GetGiveUpLimit();\n\tif(iLimit != 0 && iReconnectAttempts > iLimit)\n\t{\n\t\tprinter::inst()->print_msg(L0, \"Give up limit reached. Exitting.\");\n\t\texit(0);\n\t}\n\n\tlong long unsigned int rt = jconf::inst()->GetNetRetry();\n\tprinter::inst()->print_msg(L1, \"Pool connection lost. Waiting %lld s before retry (attempt %llu).\",\n\t\trt, int_port(iReconnectAttempts));\n\n\tauto work = minethd::miner_work();\n\tminethd::switch_work(work);\n\n\tpush_timed_event(ex_event(EV_RECONNECT, usr_pool_id), rt);\n}\n\nvoid executor::log_socket_error(std::string&& sError)\n{\n\tvSocketLog.emplace_back(std::move(sError));\n\tprinter::inst()->print_msg(L1, \"SOCKET ERROR - %s\", vSocketLog.back().msg.c_str());\n}\n\nvoid executor::log_result_error(std::string&& sError)\n{\n\tsize_t i = 1, ln = vMineResults.size();\n\tfor(; i < ln; i++)\n\t{\n\t\tif(vMineResults[i].compare(sError))\n\t\t{\n\t\t\tvMineResults[i].increment();\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif(i == ln) //Not found\n\t\tvMineResults.emplace_back(std::move(sError));\n\telse\n\t\tsError.clear();\n}\n\nvoid executor::log_result_ok(uint64_t iActualDiff)\n{\n\tiPoolHashes += iPoolDiff;\n\n\tsize_t ln = iTopDiff.size() - 1;\n\tif(iActualDiff > iTopDiff[ln])\n\t{\n\t\tiTopDiff[ln] = iActualDiff;\n\t\tstd::sort(iTopDiff.rbegin(), iTopDiff.rend());\n\t}\n\n\tvMineResults[0].increment();\n}\n\njpsock* executor::pick_pool_by_id(size_t pool_id)\n{\n\tassert(pool_id != invalid_pool_id);\n\n\tif(pool_id == dev_pool_id)\n\t\treturn dev_pool;\n\telse\n\t\treturn usr_pool;\n}\n\nvoid executor::on_sock_ready(size_t pool_id)\n{\n\tjpsock* pool = pick_pool_by_id(pool_id);\n\n\tif(pool_id == dev_pool_id)\n\t{\n\t\tif(!pool->cmd_login(\"\", \"\"))\n\t\t\tpool->disconnect();\n\n\t\tcurrent_pool_id = dev_pool_id;\n\t\tprinter::inst()->print_msg(L1, \"Dev pool logged in. Switching work.\");\n\t\treturn;\n\t}\n\n\tprinter::inst()->print_msg(L1, \"Connected. Logging in...\");\n\n\tif (!pool->cmd_login(jconf::inst()->GetWalletAddress(), jconf::inst()->GetPoolPwd()))\n\t{\n\t\tif(!pool->have_sock_error())\n\t\t{\n\t\t\tlog_socket_error(pool->get_call_error());\n\t\t\tpool->disconnect();\n\t\t}\n\t}\n\telse\n\t{\n\t\tiReconnectAttempts = 0;\n\t\treset_stats();\n\t}\n}\n\nvoid executor::on_sock_error(size_t pool_id, std::string&& sError)\n{\n\tjpsock* pool = pick_pool_by_id(pool_id);\n\n\tif(pool_id == dev_pool_id)\n\t{\n\t\tpool->disconnect();\n\n\t\tif(current_pool_id != dev_pool_id)\n\t\t\treturn;\n\n\t\tprinter::inst()->print_msg(L1, \"Dev pool connection error. Switching work.\");\n\t\ton_switch_pool(usr_pool_id);\n\t\treturn;\n\t}\n\n\tlog_socket_error(std::move(sError));\n\tpool->disconnect();\n\tsched_reconnect();\n}\n\nvoid executor::on_pool_have_job(size_t pool_id, pool_job& oPoolJob)\n{\n\tif(pool_id != current_pool_id)\n\t\treturn;\n\n\tjpsock* pool = pick_pool_by_id(pool_id);\n\n\tminethd::miner_work oWork(oPoolJob.sJobID, oPoolJob.bWorkBlob,\n\t\toPoolJob.iWorkLen, oPoolJob.iResumeCnt, oPoolJob.iTarget, pool_id);\n\n\tminethd::switch_work(oWork);\n\n\tif(pool_id == dev_pool_id)\n\t\treturn;\n\n\tif(iPoolDiff != pool->get_current_diff())\n\t{\n\t\tiPoolDiff = pool->get_current_diff();\n\t\tprinter::inst()->print_msg(L2, \"Difficulty changed. Now: %llu.\", int_port(iPoolDiff));\n\t}\n\n\tprinter::inst()->print_msg(L3, \"New block detected.\");\n}\n\nvoid executor::on_miner_result(size_t pool_id, job_result& oResult)\n{\n\tjpsock* pool = pick_pool_by_id(pool_id);\n\n\t*(uint32_t*)(oResult.bWorkBlob + 39) = oResult.iNonce;\n\n\tif(jconf::inst()->HaveHardwareAes())\n\t\tcryptonight_hash_ctx(oResult.bWorkBlob, oResult.iWorkLen, oResult.bResult, cpu_ctx);\n\telse\n\t\tcryptonight_hash_ctx_soft(oResult.bWorkBlob, oResult.iWorkLen, oResult.bResult, cpu_ctx);\n\n\tbool bVerified = ((uint32_t*)oResult.bResult)[7] < oResult.iTarget;\n\n\tif(pool_id == dev_pool_id)\n\t{\n\t\t//Ignore errors silently\n\t\tif(pool->is_running() && pool->is_logged_in() && bVerified)\n\t\t\tpool->cmd_submit(oResult.sJobID, oResult.iNonce, oResult.bResult);\n\n\t\treturn;\n\t}\n\n\tif (!bVerified)\n\t{\n\t\tlog_result_error(\"[GPU COMPUTE ERROR]\");\n\t\treturn;\n\t}\n\n\tif (!pool->is_running() || !pool->is_logged_in())\n\t{\n\t\tlog_result_error(\"[NETWORK ERROR]\");\n\t\treturn;\n\t}\n\n\tusing namespace std::chrono;\n\tsize_t t_start = time_point_cast<milliseconds>(high_resolution_clock::now()).time_since_epoch().count();\n\tbool bResult = pool->cmd_submit(oResult.sJobID, oResult.iNonce, oResult.bResult);\n\tsize_t t_len = time_point_cast<milliseconds>(high_resolution_clock::now()).time_since_epoch().count() - t_start;\n\n\tif(t_len > 0xFFFF)\n\t\tt_len = 0xFFFF;\n\tiPoolCallTimes.push_back((uint16_t)t_len);\n\n\tif(bResult)\n\t{\n\t\tuint64_t* targets = (uint64_t*)oResult.bResult;\n\t\tlog_result_ok(jpsock::t64_to_diff(targets[3]));\n\t\tprinter::inst()->print_msg(L3, \"Result accepted by the pool.\");\n\t}\n\telse\n\t{\n\t\tif(!pool->have_sock_error())\n\t\t{\n\t\t\tprinter::inst()->print_msg(L3, \"Result rejected by the pool.\");\n\n\t\t\tstd::string error = pool->get_call_error();\n\n\t\t\tif(strncasecmp(error.c_str(), \"Unauthenticated\", 15) == 0)\n\t\t\t{\n\t\t\t\tprinter::inst()->print_msg(L2, \"Your miner was unable to find a share in time. Either the pool difficulty is too high, or the pool timeout is too low.\");\n\t\t\t\tpool->disconnect();\n\t\t\t}\n\n\t\t\tlog_result_error(std::move(error));\n\t\t}\n\t\telse\n\t\t\tlog_result_error(\"[NETWORK ERROR]\");\n\t}\n}\n\nvoid executor::on_reconnect(size_t pool_id)\n{\n\tjpsock* pool = pick_pool_by_id(pool_id);\n\n\tstd::string error;\n\tif(pool_id == dev_pool_id)\n\t\treturn;\n\n\tprinter::inst()->print_msg(L1, \"Connecting to pool %s ...\", jconf::inst()->GetPoolAddress());\n\n\tif(!pool->connect(jconf::inst()->GetPoolAddress(), error))\n\t{\n\t\tlog_socket_error(std::move(error));\n\t\tsched_reconnect();\n\t}\n}\n\nvoid executor::on_switch_pool(size_t pool_id)\n{\n\tif(pool_id == current_pool_id)\n\t\treturn;\n\n\tjpsock* pool = pick_pool_by_id(pool_id);\n\tif(pool_id == dev_pool_id)\n\t{\n\t\tstd::string error;\n\n\t\t// If it fails, it fails, we carry on on the usr pool\n\t\t// as we never receive further events\n\t\tprinter::inst()->print_msg(L1, \"Connecting to dev pool...\");\n\t\tconst char* dev_pool_addr = jconf::inst()->GetTlsSetting() ? \"donate.xmr-stak.net:6666\" : \"donate.xmr-stak.net:3333\";\n\t\tif(!pool->connect(dev_pool_addr, error))\n\t\t\tprinter::inst()->print_msg(L1, \"Error connecting to dev pool. Staying with user pool.\");\n\t}\n\telse\n\t{\n\t\tprinter::inst()->print_msg(L1, \"Switching back to user pool.\");\n\n\t\tcurrent_pool_id = pool_id;\n\t\tpool_job oPoolJob;\n\n\t\tif(!pool->get_current_job(oPoolJob))\n\t\t{\n\t\t\tpool->disconnect();\n\t\t\treturn;\n\t\t}\n\n\t\tminethd::miner_work oWork(oPoolJob.sJobID, oPoolJob.bWorkBlob,\n\t\t\toPoolJob.iWorkLen, oPoolJob.iResumeCnt, oPoolJob.iTarget, pool_id);\n\n\t\tminethd::switch_work(oWork);\n\n\t\tif(dev_pool->is_running())\n\t\t\tpush_timed_event(ex_event(EV_DEV_POOL_EXIT), 5);\n\t}\n}\n\nvoid executor::ex_main()\n{\n\tassert(1000 % iTickTime == 0);\n\n\tminethd::miner_work oWork = minethd::miner_work();\n\tpvThreads = minethd::thread_starter(oWork);\n\ttelem = new telemetry(pvThreads->size());\n\n\tcurrent_pool_id = usr_pool_id;\n\tusr_pool = new jpsock(usr_pool_id, jconf::inst()->GetTlsSetting());\n\tdev_pool = new jpsock(dev_pool_id, jconf::inst()->GetTlsSetting());\n\n\tex_event ev;\n\tstd::thread clock_thd(&executor::ex_clock_thd, this);\n\n\t//This will connect us to the pool for the first time\n\tpush_event(ex_event(EV_RECONNECT, usr_pool_id));\n\n\t// Place the default success result at postion 0, it needs to\n\t// be here even if our first result is a failure\n\tvMineResults.emplace_back();\n\n\t// If the user requested it, start the autohash printer\n\tif(jconf::inst()->GetVerboseLevel() >= 4)\n\t\tpush_timed_event(ex_event(EV_HASHRATE_LOOP), jconf::inst()->GetAutohashTime());\n\n\tsize_t cnt = 0, i;\n\twhile (true)\n\t{\n\t\tev = oEventQ.pop();\n\t\tswitch (ev.iName)\n\t\t{\n\t\tcase EV_SOCK_READY:\n\t\t\ton_sock_ready(ev.iPoolId);\n\t\t\tbreak;\n\n\t\tcase EV_SOCK_ERROR:\n\t\t\ton_sock_error(ev.iPoolId, std::move(ev.sSocketError));\n\t\t\tbreak;\n\n\t\tcase EV_POOL_HAVE_JOB:\n\t\t\ton_pool_have_job(ev.iPoolId, ev.oPoolJob);\n\t\t\tbreak;\n\n\t\tcase EV_MINER_HAVE_RESULT:\n\t\t\ton_miner_result(ev.iPoolId, ev.oJobResult);\n\t\t\tbreak;\n\n\t\tcase EV_RECONNECT:\n\t\t\ton_reconnect(ev.iPoolId);\n\t\t\tbreak;\n\n\t\tcase EV_SWITCH_POOL:\n\t\t\ton_switch_pool(ev.iPoolId);\n\t\t\tbreak;\n\n\t\tcase EV_DEV_POOL_EXIT:\n\t\t\tdev_pool->disconnect();\n\t\t\tbreak;\n\n\t\tcase EV_PERF_TICK:\n\t\t\tfor (i = 0; i < pvThreads->size(); i++)\n\t\t\t\ttelem->push_perf_value(i, pvThreads->at(i)->iHashCount.load(std::memory_order_relaxed),\n\t\t\t\tpvThreads->at(i)->iTimestamp.load(std::memory_order_relaxed));\n\n\t\t\tif((cnt++ & 0xF) == 0) //Every 16 ticks\n\t\t\t{\n\t\t\t\tdouble fHps = 0.0;\n\t\t\t\tfor (i = 0; i < pvThreads->size(); i++)\n\t\t\t\t\tfHps += telem->calc_telemetry_data(10000, i);\n\n\t\t\t\tif(fHighestHps < fHps)\n\t\t\t\t\tfHighestHps = fHps;\n\t\t\t}\n\t\tbreak;\n\n\t\tcase EV_USR_HASHRATE:\n\t\tcase EV_USR_RESULTS:\n\t\tcase EV_USR_CONNSTAT:\n\t\t\tprint_report(ev.iName);\n\t\t\tbreak;\n\n\t\tcase EV_HTML_HASHRATE:\n\t\tcase EV_HTML_RESULTS:\n\t\tcase EV_HTML_CONNSTAT:\n\t\t\thttp_report(ev.iName);\n\t\t\tbreak;\n\n\t\tcase EV_HASHRATE_LOOP:\n\t\t\tprint_report(EV_USR_HASHRATE);\n\t\t\tpush_timed_event(ex_event(EV_HASHRATE_LOOP), jconf::inst()->GetAutohashTime());\n\t\t\tbreak;\n\n\t\tcase EV_INVALID_VAL:\n\t\tdefault:\n\t\t\tassert(false);\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\ninline const char* hps_format(double h, char* buf, size_t l)\n{\n\tif(std::isnormal(h) || h == 0.0)\n\t{\n\t\tsnprintf(buf, l, \" %03.1f\", h);\n\t\treturn buf;\n\t}\n\telse\n\t\treturn \"  (na)\";\n}\n\nvoid executor::hashrate_report(std::string& out)\n{\n\tchar num[32];\n\tsize_t nthd = pvThreads->size();\n\n\tout.reserve(256 + nthd * 64);\n\n\tdouble fTotal[3] = { 0.0, 0.0, 0.0};\n\tsize_t i;\n\n\tout.append(\"HASHRATE REPORT\\n\");\n\tout.append(\"| ID |   10s |   60s |   15m |\");\n\tif(nthd != 1)\n\t\tout.append(\" ID |   10s |   60s |   15m |\\n\");\n\telse\n\t\tout.append(1, '\\n');\n\n\tfor (i = 0; i < nthd; i++)\n\t{\n\t\tdouble fHps[3];\n\n\t\tfHps[0] = telem->calc_telemetry_data(10000, i);\n\t\tfHps[1] = telem->calc_telemetry_data(60000, i);\n\t\tfHps[2] = telem->calc_telemetry_data(900000, i);\n\n\t\tsnprintf(num, sizeof(num), \"| %2u |\", (unsigned int)i);\n\t\tout.append(num);\n\t\tout.append(hps_format(fHps[0], num, sizeof(num))).append(\" |\");\n\t\tout.append(hps_format(fHps[1], num, sizeof(num))).append(\" |\");\n\t\tout.append(hps_format(fHps[2], num, sizeof(num))).append(1, ' ');\n\n\t\tfTotal[0] += fHps[0];\n\t\tfTotal[1] += fHps[1];\n\t\tfTotal[2] += fHps[2];\n\n\t\tif((i & 0x1) == 1) //Odd i's\n\t\t\tout.append(\"|\\n\");\n\t}\n\n\tif((i & 0x1) == 1) //We had odd number of threads\n\t\tout.append(\"|\\n\");\n\n\tif(nthd != 1)\n\t\tout.append(\"-----------------------------------------------------\\n\");\n\telse\n\t\tout.append(\"---------------------------\\n\");\n\n\tout.append(\"Totals:  \");\n\tout.append(hps_format(fTotal[0], num, sizeof(num)));\n\tout.append(hps_format(fTotal[1], num, sizeof(num)));\n\tout.append(hps_format(fTotal[2], num, sizeof(num)));\n\tout.append(\" H/s\\nHighest: \");\n\tout.append(hps_format(fHighestHps, num, sizeof(num)));\n\tout.append(\" H/s\\n\");\n}\n\nchar* time_format(char* buf, size_t len, std::chrono::system_clock::time_point time)\n{\n\ttime_t ctime = std::chrono::system_clock::to_time_t(time);\n\ttm stime;\n\n\t/*\n\t * Oh for god's sake... this feels like we are back to the 90's...\n\t * and don't get me started on lack strcpy_s because NIH - use non-standard strlcpy...\n\t * And of course C++ implements unsafe version because... reasons\n\t */\n\n#ifdef _WIN32\n\tlocaltime_s(&stime, &ctime);\n#else\n\tlocaltime_r(&ctime, &stime);\n#endif // __WIN32\n\tstrftime(buf, len, \"%F %T\", &stime);\n\n\treturn buf;\n}\n\nvoid executor::result_report(std::string& out)\n{\n\tchar num[128];\n\tchar date[32];\n\n\tout.reserve(1024);\n\n\tsize_t iGoodRes = vMineResults[0].count, iTotalRes = iGoodRes;\n\tsize_t ln = vMineResults.size();\n\n\tfor(size_t i=1; i < ln; i++)\n\t\tiTotalRes += vMineResults[i].count;\n\n\tout.append(\"RESULT REPORT\\n\");\n\tif(iTotalRes == 0)\n\t{\n\t\tout.append(\"You haven't found any results yet.\\n\");\n\t\treturn;\n\t}\n\n\tdouble dConnSec;\n\t{\n\t\tusing namespace std::chrono;\n\t\tdConnSec = (double)duration_cast<seconds>(system_clock::now() - tPoolConnTime).count();\n\t}\n\n\tsnprintf(num, sizeof(num), \" (%.1f %%)\\n\", 100.0 * iGoodRes / iTotalRes);\n\n\tout.append(\"Difficulty       : \").append(std::to_string(iPoolDiff)).append(1, '\\n');\n\tout.append(\"Good results     : \").append(std::to_string(iGoodRes)).append(\" / \").\n\t\tappend(std::to_string(iTotalRes)).append(num);\n\n\tif(iPoolCallTimes.size() != 0)\n\t{\n\t\t// Here we use iPoolCallTimes since it also gets reset when we disconnect\n\t\tsnprintf(num, sizeof(num), \"%.1f sec\\n\", dConnSec / iPoolCallTimes.size());\n\t\tout.append(\"Avg result time  : \").append(num);\n\t}\n\tout.append(\"Pool-side hashes : \").append(std::to_string(iPoolHashes)).append(2, '\\n');\n\tout.append(\"Top 10 best results found:\\n\");\n\n\tfor(size_t i=0; i < 10; i += 2)\n\t{\n\t\tsnprintf(num, sizeof(num), \"| %2llu | %16llu | %2llu | %16llu |\\n\",\n\t\t\tint_port(i), int_port(iTopDiff[i]), int_port(i+1), int_port(iTopDiff[i+1]));\n\t\tout.append(num);\n\t}\n\n\tout.append(\"\\nError details:\\n\");\n\tif(ln > 1)\n\t{\n\t\tout.append(\"| Count | Error text                       | Last seen           |\\n\");\n\t\tfor(size_t i=1; i < ln; i++)\n\t\t{\n\t\t\tsnprintf(num, sizeof(num), \"| %5llu | %-32.32s | %s |\\n\", int_port(vMineResults[i].count),\n\t\t\t\tvMineResults[i].msg.c_str(), time_format(date, sizeof(date), vMineResults[i].time));\n\t\t\tout.append(num);\n\t\t}\n\t}\n\telse\n\t\tout.append(\"Yay! No errors.\\n\");\n}\n\nvoid executor::connection_report(std::string& out)\n{\n\tchar num[128];\n\tchar date[32];\n\n\tout.reserve(512);\n\n\tjpsock* pool = pick_pool_by_id(dev_pool_id + 1);\n\n\tout.append(\"CONNECTION REPORT\\n\");\n\tif (pool->is_running() && pool->is_logged_in())\n\t\tout.append(\"Connected since : \").append(time_format(date, sizeof(date), tPoolConnTime)).append(1, '\\n');\n\telse\n\t\tout.append(\"Connected since : <not connected>\\n\");\n\n\tsize_t n_calls = iPoolCallTimes.size();\n\tif (n_calls > 1)\n\t{\n\t\t//Not-really-but-good-enough median\n\t\tstd::nth_element(iPoolCallTimes.begin(), iPoolCallTimes.begin() + n_calls/2, iPoolCallTimes.end());\n\t\tout.append(\"Pool ping time  : \").append(std::to_string(iPoolCallTimes[n_calls/2])).append(\" ms\\n\");\n\t}\n\telse\n\t\tout.append(\"Pool ping time  : (n/a)\\n\");\n\n\tout.append(\"\\nNetwork error log:\\n\");\n\tsize_t ln = vSocketLog.size();\n\tif(ln > 0)\n\t{\n\t\tout.append(\"| Date                | Error text                                             |\\n\");\n\t\tfor(size_t i=0; i < ln; i++)\n\t\t{\n\t\t\tsnprintf(num, sizeof(num), \"| %s | %-54.54s |\\n\",\n\t\t\t\ttime_format(date, sizeof(date), vSocketLog[i].time), vSocketLog[i].msg.c_str());\n\t\t\tout.append(num);\n\t\t}\n\t}\n\telse\n\t\tout.append(\"Yay! No errors.\\n\");\n}\n\nvoid executor::print_report(ex_event_name ev)\n{\n\tstd::string out;\n\tswitch(ev)\n\t{\n\tcase EV_USR_HASHRATE:\n\t\thashrate_report(out);\n\t\tbreak;\n\n\tcase EV_USR_RESULTS:\n\t\tresult_report(out);\n\t\tbreak;\n\n\tcase EV_USR_CONNSTAT:\n\t\tconnection_report(out);\n\t\tbreak;\n\tdefault:\n\t\tassert(false);\n\t\tbreak;\n\t}\n\n\tprinter::inst()->print_str(out.c_str());\n}\n\nvoid executor::http_hashrate_report(std::string& out)\n{\n\tchar num_a[32], num_b[32], num_c[32], num_d[32];\n\tchar buffer[4096];\n\tsize_t nthd = pvThreads->size();\n\n\tout.reserve(4096);\n\n\tsnprintf(buffer, sizeof(buffer), sHtmlCommonHeader, \"Hashrate Report\", \"Hashrate Report\");\n\tout.append(buffer);\n\n\tsnprintf(buffer, sizeof(buffer), sHtmlHashrateBodyHigh, (unsigned int)nthd + 3);\n\tout.append(buffer);\n\n\tdouble fTotal[3] = { 0.0, 0.0, 0.0};\n\tfor(size_t i=0; i < nthd; i++)\n\t{\n\t\tdouble fHps[3];\n\n\t\tfHps[0] = telem->calc_telemetry_data(10000, i);\n\t\tfHps[1] = telem->calc_telemetry_data(60000, i);\n\t\tfHps[2] = telem->calc_telemetry_data(900000, i);\n\n\t\tnum_a[0] = num_b[0] = num_c[0] ='\\0';\n\t\thps_format(fHps[0], num_a, sizeof(num_a));\n\t\thps_format(fHps[1], num_b, sizeof(num_b));\n\t\thps_format(fHps[2], num_c, sizeof(num_c));\n\n\t\tfTotal[0] += fHps[0];\n\t\tfTotal[1] += fHps[1];\n\t\tfTotal[2] += fHps[2];\n\n\t\tsnprintf(buffer, sizeof(buffer), sHtmlHashrateTableRow, (unsigned int)i, num_a, num_b, num_c);\n\t\tout.append(buffer);\n\t}\n\n\tnum_a[0] = num_b[0] = num_c[0] = num_d[0] ='\\0';\n\thps_format(fTotal[0], num_a, sizeof(num_a));\n\thps_format(fTotal[1], num_b, sizeof(num_b));\n\thps_format(fTotal[2], num_c, sizeof(num_c));\n\thps_format(fHighestHps, num_d, sizeof(num_d));\n\n\tsnprintf(buffer, sizeof(buffer), sHtmlHashrateBodyLow, num_a, num_b, num_c, num_d);\n\tout.append(buffer);\n}\n\nvoid executor::http_result_report(std::string& out)\n{\n\tchar date[128];\n\tchar buffer[4096];\n\n\tout.reserve(4096);\n\n\tsnprintf(buffer, sizeof(buffer), sHtmlCommonHeader, \"Result Report\", \"Result Report\");\n\tout.append(buffer);\n\n\tsize_t iGoodRes = vMineResults[0].count, iTotalRes = iGoodRes;\n\tsize_t ln = vMineResults.size();\n\n\tfor(size_t i=1; i < ln; i++)\n\t\tiTotalRes += vMineResults[i].count;\n\n\tdouble fGoodResPrc = 0.0;\n\tif(iTotalRes > 0)\n\t\tfGoodResPrc = 100.0 * iGoodRes / iTotalRes;\n\n\tdouble fAvgResTime = 0.0;\n\tif(iPoolCallTimes.size() > 0)\n\t{\n\t\tusing namespace std::chrono;\n\t\tfAvgResTime = ((double)duration_cast<seconds>(system_clock::now() - tPoolConnTime).count())\n\t\t\t/ iPoolCallTimes.size();\n\t}\n\n\tsnprintf(buffer, sizeof(buffer), sHtmlResultBodyHigh,\n\t\tiPoolDiff, iGoodRes, iTotalRes, fGoodResPrc, fAvgResTime, iPoolHashes,\n\t\tint_port(iTopDiff[0]), int_port(iTopDiff[1]), int_port(iTopDiff[2]), int_port(iTopDiff[3]),\n\t\tint_port(iTopDiff[4]), int_port(iTopDiff[5]), int_port(iTopDiff[6]), int_port(iTopDiff[7]),\n\t\tint_port(iTopDiff[8]), int_port(iTopDiff[9]));\n\n\tout.append(buffer);\n\n\tfor(size_t i=1; i < vMineResults.size(); i++)\n\t{\n\t\tsnprintf(buffer, sizeof(buffer), sHtmlResultTableRow, vMineResults[i].msg.c_str(),\n\t\t\tint_port(vMineResults[i].count), time_format(date, sizeof(date), vMineResults[i].time));\n\t\tout.append(buffer);\n\t}\n\n\tout.append(sHtmlResultBodyLow);\n}\n\nvoid executor::http_connection_report(std::string& out)\n{\n\tchar date[128];\n\tchar buffer[4096];\n\n\tout.reserve(4096);\n\n\tsnprintf(buffer, sizeof(buffer), sHtmlCommonHeader, \"Connection Report\", \"Connection Report\");\n\tout.append(buffer);\n\n\tjpsock* pool = pick_pool_by_id(dev_pool_id + 1);\n\tconst char* cdate = \"not connected\";\n\tif (pool->is_running() && pool->is_logged_in())\n\t\tcdate = time_format(date, sizeof(date), tPoolConnTime);\n\n\tsize_t n_calls = iPoolCallTimes.size();\n\tunsigned int ping_time = 0;\n\tif (n_calls > 1)\n\t{\n\t\t//Not-really-but-good-enough median\n\t\tstd::nth_element(iPoolCallTimes.begin(), iPoolCallTimes.begin() + n_calls/2, iPoolCallTimes.end());\n\t\tping_time = iPoolCallTimes[n_calls/2];\n\t}\n\n\tsnprintf(buffer, sizeof(buffer), sHtmlConnectionBodyHigh,\n\t\tjconf::inst()->GetPoolAddress(),\n\t\tcdate, ping_time);\n\tout.append(buffer);\n\n\n\tfor(size_t i=0; i < vSocketLog.size(); i++)\n\t{\n\t\tsnprintf(buffer, sizeof(buffer), sHtmlConnectionTableRow,\n\t\t\ttime_format(date, sizeof(date), vSocketLog[i].time), vSocketLog[i].msg.c_str());\n\t\tout.append(buffer);\n\t}\n\n\tout.append(sHtmlConnectionBodyLow);\n}\n\nvoid executor::http_report(ex_event_name ev)\n{\n\tassert(pHttpString != nullptr);\n\n\tswitch(ev)\n\t{\n\tcase EV_HTML_HASHRATE:\n\t\thttp_hashrate_report(*pHttpString);\n\t\tbreak;\n\n\tcase EV_HTML_RESULTS:\n\t\thttp_result_report(*pHttpString);\n\t\tbreak;\n\n\tcase EV_HTML_CONNSTAT:\n\t\thttp_connection_report(*pHttpString);\n\t\tbreak;\n\tdefault:\n\t\tassert(false);\n\t\tbreak;\n\t}\n\n\thttpReady.set_value();\n}\n\nvoid executor::get_http_report(ex_event_name ev_id, std::string& data)\n{\n\tstd::lock_guard<std::mutex> lck(httpMutex);\n\n\tassert(pHttpString == nullptr);\n\tassert(ev_id == EV_HTML_HASHRATE || ev_id == EV_HTML_RESULTS || ev_id == EV_HTML_CONNSTAT);\n\n\tpHttpString = &data;\n\thttpReady = std::promise<void>();\n\tstd::future<void> ready = httpReady.get_future();\n\n\tpush_event(ex_event(ev_id));\n\n\tready.wait();\n\tpHttpString = nullptr;\n}\n"
  },
  {
    "path": "executor.h",
    "content": "#pragma once\n#include \"thdq.hpp\"\n#include \"msgstruct.h\"\n#include <atomic>\n#include <array>\n#include <list>\n#include <future>\n\n#include \"crypto/cryptonight.h\"\n\nclass jpsock;\nclass minethd;\nclass telemetry;\n\nclass executor\n{\npublic:\n\tstatic executor* inst()\n\t{\n\t\tif (oInst == nullptr) oInst = new executor;\n\t\treturn oInst;\n\t};\n\n\tvoid ex_start(bool daemon) { daemon ? ex_main() : std::thread(&executor::ex_main, this).detach(); }\n\n\tvoid get_http_report(ex_event_name ev_id, std::string& data);\n\n\tinline void push_event(ex_event&& ev) { oEventQ.push(std::move(ev)); }\n\tvoid push_timed_event(ex_event&& ev, size_t sec);\n\n\tconstexpr static size_t invalid_pool_id = 0;\n\tconstexpr static size_t dev_pool_id = 1;\n\tconstexpr static size_t usr_pool_id = 2;\n\nprivate:\n\tstruct timed_event\n\t{\n\t\tex_event event;\n\t\tsize_t ticks_left;\n\n\t\ttimed_event(ex_event&& ev, size_t ticks) : event(std::move(ev)), ticks_left(ticks) {}\n\t};\n\n\tcryptonight_ctx* cpu_ctx;\n\n\t// In miliseconds, has to divide a second (1000ms) into an integer number\n\tconstexpr static size_t iTickTime = 500;\n\n\t// Dev donation time period in seconds. 100 minutes by default.\n\t// We will divide up this period according to the config setting\n\tconstexpr static size_t iDevDonatePeriod = 100 * 60;\n\n\tstd::list<timed_event> lTimedEvents;\n\tstd::mutex timed_event_mutex;\n\tthdq<ex_event> oEventQ;\n\n\ttelemetry* telem;\n\tstd::vector<minethd*>* pvThreads;\n\n\tsize_t current_pool_id;\n\n\tjpsock* usr_pool;\n\tjpsock* dev_pool;\n\n\tjpsock* pick_pool_by_id(size_t pool_id);\n\n\tbool is_dev_time;\n\n\texecutor();\n\tstatic executor* oInst;\n\n\tvoid ex_main();\n\n\tvoid ex_clock_thd();\n\tvoid pool_connect(jpsock* pool);\n\n\tvoid hashrate_report(std::string& out);\n\tvoid result_report(std::string& out);\n\tvoid connection_report(std::string& out);\n\n\tvoid http_hashrate_report(std::string& out);\n\tvoid http_result_report(std::string& out);\n\tvoid http_connection_report(std::string& out);\n\n\tvoid http_report(ex_event_name ev);\n\tvoid print_report(ex_event_name ev);\n\n\tstd::string* pHttpString = nullptr;\n\tstd::promise<void> httpReady;\n\tstd::mutex httpMutex;\n\n\tsize_t iReconnectAttempts = 0;\n\n\tstruct sck_error_log\n\t{\n\t\tstd::chrono::system_clock::time_point time;\n\t\tstd::string msg;\n\n\t\tsck_error_log(std::string&& err) : msg(std::move(err))\n\t\t{\n\t\t\ttime = std::chrono::system_clock::now();\n\t\t}\n\t};\n\tstd::vector<sck_error_log> vSocketLog;\n\n\t// Element zero is always the success element.\n\t// Keep in mind that this is a tally and not a log like above\n\tstruct result_tally\n\t{\n\t\tstd::chrono::system_clock::time_point time;\n\t\tstd::string msg;\n\t\tsize_t count;\n\n\t\tresult_tally() : msg(\"[OK]\"), count(0)\n\t\t{\n\t\t\ttime = std::chrono::system_clock::now();\n\t\t}\n\n\t\tresult_tally(std::string&& err) : msg(std::move(err)), count(1)\n\t\t{\n\t\t\ttime = std::chrono::system_clock::now();\n\t\t}\n\n\t\tvoid increment()\n\t\t{\n\t\t\tcount++;\n\t\t\ttime = std::chrono::system_clock::now();\n\t\t}\n\n\t\tbool compare(std::string& err)\n\t\t{\n\t\t\tif(msg == err)\n\t\t\t{\n\t\t\t\tincrement();\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse\n\t\t\t\treturn false;\n\t\t}\n\t};\n\tstd::vector<result_tally> vMineResults;\n\n\t//More result statistics\n\tstd::array<size_t, 10> iTopDiff { { } }; //Initialize to zero\n\n\tstd::chrono::system_clock::time_point tPoolConnTime;\n\tsize_t iPoolHashes = 0;\n\tuint64_t iPoolDiff = 0;\n\n\t// Set it to 16 bit so that we can just let it grow\n\t// Maximum realistic growth rate - 5MB / month\n\tstd::vector<uint16_t> iPoolCallTimes;\n\n\t//Those stats are reset if we disconnect\n\tinline void reset_stats()\n\t{\n\t\tiPoolCallTimes.clear();\n\t\ttPoolConnTime = std::chrono::system_clock::now();\n\t\tiPoolHashes = 0;\n\t\tiPoolDiff = 0;\n\t}\n\n\tdouble fHighestHps = 0.0;\n\n\tvoid log_socket_error(std::string&& sError);\n\tvoid log_result_error(std::string&& sError);\n\tvoid log_result_ok(uint64_t iActualDiff);\n\n\tvoid sched_reconnect();\n\n\tvoid on_sock_ready(size_t pool_id);\n\tvoid on_sock_error(size_t pool_id, std::string&& sError);\n\tvoid on_pool_have_job(size_t pool_id, pool_job& oPoolJob);\n\tvoid on_miner_result(size_t pool_id, job_result& oResult);\n\tvoid on_reconnect(size_t pool_id);\n\tvoid on_switch_pool(size_t pool_id);\n\n\tinline size_t sec_to_ticks(size_t sec) { return sec * (1000 / iTickTime); }\n};\n\n"
  },
  {
    "path": "httpd.cpp",
    "content": "/*\n  * This program is free software: you can redistribute it and/or modify\n  * it under the terms of the GNU General Public License as published by\n  * the Free Software Foundation, either version 3 of the License, or\n  * any later version.\n  *\n  * This program is distributed in the hope that it will be useful,\n  * but WITHOUT ANY WARRANTY; without even the implied warranty of\n  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n  * GNU General Public License for more details.\n  *\n  * You should have received a copy of the GNU General Public License\n  * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n  *\n  * Additional permission under GNU GPL version 3 section 7\n  *\n  * If you modify this Program, or any covered work, by linking or combining\n  * it with OpenSSL (or a modified version of that library), containing parts\n  * covered by the terms of OpenSSL License and SSLeay License, the licensors\n  * of this Program grant you additional permission to convey the resulting work.\n  *\n  */\n\n#ifndef CONF_NO_HTTPD\n\n#include <stdlib.h>\n#include <stdio.h>\n#include <string.h>\n#include <string>\n\n#include \"msgstruct.h\"\n#include \"httpd.h\"\n#include \"console.h\"\n#include \"executor.h\"\n#include \"jconf.h\"\n\n#include \"webdesign.h\"\n\n#ifdef _WIN32\n#include \"libmicrohttpd/microhttpd.h\"\n#define strcasecmp _stricmp\n#else\n#include <microhttpd.h>\n#endif // _WIN32\n\nhttpd* httpd::oInst = nullptr;\n\nhttpd::httpd()\n{\n\n}\n\nint httpd::req_handler(void * cls,\n\t        MHD_Connection* connection,\n\t        const char* url,\n\t        const char* method,\n\t        const char* version,\n\t        const char* upload_data,\n\t        size_t* upload_data_size,\n\t        void ** ptr)\n{\n\tstruct MHD_Response * rsp;\n\n\tif (strcmp(method, \"GET\") != 0)\n\t\treturn MHD_NO;\n\n\t*ptr = nullptr;\n\n\tstd::string str;\n\tif(strcasecmp(url, \"/style.css\") == 0)\n\t{\n\t\tconst char* req_etag = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, \"If-None-Match\");\n\n\t\tif(req_etag != NULL && strcmp(req_etag, sHtmlCssEtag) == 0)\n\t\t{ //Cache hit\n\t\t\trsp = MHD_create_response_from_buffer(0, nullptr, MHD_RESPMEM_PERSISTENT);\n\n\t\t\tint ret = MHD_queue_response(connection, MHD_HTTP_NOT_MODIFIED, rsp);\n\t\t\tMHD_destroy_response(rsp);\n\t\t\treturn ret;\n\t\t}\n\n\t\trsp = MHD_create_response_from_buffer(sHtmlCssSize, (void*)sHtmlCssFile, MHD_RESPMEM_PERSISTENT);\n\t\tMHD_add_response_header(rsp, \"ETag\", sHtmlCssEtag);\n\t\tMHD_add_response_header(rsp, \"Content-Type\", \"text/css; charset=utf-8\");\n\t}\n\telse if(strcasecmp(url, \"/h\") == 0 || strcasecmp(url, \"/hashrate\") == 0)\n\t{\n\t\texecutor::inst()->get_http_report(EV_HTML_HASHRATE, str);\n\n\t\trsp = MHD_create_response_from_buffer(str.size(), (void*)str.c_str(), MHD_RESPMEM_MUST_COPY);\n\t\tMHD_add_response_header(rsp, \"Content-Type\", \"text/html; charset=utf-8\");\n\t}\n\telse if(strcasecmp(url, \"/c\") == 0 || strcasecmp(url, \"/connection\") == 0)\n\t{\n\t\texecutor::inst()->get_http_report(EV_HTML_CONNSTAT, str);\n\n\t\trsp = MHD_create_response_from_buffer(str.size(), (void*)str.c_str(), MHD_RESPMEM_MUST_COPY);\n\t\tMHD_add_response_header(rsp, \"Content-Type\", \"text/html; charset=utf-8\");\n\t}\n\telse if(strcasecmp(url, \"/r\") == 0 || strcasecmp(url, \"/results\") == 0)\n\t{\n\t\texecutor::inst()->get_http_report(EV_HTML_RESULTS, str);\n\n\t\trsp = MHD_create_response_from_buffer(str.size(), (void*)str.c_str(), MHD_RESPMEM_MUST_COPY);\n\t\tMHD_add_response_header(rsp, \"Content-Type\", \"text/html; charset=utf-8\");\n\t}\n\telse\n\t{\n\t\t//Do a 302 redirect to /h\n\t\tchar loc_path[256];\n\t\tconst char* host_val = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, \"Host\");\n\n\t\tif(host_val != nullptr)\n\t\t\tsnprintf(loc_path, sizeof(loc_path), \"http://%s/h\", host_val);\n\t\telse\n\t\t\tsnprintf(loc_path, sizeof(loc_path), \"/h\");\n\n\t\trsp = MHD_create_response_from_buffer(0, nullptr, MHD_RESPMEM_PERSISTENT);\n\t\tint ret = MHD_queue_response(connection, MHD_HTTP_TEMPORARY_REDIRECT, rsp);\n\t\tMHD_add_response_header(rsp, \"Location\", loc_path);\n\t\tMHD_destroy_response(rsp);\n\t\treturn ret;\n\t}\n\n\tint ret = MHD_queue_response(connection, MHD_HTTP_OK, rsp);\n\tMHD_destroy_response(rsp);\n\treturn ret;\n}\n\nbool httpd::start_daemon()\n{\n\td = MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION,\n\t\tjconf::inst()->GetHttpdPort(), NULL, NULL,\n\t\t&httpd::req_handler,\n\t\tNULL, MHD_OPTION_END);\n\n\tif(d == nullptr)\n\t{\n\t\tprinter::inst()->print_str(\"HTTP Daemon failed to start.\");\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\n#endif\n\n"
  },
  {
    "path": "httpd.h",
    "content": "#pragma once\n\nstruct MHD_Daemon;\nstruct MHD_Connection;\n\nclass httpd\n{\npublic:\n\tstatic httpd* inst()\n\t{\n\t\tif (oInst == nullptr) oInst = new httpd;\n\t\treturn oInst;\n\t};\n\n\tbool start_daemon();\n\nprivate:\n\thttpd();\n\tstatic httpd* oInst;\n\n\tstatic int req_handler(void * cls,\n\t        MHD_Connection* connection,\n\t        const char* url,\n\t        const char* method,\n\t        const char* version,\n\t        const char* upload_data,\n\t        size_t* upload_data_size,\n\t        void ** ptr);\n\n\tMHD_Daemon *d;\n};\n"
  },
  {
    "path": "jconf.cpp",
    "content": "/*\n  * This program is free software: you can redistribute it and/or modify\n  * it under the terms of the GNU General Public License as published by\n  * the Free Software Foundation, either version 3 of the License, or\n  * any later version.\n  *\n  * This program is distributed in the hope that it will be useful,\n  * but WITHOUT ANY WARRANTY; without even the implied warranty of\n  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n  * GNU General Public License for more details.\n  *\n  * You should have received a copy of the GNU General Public License\n  * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n  *\n  * Additional permission under GNU GPL version 3 section 7\n  *\n  * If you modify this Program, or any covered work, by linking or combining\n  * it with OpenSSL (or a modified version of that library), containing parts\n  * covered by the terms of OpenSSL License and SSLeay License, the licensors\n  * of this Program grant you additional permission to convey the resulting work.\n  *\n  */\n\n#include \"jconf.h\"\n#include \"console.h\"\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#ifdef _WIN32\n#define strcasecmp _stricmp\n#include <intrin.h>\n#else\n#include <cpuid.h>\n#endif\n\n#include \"rapidjson/document.h\"\n#include \"rapidjson/error/en.h\"\n#include \"jext.h\"\n#include \"console.h\"\n\nusing namespace rapidjson;\n\n/*\n * This enum needs to match index in oConfigValues, otherwise we will get a runtime error\n */\nenum configEnum { iGpuThreadNum, aGpuThreadsConf, iPlatformIdx,\n\tbTlsMode, bTlsSecureAlgo, sTlsFingerprint, sPoolAddr, sWalletAddr, sPoolPwd,\n\tiCallTimeout, iNetRetry, iGiveUpLimit, iVerboseLevel, iAutohashTime,\n\tbDaemonMode, sOutputFile, iHttpdPort, bPreferIpv4 };\n\nstruct configVal {\n\tconfigEnum iName;\n\tconst char* sName;\n\tType iType;\n};\n\n//Same order as in configEnum, as per comment above\nconfigVal oConfigValues[] = {\n\t{ iGpuThreadNum, \"gpu_thread_num\", kNumberType },\n\t{ aGpuThreadsConf, \"gpu_threads_conf\", kArrayType },\n\t{ iPlatformIdx, \"platform_index\", kNumberType },\n\t{ bTlsMode, \"use_tls\", kTrueType },\n\t{ bTlsSecureAlgo, \"tls_secure_algo\", kTrueType },\n\t{ sTlsFingerprint, \"tls_fingerprint\", kStringType },\n\t{ sPoolAddr, \"pool_address\", kStringType },\n\t{ sWalletAddr, \"wallet_address\", kStringType },\n\t{ sPoolPwd, \"pool_password\", kStringType },\n\t{ iCallTimeout, \"call_timeout\", kNumberType },\n\t{ iNetRetry, \"retry_time\", kNumberType },\n\t{ iGiveUpLimit, \"giveup_limit\", kNumberType },\n\t{ iVerboseLevel, \"verbose_level\", kNumberType },\n\t{ iAutohashTime, \"h_print_time\", kNumberType },\n\t{ bDaemonMode, \"daemon_mode\", kTrueType },\n\t{ sOutputFile, \"output_file\", kStringType },\n\t{ iHttpdPort, \"httpd_port\", kNumberType },\n\t{ bPreferIpv4, \"prefer_ipv4\", kTrueType }\n};\n\nconstexpr size_t iConfigCnt = (sizeof(oConfigValues)/sizeof(oConfigValues[0]));\n\ninline bool checkType(Type have, Type want)\n{\n\tif(want == have)\n\t\treturn true;\n\telse if(want == kTrueType && have == kFalseType)\n\t\treturn true;\n\telse if(want == kFalseType && have == kTrueType)\n\t\treturn true;\n\telse\n\t\treturn false;\n}\n\nstruct jconf::opaque_private\n{\n\tDocument jsonDoc;\n\tconst Value* configValues[iConfigCnt]; //Compile time constant\n\n\topaque_private()\n\t{\n\t}\n};\n\njconf* jconf::oInst = nullptr;\n\njconf::jconf()\n{\n\tprv = new opaque_private();\n}\n\nbool jconf::GetThreadConfig(size_t id, thd_cfg &cfg)\n{\n\tif(id >= prv->configValues[aGpuThreadsConf]->Size())\n\t\treturn false;\n\n\tconst Value& oThdConf = prv->configValues[aGpuThreadsConf]->GetArray()[id];\n\n\tif(!oThdConf.IsObject())\n\t\treturn false;\n\n\tconst Value *idx, *intensity, *w_size, *aff;\n\tidx = GetObjectMember(oThdConf, \"index\");\n\tintensity = GetObjectMember(oThdConf, \"intensity\");\n\tw_size = GetObjectMember(oThdConf, \"worksize\");\n\taff = GetObjectMember(oThdConf, \"affine_to_cpu\");\n\n\tif(idx == nullptr || intensity == nullptr || w_size == nullptr || aff == nullptr)\n\t\treturn false;\n\n\tif(!idx->IsUint64() || !intensity->IsUint64() || !w_size->IsUint64())\n\t\treturn false;\n\n\tif(!aff->IsUint64() && !aff->IsBool())\n\t\treturn false;\n\n\tcfg.index = idx->GetUint64();\n\tcfg.intensity = intensity->GetUint64();\n\tcfg.w_size = w_size->GetUint64();\n\n\tif(aff->IsNumber())\n\t\tcfg.cpu_aff = aff->GetInt64();\n\telse\n\t\tcfg.cpu_aff = -1;\n\n\treturn true;\n}\n\nsize_t jconf::GetPlatformIdx()\n{\n\treturn prv->configValues[iPlatformIdx]->GetUint64();\n}\n\nbool jconf::GetTlsSetting()\n{\n\treturn prv->configValues[bTlsMode]->GetBool();\n}\n\nbool jconf::TlsSecureAlgos()\n{\n\treturn prv->configValues[bTlsSecureAlgo]->GetBool();\n}\n\nconst char* jconf::GetTlsFingerprint()\n{\n\treturn prv->configValues[sTlsFingerprint]->GetString();\n}\n\nconst char* jconf::GetPoolAddress()\n{\n\treturn prv->configValues[sPoolAddr]->GetString();\n}\n\nconst char* jconf::GetPoolPwd()\n{\n\treturn prv->configValues[sPoolPwd]->GetString();\n}\n\nconst char* jconf::GetWalletAddress()\n{\n\treturn prv->configValues[sWalletAddr]->GetString();\n}\n\nbool jconf::PreferIpv4()\n{\n\treturn prv->configValues[bPreferIpv4]->GetBool();\n}\n\nsize_t jconf::GetThreadCount()\n{\n\treturn prv->configValues[aGpuThreadsConf]->Size();\n}\n\nuint64_t jconf::GetCallTimeout()\n{\n\treturn prv->configValues[iCallTimeout]->GetUint64();\n}\n\nuint64_t jconf::GetNetRetry()\n{\n\treturn prv->configValues[iNetRetry]->GetUint64();\n}\n\nuint64_t jconf::GetGiveUpLimit()\n{\n\treturn prv->configValues[iGiveUpLimit]->GetUint64();\n}\n\nuint64_t jconf::GetVerboseLevel()\n{\n\treturn prv->configValues[iVerboseLevel]->GetUint64();\n}\n\nuint64_t jconf::GetAutohashTime()\n{\n\treturn prv->configValues[iAutohashTime]->GetUint64();\n}\n\nuint16_t jconf::GetHttpdPort()\n{\n\treturn prv->configValues[iHttpdPort]->GetUint();\n}\n\nbool jconf::DaemonMode()\n{\n\treturn prv->configValues[bDaemonMode]->GetBool();\n}\n\nconst char* jconf::GetOutputFile()\n{\n\treturn prv->configValues[sOutputFile]->GetString();\n}\n\nbool jconf::check_cpu_features()\n{\n\tconstexpr int AESNI_BIT = 1 << 25;\n\tconstexpr int SSE2_BIT = 1 << 26;\n\n\tint cpu_info[4];\n#ifdef _WIN32\n\t__cpuid(cpu_info, 1);\n#else\n\t__cpuid(1, cpu_info[0], cpu_info[1], cpu_info[2], cpu_info[3]);\n#endif\n\n\tbHaveAes = (cpu_info[2] & AESNI_BIT) != 0;\n\treturn (cpu_info[3] & SSE2_BIT) != 0;\n}\n\nbool jconf::parse_config(const char* sFilename)\n{\n\tFILE * pFile;\n\tchar * buffer;\n\tsize_t flen;\n\n\tif(!check_cpu_features())\n\t{\n\t\tprinter::inst()->print_msg(L0, \"CPU support of SSE2 is required.\");\n\t\treturn false;\n\t}\n\n\tpFile = fopen(sFilename, \"rb\");\n\tif (pFile == NULL)\n\t{\n\t\tprinter::inst()->print_msg(L0, \"Failed to open config file %s.\", sFilename);\n\t\treturn false;\n\t}\n\n\tfseek(pFile,0,SEEK_END);\n\tflen = ftell(pFile);\n\trewind(pFile);\n\n\tif(flen >= 64*1024)\n\t{\n\t\tfclose(pFile);\n\t\tprinter::inst()->print_msg(L0, \"Oversized config file - %s.\", sFilename);\n\t\treturn false;\n\t}\n\n\tif(flen <= 16)\n\t{\n\t\tprinter::inst()->print_msg(L0, \"File is empty or too short - %s.\", sFilename);\n\t\treturn false;\n\t}\n\n\tbuffer = (char*)malloc(flen + 3);\n\tif(fread(buffer+1, flen, 1, pFile) != 1)\n\t{\n\t\tfree(buffer);\n\t\tfclose(pFile);\n\t\tprinter::inst()->print_msg(L0, \"Read error while reading %s.\", sFilename);\n\t\treturn false;\n\t}\n\tfclose(pFile);\n\n\t//Replace Unicode BOM with spaces - we always use UTF-8\n\tunsigned char* ubuffer = (unsigned char*)buffer;\n\tif(ubuffer[1] == 0xEF && ubuffer[2] == 0xBB && ubuffer[3] == 0xBF)\n\t{\n\t\tbuffer[1] = ' ';\n\t\tbuffer[2] = ' ';\n\t\tbuffer[3] = ' ';\n\t}\n\n\tbuffer[0] = '{';\n\tbuffer[flen] = '}';\n\tbuffer[flen + 1] = '\\0';\n\n\tprv->jsonDoc.Parse<kParseCommentsFlag|kParseTrailingCommasFlag>(buffer, flen+2);\n\tfree(buffer);\n\n\tif(prv->jsonDoc.HasParseError())\n\t{\n\t\tprinter::inst()->print_msg(L0, \"JSON config parse error(offset %llu): %s\",\n\t\t\tint_port(prv->jsonDoc.GetErrorOffset()), GetParseError_En(prv->jsonDoc.GetParseError()));\n\t\treturn false;\n\t}\n\n\n\tif(!prv->jsonDoc.IsObject())\n\t{ //This should never happen as we created the root ourselves\n\t\tprinter::inst()->print_msg(L0, \"Invalid config file. No root?\\n\");\n\t\treturn false;\n\t}\n\n\tfor(size_t i = 0; i < iConfigCnt; i++)\n\t{\n\t\tif(oConfigValues[i].iName != i)\n\t\t{\n\t\t\tprinter::inst()->print_msg(L0, \"Code error. oConfigValues are not in order.\");\n\t\t\treturn false;\n\t\t}\n\n\t\tprv->configValues[i] = GetObjectMember(prv->jsonDoc, oConfigValues[i].sName);\n\n\t\tif(prv->configValues[i] == nullptr)\n\t\t{\n\t\t\tprinter::inst()->print_msg(L0, \"Invalid config file. Missing value \\\"%s\\\".\", oConfigValues[i].sName);\n\t\t\treturn false;\n\t\t}\n\n\t\tif(!checkType(prv->configValues[i]->GetType(), oConfigValues[i].iType))\n\t\t{\n\t\t\tprinter::inst()->print_msg(L0, \"Invalid config file. Value \\\"%s\\\" has unexpected type.\", oConfigValues[i].sName);\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tsize_t n_thd = prv->configValues[aGpuThreadsConf]->Size();\n\tif(prv->configValues[iGpuThreadNum]->GetUint64() != n_thd)\n\t{\n\t\tprinter::inst()->print_msg(L0,\n\t\t\t\"Invalid config file. Your GPU config array has %llu members, while you want to use %llu threads.\",\n\t\t\tint_port(n_thd), int_port(prv->configValues[iGpuThreadNum]->GetUint64()));\n\t\treturn false;\n\t}\n\n\tthd_cfg c;\n\tfor(size_t i=0; i < n_thd; i++)\n\t{\n\t\tif(!GetThreadConfig(i, c))\n\t\t{\n\t\t\tprinter::inst()->print_msg(L0, \"Thread %llu has invalid config.\", int_port(i));\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tif(!prv->configValues[iCallTimeout]->IsUint64() ||\n\t\t!prv->configValues[iNetRetry]->IsUint64() ||\n\t\t!prv->configValues[iGiveUpLimit]->IsUint64())\n\t{\n\t\tprinter::inst()->print_msg(L0,\n\t\t\t\"Invalid config file. call_timeout, retry_time and giveup_limit need to be positive integers.\");\n\t\treturn false;\n\t}\n\n\tif(!prv->configValues[iVerboseLevel]->IsUint64() || !prv->configValues[iAutohashTime]->IsUint64())\n\t{\n\t\tprinter::inst()->print_msg(L0,\n\t\t\t\"Invalid config file. verbose_level and h_print_time need to be positive integers.\");\n\t\treturn false;\n\t}\n\n\tif(!prv->configValues[iHttpdPort]->IsUint() || prv->configValues[iHttpdPort]->GetUint() > 0xFFFF)\n\t{\n\t\tprinter::inst()->print_msg(L0,\n\t\t\t\"Invalid config file. httpd_port has to be in the range 0 to 65535.\");\n\t\treturn false;\n\t}\n\n#ifdef CONF_NO_TLS\n\tif(prv->configValues[bTlsMode]->GetBool())\n\t{\n\t\tprinter::inst()->print_msg(L0,\n\t\t\t\"Invalid config file. TLS enabled while the application has been compiled without TLS support.\");\n\t\treturn false;\n\t}\n#endif // CONF_NO_TLS\n\n\tprinter::inst()->set_verbose_level(prv->configValues[iVerboseLevel]->GetUint64());\n\treturn true;\n}\n"
  },
  {
    "path": "jconf.h",
    "content": "#pragma once\n#include <stdlib.h>\n#include <string>\n\nclass jconf\n{\npublic:\n\tstatic jconf* inst()\n\t{\n\t\tif (oInst == nullptr) oInst = new jconf;\n\t\treturn oInst;\n\t};\n\n\tbool parse_config(const char* sFilename);\n\n\tstruct thd_cfg {\n\t\tsize_t index;\n\t\tsize_t intensity;\n\t\tsize_t w_size;\n\t\tlong long cpu_aff;\n\t};\n\n\tsize_t GetThreadCount();\n\tbool GetThreadConfig(size_t id, thd_cfg &cfg);\n\n\tsize_t GetPlatformIdx();\n\n\tbool GetTlsSetting();\n\tbool TlsSecureAlgos();\n\tconst char* GetTlsFingerprint();\n\n\tconst char* GetPoolAddress();\n\tconst char* GetPoolPwd();\n\tconst char* GetWalletAddress();\n\n\tuint64_t GetVerboseLevel();\n\tuint64_t GetAutohashTime();\n\n\tconst char* GetOutputFile();\n\n\tuint64_t GetCallTimeout();\n\tuint64_t GetNetRetry();\n\tuint64_t GetGiveUpLimit();\n\n\tuint16_t GetHttpdPort();\n\n\tbool DaemonMode();\n\n\tbool PreferIpv4();\n\n\tinline bool HaveHardwareAes() { return bHaveAes; }\n\nprivate:\n\tjconf();\n\tstatic jconf* oInst;\n\n\tbool check_cpu_features();\n\tstruct opaque_private;\n\topaque_private* prv;\n\n\tbool bHaveAes;\n};\n"
  },
  {
    "path": "jext.h",
    "content": "#pragma once\n\nusing namespace rapidjson;\n\n/* This macro brings rapidjson more in line with other libs */\ninline const Value* GetObjectMember(const Value& obj, const char* key)\n{\n\tValue::ConstMemberIterator itr = obj.FindMember(key);\n\tif (itr != obj.MemberEnd())\n\t\treturn &itr->value;\n\telse\n\t\treturn nullptr;\n}\n"
  },
  {
    "path": "jpsock.cpp",
    "content": "/*\n  * This program is free software: you can redistribute it and/or modify\n  * it under the terms of the GNU General Public License as published by\n  * the Free Software Foundation, either version 3 of the License, or\n  * any later version.\n  *\n  * This program is distributed in the hope that it will be useful,\n  * but WITHOUT ANY WARRANTY; without even the implied warranty of\n  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n  * GNU General Public License for more details.\n  *\n  * You should have received a copy of the GNU General Public License\n  * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n  *\n  * Additional permission under GNU GPL version 3 section 7\n  *\n  * If you modify this Program, or any covered work, by linking or combining\n  * it with OpenSSL (or a modified version of that library), containing parts\n  * covered by the terms of OpenSSL License and SSLeay License, the licensors\n  * of this Program grant you additional permission to convey the resulting work.\n  *\n  */\n\n#include <stdarg.h>\n#include <assert.h>\n\n#include \"jpsock.h\"\n#include \"executor.h\"\n#include \"jconf.h\"\n\n#include \"rapidjson/document.h\"\n#include \"jext.h\"\n#include \"socks.h\"\n#include \"socket.h\"\n#include \"version.h\"\n\n#define AGENTID_STR XMR_STAK_NAME \"/\" XMR_STAK_VERSION\n\nusing namespace rapidjson;\n\nstruct jpsock::call_rsp\n{\n\tbool bHaveResponse;\n\tuint64_t iCallId;\n\tValue* pCallData;\n\tstd::string sCallErr;\n\n\tcall_rsp(Value* val) : pCallData(val)\n\t{\n\t\tbHaveResponse = false;\n\t\tiCallId = 0;\n\t\tsCallErr.clear();\n\t}\n};\n\ntypedef GenericDocument<UTF8<>, MemoryPoolAllocator<>, MemoryPoolAllocator<>> MemDocument;\n\n/*\n *\n * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n * ASSUMPTION - only one calling thread. Multiple calling threads would require better\n * thread safety. The calling thread is assumed to be the executor thread.\n * If there is a reason to call the pool outside of the executor context, consider\n * doing it via an executor event.\n * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n *\n * Call values and allocators are for the calling thread (executor). When processing\n * a call, the recv thread will make a copy of the call response and then erase its copy.\n */\n\nstruct jpsock::opaque_private\n{\n\tValue  oCallValue;\n\n\tMemoryPoolAllocator<> callAllocator;\n\tMemoryPoolAllocator<> recvAllocator;\n\tMemoryPoolAllocator<> parseAllocator;\n\tMemDocument jsonDoc;\n\tcall_rsp oCallRsp;\n\n\topaque_private(uint8_t* bCallMem, uint8_t* bRecvMem, uint8_t* bParseMem) :\n\t\tcallAllocator(bCallMem, jpsock::iJsonMemSize),\n\t\trecvAllocator(bRecvMem, jpsock::iJsonMemSize),\n\t\tparseAllocator(bParseMem, jpsock::iJsonMemSize),\n\t\tjsonDoc(&recvAllocator, jpsock::iJsonMemSize, &parseAllocator),\n\t\toCallRsp(nullptr)\n\t{\n\t}\n};\n\nstruct jpsock::opq_json_val\n{\n\tconst Value* val;\n\topq_json_val(const Value* val) : val(val) {}\n};\n\njpsock::jpsock(size_t id, bool tls) : pool_id(id)\n{\n\tsock_init();\n\n\tbJsonCallMem = (uint8_t*)malloc(iJsonMemSize);\n\tbJsonRecvMem = (uint8_t*)malloc(iJsonMemSize);\n\tbJsonParseMem = (uint8_t*)malloc(iJsonMemSize);\n\n\tprv = new opaque_private(bJsonCallMem, bJsonRecvMem, bJsonParseMem);\n\n#ifndef CONF_NO_TLS\n\tif(tls)\n\t\tsck = new tls_socket(this);\n\telse\n\t\tsck = new plain_socket(this);\n#else\n\tsck = new plain_socket(this);\n#endif\n\n\toRecvThd = nullptr;\n\tbRunning = false;\n\tbLoggedIn = false;\n\tiJobDiff = 0;\n\n\tmemset(&oCurrentJob, 0, sizeof(oCurrentJob));\n}\n\njpsock::~jpsock()\n{\n\tdelete prv;\n\tprv = nullptr;\n\n\tfree(bJsonCallMem);\n\tfree(bJsonRecvMem);\n\tfree(bJsonParseMem);\n}\n\nstd::string&& jpsock::get_call_error()\n{\n\treturn std::move(prv->oCallRsp.sCallErr);\n}\n\nbool jpsock::set_socket_error(const char* a)\n{\n\tif(!bHaveSocketError)\n\t{\n\t\tbHaveSocketError = true;\n\t\tsSocketError.assign(a);\n\t}\n\n\treturn false;\n}\n\nbool jpsock::set_socket_error(const char* a, const char* b)\n{\n\tif(!bHaveSocketError)\n\t{\n\t\tbHaveSocketError = true;\n\t\tsize_t ln_a = strlen(a);\n\t\tsize_t ln_b = strlen(b);\n\n\t\tsSocketError.reserve(ln_a + ln_b + 2);\n\t\tsSocketError.assign(a, ln_a);\n\t\tsSocketError.append(b, ln_b);\n\t}\n\n\treturn false;\n}\n\nbool jpsock::set_socket_error(const char* a, size_t len)\n{\n\tif(!bHaveSocketError)\n\t{\n\t\tbHaveSocketError = true;\n\t\tsSocketError.assign(a, len);\n\t}\n\n\treturn false;\n}\n\nbool jpsock::set_socket_error_strerr(const char* a)\n{\n\tchar sSockErrText[512];\n\treturn set_socket_error(a, sock_strerror(sSockErrText, sizeof(sSockErrText)));\n}\n\nbool jpsock::set_socket_error_strerr(const char* a, int res)\n{\n\tchar sSockErrText[512];\n\treturn set_socket_error(a, sock_gai_strerror(res, sSockErrText, sizeof(sSockErrText)));\n}\n\nvoid jpsock::jpsock_thread()\n{\n\tjpsock_thd_main();\n\texecutor::inst()->push_event(ex_event(std::move(sSocketError), pool_id));\n\n\t// If a call is wating, send an error to end it\n\tbool bCallWaiting = false;\n\tstd::unique_lock<std::mutex> mlock(call_mutex);\n\tif(prv->oCallRsp.pCallData != nullptr)\n\t{\n\t\tprv->oCallRsp.bHaveResponse = true;\n\t\tprv->oCallRsp.iCallId = 0;\n\t\tprv->oCallRsp.pCallData = nullptr;\n\t\tbCallWaiting = true;\n\t}\n\tmlock.unlock();\n\n\tif(bCallWaiting)\n\t\tcall_cond.notify_one();\n\n\tbRunning = false;\n\tbLoggedIn = false;\n\n\tstd::unique_lock<std::mutex>(job_mutex);\n\tmemset(&oCurrentJob, 0, sizeof(oCurrentJob));\n}\n\nbool jpsock::jpsock_thd_main()\n{\n\tif(!sck->connect())\n\t\treturn false;\n\n\texecutor::inst()->push_event(ex_event(EV_SOCK_READY, pool_id));\n\n\tchar buf[iSockBufferSize];\n\tsize_t datalen = 0;\n\twhile (true)\n\t{\n\t\tint ret = sck->recv(buf + datalen, sizeof(buf) - datalen);\n\n\t\tif(ret <= 0)\n\t\t\treturn false;\n\n\t\tdatalen += ret;\n\n\t\tif (datalen >= sizeof(buf))\n\t\t{\n\t\t\tsck->close(false);\n\t\t\treturn set_socket_error(\"RECEIVE error: data overflow\");\n\t\t}\n\n\t\tchar* lnend;\n\t\tchar* lnstart = buf;\n\t\twhile ((lnend = (char*)memchr(lnstart, '\\n', datalen)) != nullptr)\n\t\t{\n\t\t\tlnend++;\n\t\t\tint lnlen = lnend - lnstart;\n\n\t\t\tif (!process_line(lnstart, lnlen))\n\t\t\t{\n\t\t\t\tsck->close(false);\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tdatalen -= lnlen;\n\t\t\tlnstart = lnend;\n\t\t}\n\n\t\t//Got leftover data? Move it to the front\n\t\tif (datalen > 0 && buf != lnstart)\n\t\t\tmemmove(buf, lnstart, datalen);\n\t}\n}\n\nbool jpsock::process_line(char* line, size_t len)\n{\n\tprv->jsonDoc.SetNull();\n\tprv->parseAllocator.Clear();\n\tprv->callAllocator.Clear();\n\n\t/*NULL terminate the line instead of '\\n', parsing will add some more NULLs*/\n\tline[len-1] = '\\0';\n\n\t//printf(\"RECV: %s\\n\", line);\n\n\tif (prv->jsonDoc.ParseInsitu(line).HasParseError())\n\t\treturn set_socket_error(\"PARSE error: Invalid JSON\");\n\n\tif (!prv->jsonDoc.IsObject())\n\t\treturn set_socket_error(\"PARSE error: Invalid root\");\n\n\tconst Value* mt;\n\tif (prv->jsonDoc.HasMember(\"method\"))\n\t{\n\t\tmt = GetObjectMember(prv->jsonDoc, \"method\");\n\n\t\tif(!mt->IsString())\n\t\t\treturn set_socket_error(\"PARSE error: Protocol error 1\");\n\n\t\tif(strcmp(mt->GetString(), \"job\") != 0)\n\t\t\treturn set_socket_error(\"PARSE error: Unsupported server method \", mt->GetString());\n\n\t\tmt = GetObjectMember(prv->jsonDoc, \"params\");\n\t\tif(mt == nullptr || !mt->IsObject())\n\t\t\treturn set_socket_error(\"PARSE error: Protocol error 2\");\n\n\t\topq_json_val v(mt);\n\t\treturn process_pool_job(&v);\n\t}\n\telse\n\t{\n\t\tuint64_t iCallId;\n\t\tmt = GetObjectMember(prv->jsonDoc, \"id\");\n\t\tif (mt == nullptr || !mt->IsUint64())\n\t\t\treturn set_socket_error(\"PARSE error: Protocol error 3\");\n\n\t\tiCallId = mt->GetUint64();\n\n\t\tmt = GetObjectMember(prv->jsonDoc, \"error\");\n\n\t\tconst char* sError = nullptr;\n\t\tsize_t iErrorLn = 0;\n\t\tif (mt == nullptr || mt->IsNull())\n\t\t{\n\t\t\t/* If there was no error we need a result */\n\t\t\tif ((mt = GetObjectMember(prv->jsonDoc, \"result\")) == nullptr)\n\t\t\t\treturn set_socket_error(\"PARSE error: Protocol error 7\");\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif(!mt->IsObject())\n\t\t\t\treturn set_socket_error(\"PARSE error: Protocol error 5\");\n\n\t\t\tconst Value* msg = GetObjectMember(*mt, \"message\");\n\n\t\t\tif(msg == nullptr || !msg->IsString())\n\t\t\t\treturn set_socket_error(\"PARSE error: Protocol error 6\");\n\n\t\t\tiErrorLn = msg->GetStringLength();\n\t\t\tsError = msg->GetString();\n\t\t}\n\n\t\tstd::unique_lock<std::mutex> mlock(call_mutex);\n\t\tif (prv->oCallRsp.pCallData == nullptr)\n\t\t{\n\t\t\t/*Server sent us a call reply without us making a call*/\n\t\t\tmlock.unlock();\n\t\t\treturn set_socket_error(\"PARSE error: Unexpected call response\");\n\t\t}\n\n\t\tprv->oCallRsp.bHaveResponse = true;\n\t\tprv->oCallRsp.iCallId = iCallId;\n\n\t\tif(sError != nullptr)\n\t\t{\n\t\t\tprv->oCallRsp.pCallData = nullptr;\n\t\t\tprv->oCallRsp.sCallErr.assign(sError, iErrorLn);\n\t\t}\n\t\telse\n\t\t\tprv->oCallRsp.pCallData->CopyFrom(*mt, prv->callAllocator);\n\n\t\tmlock.unlock();\n\t\tcall_cond.notify_one();\n\n\t\treturn true;\n\t}\n}\n\nbool jpsock::process_pool_job(const opq_json_val* params)\n{\n\tif (!params->val->IsObject())\n\t\treturn set_socket_error(\"PARSE error: Job error 1\");\n\n\tconst Value * blob, *jobid, *target;\n\tjobid = GetObjectMember(*params->val, \"job_id\");\n\tblob = GetObjectMember(*params->val, \"blob\");\n\ttarget = GetObjectMember(*params->val, \"target\");\n\n\tif (jobid == nullptr || blob == nullptr || target == nullptr ||\n\t\t!jobid->IsString() || !blob->IsString() || !target->IsString())\n\t{\n\t\treturn set_socket_error(\"PARSE error: Job error 2\");\n\t}\n\n\tif (jobid->GetStringLength() >= sizeof(pool_job::sJobID)) // Note >=\n\t\treturn set_socket_error(\"PARSE error: Job error 3\");\n\n\tuint32_t iWorkLn = blob->GetStringLength() / 2;\n\tif (iWorkLn > sizeof(pool_job::bWorkBlob))\n\t\treturn set_socket_error(\"PARSE error: Invalid job legth. Are you sure you are mining the correct coin?\");\n\n\tpool_job oPoolJob;\n\tif (!hex2bin(blob->GetString(), iWorkLn * 2, oPoolJob.bWorkBlob))\n\t\treturn set_socket_error(\"PARSE error: Job error 4\");\n\n\toPoolJob.iWorkLen = iWorkLn;\n\tmemset(oPoolJob.sJobID, 0, sizeof(pool_job::sJobID));\n\tmemcpy(oPoolJob.sJobID, jobid->GetString(), jobid->GetStringLength()); //Bounds checking at proto error 3\n\n\tsize_t target_slen = target->GetStringLength();\n\tif(target_slen <= 8)\n\t{\n\t\tuint32_t iTempInt = 0;\n\t\tchar sTempStr[] = \"00000000\"; // Little-endian CPU FTW\n\t\tmemcpy(sTempStr, target->GetString(), target_slen);\n\t\tif(!hex2bin(sTempStr, 8, (unsigned char*)&iTempInt) || iTempInt == 0)\n\t\t\treturn set_socket_error(\"PARSE error: Invalid target\");\n\n\t\toPoolJob.iTarget = iTempInt;\n\t}\n\telse\n\t\treturn set_socket_error(\"PARSE error: Job error 5\");\n\n\tiJobDiff = t32_to_diff(oPoolJob.iTarget);\n\n\texecutor::inst()->push_event(ex_event(oPoolJob, pool_id));\n\n\tstd::unique_lock<std::mutex>(job_mutex);\n\toCurrentJob = oPoolJob;\n\treturn true;\n}\n\nbool jpsock::connect(const char* sAddr, std::string& sConnectError)\n{\n\tbHaveSocketError = false;\n\tsSocketError.clear();\n\tiJobDiff = 0;\n\n\tif(sck->set_hostname(sAddr))\n\t{\n\t\tbRunning = true;\n\t\toRecvThd = new std::thread(&jpsock::jpsock_thread, this);\n\t\treturn true;\n\t}\n\n\tsConnectError = std::move(sSocketError);\n\treturn false;\n}\n\nvoid jpsock::disconnect()\n{\n\tsck->close(false);\n\n\tif(oRecvThd != nullptr)\n\t{\n\t\toRecvThd->join();\n\t\tdelete oRecvThd;\n\t\toRecvThd = nullptr;\n\t}\n\n\tsck->close(true);\n}\n\nbool jpsock::cmd_ret_wait(const char* sPacket, opq_json_val& poResult)\n{\n\t//printf(\"SEND: %s\\n\", sPacket);\n\n\t/*Set up the call rsp for the call reply*/\n\tprv->oCallValue.SetNull();\n\tprv->callAllocator.Clear();\n\n\tstd::unique_lock<std::mutex> mlock(call_mutex);\n\tprv->oCallRsp = call_rsp(&prv->oCallValue);\n\tmlock.unlock();\n\n\tif(!sck->send(sPacket))\n\t{\n\t\tdisconnect(); //This will join the other thread;\n\t\treturn false;\n\t}\n\n\t//Success is true if the server approves, result is true if there was no socket error\n\tbool bSuccess;\n\tmlock.lock();\n\tbool bResult = call_cond.wait_for(mlock, std::chrono::seconds(jconf::inst()->GetCallTimeout()),\n\t\t[&]() { return prv->oCallRsp.bHaveResponse; });\n\n\tbSuccess = prv->oCallRsp.pCallData != nullptr;\n\tprv->oCallRsp.pCallData = nullptr;\n\tmlock.unlock();\n\n\tif(bHaveSocketError)\n\t\treturn false;\n\n\t//This means that there was no socket error, but the server is not taking to us\n\tif(!bResult)\n\t{\n\t\tset_socket_error(\"CALL error: Timeout while waiting for a reply\");\n\t\tdisconnect();\n\t\treturn false;\n\t}\n\n\tif(bSuccess)\n\t\tpoResult.val = &prv->oCallValue;\n\n\treturn bSuccess;\n}\n\nbool jpsock::cmd_login(const char* sLogin, const char* sPassword)\n{\n\tchar cmd_buffer[1024];\n\n\tsnprintf(cmd_buffer, sizeof(cmd_buffer), \"{\\\"method\\\":\\\"login\\\",\\\"params\\\":{\\\"login\\\":\\\"%s\\\",\\\"pass\\\":\\\"%s\\\",\\\"agent\\\":\\\"\" AGENTID_STR \"\\\"},\\\"id\\\":1}\\n\",\n\t\tsLogin, sPassword);\n\n\topq_json_val oResult(nullptr);\n\n\t/*Normal error conditions (failed login etc..) will end here*/\n\tif (!cmd_ret_wait(cmd_buffer, oResult))\n\t\treturn false;\n\n\tif (!oResult.val->IsObject())\n\t{\n\t\tset_socket_error(\"PARSE error: Login protocol error 1\");\n\t\tdisconnect();\n\t\treturn false;\n\t}\n\n\tconst Value* id = GetObjectMember(*oResult.val, \"id\");\n\tconst Value* job = GetObjectMember(*oResult.val, \"job\");\n\n\tif (id == nullptr || job == nullptr || !id->IsString())\n\t{\n\t\tset_socket_error(\"PARSE error: Login protocol error 2\");\n\t\tdisconnect();\n\t\treturn false;\n\t}\n\n\tif (id->GetStringLength() >= sizeof(sMinerId))\n\t{\n\t\tset_socket_error(\"PARSE error: Login protocol error 3\");\n\t\tdisconnect();\n\t\treturn false;\n\t}\n\n\tmemset(sMinerId, 0, sizeof(sMinerId));\n\tmemcpy(sMinerId, id->GetString(), id->GetStringLength());\n\n\topq_json_val v(job);\n\tif(!process_pool_job(&v))\n\t{\n\t\tdisconnect();\n\t\treturn false;\n\t}\n\n\tbLoggedIn = true;\n\n\treturn true;\n}\n\nbool jpsock::cmd_submit(const char* sJobId, uint32_t iNonce, const uint8_t* bResult)\n{\n\tchar cmd_buffer[1024];\n\tchar sNonce[9];\n\tchar sResult[65];\n\n\tbin2hex((unsigned char*)&iNonce, 4, sNonce);\n\tsNonce[8] = '\\0';\n\n\tbin2hex(bResult, 32, sResult);\n\tsResult[64] = '\\0';\n\n\tsnprintf(cmd_buffer, sizeof(cmd_buffer), \"{\\\"method\\\":\\\"submit\\\",\\\"params\\\":{\\\"id\\\":\\\"%s\\\",\\\"job_id\\\":\\\"%s\\\",\\\"nonce\\\":\\\"%s\\\",\\\"result\\\":\\\"%s\\\"},\\\"id\\\":1}\\n\",\n\t\tsMinerId, sJobId, sNonce, sResult);\n\n\topq_json_val oResult(nullptr);\n\treturn cmd_ret_wait(cmd_buffer, oResult);\n}\n\nbool jpsock::get_current_job(pool_job& job)\n{\n\tstd::unique_lock<std::mutex>(job_mutex);\n\n\tif(oCurrentJob.iWorkLen == 0)\n\t\treturn false;\n\n\toCurrentJob.iResumeCnt++;\n\tjob = oCurrentJob;\n\treturn true;\n}\n\ninline unsigned char hf_hex2bin(char c, bool &err)\n{\n\tif (c >= '0' && c <= '9')\n\t\treturn c - '0';\n\telse if (c >= 'a' && c <= 'f')\n\t\treturn c - 'a' + 0xA;\n\telse if (c >= 'A' && c <= 'F')\n\t\treturn c - 'A' + 0xA;\n\n\terr = true;\n\treturn 0;\n}\n\nbool jpsock::hex2bin(const char* in, unsigned int len, unsigned char* out)\n{\n\tbool error = false;\n\tfor (unsigned int i = 0; i < len; i += 2)\n\t{\n\t\tout[i / 2] = (hf_hex2bin(in[i], error) << 4) | hf_hex2bin(in[i + 1], error);\n\t\tif (error) return false;\n\t}\n\treturn true;\n}\n\ninline char hf_bin2hex(unsigned char c)\n{\n\tif (c <= 0x9)\n\t\treturn '0' + c;\n\telse\n\t\treturn 'a' - 0xA + c;\n}\n\nvoid jpsock::bin2hex(const unsigned char* in, unsigned int len, char* out)\n{\n\tfor (unsigned int i = 0; i < len; i++)\n\t{\n\t\tout[i * 2] = hf_bin2hex((in[i] & 0xF0) >> 4);\n\t\tout[i * 2 + 1] = hf_bin2hex(in[i] & 0x0F);\n\t}\n}\n"
  },
  {
    "path": "jpsock.h",
    "content": "#pragma once\n#include <mutex>\n#include <atomic>\n#include <condition_variable>\n#include <thread>\n#include <string>\n\n#include \"msgstruct.h\"\n\n/* Our pool can have two kinds of errors:\n\t- Parsing or connection error\n\tThose are fatal errors (we drop the connection if we encounter them).\n\tAfter they are constructed from const char* strings from various places.\n\t(can be from read-only mem), we passs them in an exectutor message\n\tonce the recv thread expires.\n\t- Call error\n\tThis error happens when the \"server says no\". Usually because the job was\n\toutdated, or we somehow got the hash wrong. It isn't fatal.\n\tWe parse it in-situ in the network buffer, after that we copy it to a\n\tstd::string. Executor will move the buffer via an r-value ref.\n*/\nclass base_socket;\n\nclass jpsock\n{\npublic:\n\tjpsock(size_t id, bool tls);\n\t~jpsock();\n\n\tbool connect(const char* sAddr, std::string& sConnectError);\n\tvoid disconnect();\n\n\tbool cmd_login(const char* sLogin, const char* sPassword);\n\tbool cmd_submit(const char* sJobId, uint32_t iNonce, const uint8_t* bResult);\n\n\tstatic bool hex2bin(const char* in, unsigned int len, unsigned char* out);\n\tstatic void bin2hex(const unsigned char* in, unsigned int len, char* out);\n\n\tinline bool is_running() { return bRunning; }\n\tinline bool is_logged_in() { return bLoggedIn; }\n\n\tstd::string&& get_call_error();\n\tbool have_sock_error() { return bHaveSocketError; }\n\n\tinline static uint64_t t32_to_t64(uint32_t t) { return 0xFFFFFFFFFFFFFFFFULL / (0xFFFFFFFFULL / ((uint64_t)t)); }\n\tinline static uint64_t t64_to_diff(uint64_t t) { return 0xFFFFFFFFFFFFFFFFULL / t; }\n\tinline static uint64_t t32_to_diff(uint32_t t) { return 0xFFFFFFFF / t; }\n\tinline static uint64_t diff_to_t64(uint64_t d) { return 0xFFFFFFFFFFFFFFFFULL / d; }\n\n\tinline uint64_t get_current_diff() { return iJobDiff; }\n\n\tbool get_current_job(pool_job& job);\n\n\tsize_t pool_id;\n\n\tbool set_socket_error(const char* a);\n\tbool set_socket_error(const char* a, const char* b);\n\tbool set_socket_error(const char* a, size_t len);\n\tbool set_socket_error_strerr(const char* a);\n\tbool set_socket_error_strerr(const char* a, int res);\n\nprivate:\n\tstd::atomic<bool> bRunning;\n\tstd::atomic<bool> bLoggedIn;\n\n\tuint8_t* bJsonRecvMem;\n\tuint8_t* bJsonParseMem;\n\tuint8_t* bJsonCallMem;\n\n\tstatic constexpr size_t iJsonMemSize = 4096;\n\tstatic constexpr size_t iSockBufferSize = 4096;\n\n\tstruct call_rsp;\n\tstruct opaque_private;\n\tstruct opq_json_val;\n\n\tvoid jpsock_thread();\n\tbool jpsock_thd_main();\n\tbool process_line(char* line, size_t len);\n\tbool process_pool_job(const opq_json_val* params);\n\tbool cmd_ret_wait(const char* sPacket, opq_json_val& poResult);\n\n\tchar sMinerId[64];\n\tstd::atomic<uint64_t> iJobDiff;\n\n\tstd::string sSocketError;\n\tstd::atomic<bool> bHaveSocketError;\n\n\tstd::mutex call_mutex;\n\tstd::condition_variable call_cond;\n\tstd::thread* oRecvThd;\n\n\tstd::mutex job_mutex;\n\tpool_job oCurrentJob;\n\n\topaque_private* prv;\n\tbase_socket* sck;\n};\n\n"
  },
  {
    "path": "libmicrohttpd/microhttpd.h",
    "content": "/*\n     This file is part of libmicrohttpd\n     Copyright (C) 2006-2015 Christian Grothoff (and other contributing authors)\n\n     This library is free software; you can redistribute it and/or\n     modify it under the terms of the GNU Lesser General Public\n     License as published by the Free Software Foundation; either\n     version 2.1 of the License, or (at your option) any later version.\n\n     This library is distributed in the hope that it will be useful,\n     but WITHOUT ANY WARRANTY; without even the implied warranty of\n     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n     Lesser General Public License for more details.\n\n     You should have received a copy of the GNU Lesser General Public\n     License along with this library; if not, write to the Free Software\n     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n*/\n\n/**\n * @file microhttpd.h\n * @brief public interface to libmicrohttpd\n * @author Christian Grothoff\n * @author Karlson2k (Evgeny Grin)\n * @author Chris GauthierDickey\n *\n * All symbols defined in this header start with MHD.  MHD is a small\n * HTTP daemon library.  As such, it does not have any API for logging\n * errors (you can only enable or disable logging to stderr).  Also,\n * it may not support all of the HTTP features directly, where\n * applicable, portions of HTTP may have to be handled by clients of\n * the library.\n *\n * The library is supposed to handle everything that it must handle\n * (because the API would not allow clients to do this), such as basic\n * connection management; however, detailed interpretations of headers\n * -- such as range requests -- and HTTP methods are left to clients.\n * The library does understand HEAD and will only send the headers of\n * the response and not the body, even if the client supplied a body.\n * The library also understands headers that control connection\n * management (specifically, \"Connection: close\" and \"Expect: 100\n * continue\" are understood and handled automatically).\n *\n * MHD understands POST data and is able to decode certain formats\n * (at the moment only \"application/x-www-form-urlencoded\" and\n * \"mulitpart/formdata\"). Unsupported encodings and large POST\n * submissions may require the application to manually process\n * the stream, which is provided to the main application (and thus can be\n * processed, just not conveniently by MHD).\n *\n * The header file defines various constants used by the HTTP protocol.\n * This does not mean that MHD actually interprets all of these\n * values.  The provided constants are exported as a convenience\n * for users of the library.  MHD does not verify that transmitted\n * HTTP headers are part of the standard specification; users of the\n * library are free to define their own extensions of the HTTP\n * standard and use those with MHD.\n *\n * All functions are guaranteed to be completely reentrant and\n * thread-safe (with the exception of #MHD_set_connection_value,\n * which must only be used in a particular context).\n *\n *\n * @defgroup event event-loop control\n * MHD API to start and stop the HTTP server and manage the event loop.\n * @defgroup response generation of responses\n * MHD API used to generate responses.\n * @defgroup request handling of requests\n * MHD API used to access information about requests.\n * @defgroup authentication HTTP authentication\n * MHD API related to basic and digest HTTP authentication.\n * @defgroup logging logging\n * MHD API to mange logging and error handling\n * @defgroup specialized misc. specialized functions\n * This group includes functions that do not fit into any particular\n * category and that are rarely used.\n */\n\n#ifndef MHD_MICROHTTPD_H\n#define MHD_MICROHTTPD_H\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#if 0                           /* keep Emacsens' auto-indent happy */\n}\n#endif\n#endif\n\n/* While we generally would like users to use a configure-driven\n   build process which detects which headers are present and\n   hence works on any platform, we use \"standard\" includes here\n   to build out-of-the-box for beginning users on common systems.\n\n   If generic headers don't work on your platform, include headers\n   which define 'va_list', 'size_t', 'ssize_t', 'intptr_t',\n   'uint16_t', 'uint32_t', 'uint64_t', 'off_t', 'struct sockaddr',\n   'socklen_t', 'fd_set' and \"#define MHD_PLATFORM_H\" before\n   including \"microhttpd.h\". Then the following \"standard\"\n   includes won't be used (which might be a good idea, especially\n   on platforms where they do not exist).\n   */\n#ifndef MHD_PLATFORM_H\n#include <stdarg.h>\n#include <stdint.h>\n#include <sys/types.h>\n#if defined(_WIN32) && !defined(__CYGWIN__)\n#include <ws2tcpip.h>\n#if defined(_MSC_FULL_VER) && !defined (_SSIZE_T_DEFINED)\n#define _SSIZE_T_DEFINED\ntypedef intptr_t ssize_t;\n#endif /* !_SSIZE_T_DEFINED */\n#else\n#include <unistd.h>\n#include <sys/time.h>\n#include <sys/socket.h>\n#endif\n#endif\n\n#if defined(__CYGWIN__) && !defined(_SYS_TYPES_FD_SET)\n/* Do not define __USE_W32_SOCKETS under Cygwin! */\n#error Cygwin with winsock fd_set is not supported\n#endif\n\n/**\n * Current version of the library.\n * 0x01093001 = 1.9.30-1.\n */\n#define MHD_VERSION 0x00095100\n\n/**\n * MHD-internal return code for \"YES\".\n */\n#define MHD_YES 1\n\n/**\n * MHD-internal return code for \"NO\".\n */\n#define MHD_NO 0\n\n/**\n * MHD digest auth internal code for an invalid nonce.\n */\n#define MHD_INVALID_NONCE -1\n\n/**\n * Constant used to indicate unknown size (use when\n * creating a response).\n */\n#ifdef UINT64_MAX\n#define MHD_SIZE_UNKNOWN UINT64_MAX\n#else\n#define MHD_SIZE_UNKNOWN  ((uint64_t) -1LL)\n#endif\n\n#ifdef SIZE_MAX\n#define MHD_CONTENT_READER_END_OF_STREAM SIZE_MAX\n#define MHD_CONTENT_READER_END_WITH_ERROR (SIZE_MAX - 1)\n#else\n#define MHD_CONTENT_READER_END_OF_STREAM ((size_t) -1LL)\n#define MHD_CONTENT_READER_END_WITH_ERROR (((size_t) -1LL) - 1)\n#endif\n\n#ifndef _MHD_EXTERN\n#if defined(_WIN32) && defined(MHD_W32LIB)\n#define _MHD_EXTERN extern\n#elif defined (_WIN32) && defined(MHD_W32DLL)\n/* Define MHD_W32DLL when using MHD as W32 .DLL to speed up linker a little */\n#define _MHD_EXTERN __declspec(dllimport)\n#else\n#define _MHD_EXTERN extern\n#endif\n#endif\n\n#ifndef MHD_SOCKET_DEFINED\n/**\n * MHD_socket is type for socket FDs\n */\n#if !defined(_WIN32) || defined(_SYS_TYPES_FD_SET)\n#define MHD_POSIX_SOCKETS 1\ntypedef int MHD_socket;\n#define MHD_INVALID_SOCKET (-1)\n#else /* !defined(_WIN32) || defined(_SYS_TYPES_FD_SET) */\n#define MHD_WINSOCK_SOCKETS 1\n#include <winsock2.h>\ntypedef SOCKET MHD_socket;\n#define MHD_INVALID_SOCKET (INVALID_SOCKET)\n#endif /* !defined(_WIN32) || defined(_SYS_TYPES_FD_SET) */\n#define MHD_SOCKET_DEFINED 1\n#endif /* MHD_SOCKET_DEFINED */\n\n/**\n * Define MHD_NO_DEPRECATION before including \"microhttpd.h\" to disable deprecation messages\n */\n#ifdef MHD_NO_DEPRECATION\n#define _MHD_DEPR_MACRO(msg)\n#define _MHD_NO_DEPR_IN_MACRO 1\n#define _MHD_DEPR_IN_MACRO(msg)\n#define _MHD_NO_DEPR_FUNC 1\n#define _MHD_DEPR_FUNC(msg)\n#endif /* MHD_NO_DEPRECATION */\n\n#ifndef _MHD_DEPR_MACRO\n#if defined(_MSC_FULL_VER) && _MSC_VER+0 >= 1500\n/* VS 2008 or later */\n/* Stringify macros */\n#define _MHD_INSTRMACRO(a) #a\n#define _MHD_STRMACRO(a) _MHD_INSTRMACRO(a)\n/* deprecation message */\n#define _MHD_DEPR_MACRO(msg) __pragma(message(__FILE__ \"(\" _MHD_STRMACRO(__LINE__)\"): warning: \" msg))\n#define _MHD_DEPR_IN_MACRO(msg) _MHD_DEPR_MACRO(msg)\n#elif defined(__clang__) || defined (__GNUC_PATCHLEVEL__)\n/* clang or GCC since 3.0 */\n#define _MHD_GCC_PRAG(x) _Pragma (#x)\n#if __clang_major__+0 >= 5 || \\\n  (!defined(__apple_build_version__) && (__clang_major__+0  > 3 || (__clang_major__+0 == 3 && __clang_minor__ >= 3))) || \\\n  __GNUC__+0 > 4 || (__GNUC__+0 == 4 && __GNUC_MINOR__+0 >= 8)\n/* clang >= 3.3 (or XCode's clang >= 5.0) or\n   GCC >= 4.8 */\n#define _MHD_DEPR_MACRO(msg) _MHD_GCC_PRAG(GCC warning msg)\n#define _MHD_DEPR_IN_MACRO(msg) _MHD_DEPR_MACRO(msg)\n#else /* older clang or GCC */\n/* clang < 3.3, XCode's clang < 5.0, 3.0 <= GCC < 4.8 */\n#define _MHD_DEPR_MACRO(msg) _MHD_GCC_PRAG(message msg)\n#if (__clang_major__+0  > 2 || (__clang_major__+0 == 2 && __clang_minor__ >= 9)) /* FIXME: clang >= 2.9, earlier versions not tested */\n/* clang handles inline pragmas better than GCC */\n#define _MHD_DEPR_IN_MACRO(msg) _MHD_DEPR_MACRO(msg)\n#endif /* clang >= 2.9 */\n#endif  /* older clang or GCC */\n/* #elif defined(SOMEMACRO) */ /* add compiler-specific macros here if required */\n#endif /* clang || GCC >= 3.0 */\n#endif /* !_MHD_DEPR_MACRO */\n\n#ifndef _MHD_DEPR_MACRO\n#define _MHD_DEPR_MACRO(msg)\n#endif /* !_MHD_DEPR_MACRO */\n\n#ifndef _MHD_DEPR_IN_MACRO\n#define _MHD_NO_DEPR_IN_MACRO 1\n#define _MHD_DEPR_IN_MACRO(msg)\n#endif /* !_MHD_DEPR_IN_MACRO */\n\n#ifndef _MHD_DEPR_FUNC\n#if defined(_MSC_FULL_VER) && _MSC_VER+0 >= 1400\n/* VS 2005 or later */\n#define _MHD_DEPR_FUNC(msg) __declspec(deprecated(msg))\n#elif defined(_MSC_FULL_VER) && _MSC_VER+0 >= 1310\n/* VS .NET 2003 deprecation do not support custom messages */\n#define _MHD_DEPR_FUNC(msg) __declspec(deprecated)\n#elif (__GNUC__+0 >= 5) || (defined (__clang__) && \\\n  (__clang_major__+0 > 2 || (__clang_major__+0 == 2 && __clang_minor__ >= 9)))  /* FIXME: earlier versions not tested */\n/* GCC >= 5.0 or clang >= 2.9 */\n#define _MHD_DEPR_FUNC(msg) __attribute__((deprecated(msg)))\n#elif defined (__clang__) || __GNUC__+0 > 3 || (__GNUC__+0 == 3 && __GNUC_MINOR__+0 >= 1)\n/* 3.1 <= GCC < 5.0 or clang < 2.9 */\n/* old GCC-style deprecation do not support custom messages */\n#define _MHD_DEPR_FUNC(msg) __attribute__((__deprecated__))\n/* #elif defined(SOMEMACRO) */ /* add compiler-specific macros here if required */\n#endif /* clang < 2.9 || GCC >= 3.1 */\n#endif /* !_MHD_DEPR_FUNC */\n\n#ifndef _MHD_DEPR_FUNC\n#define _MHD_NO_DEPR_FUNC 1\n#define _MHD_DEPR_FUNC(msg)\n#endif /* !_MHD_DEPR_FUNC */\n\n/**\n * Not all architectures and `printf()`'s support the `long long` type.\n * This gives the ability to replace `long long` with just a `long`,\n * standard `int` or a `short`.\n */\n#ifndef MHD_LONG_LONG\n/**\n * @deprecated use #MHD_UNSIGNED_LONG_LONG instead!\n */\n#define MHD_LONG_LONG long long\n#define MHD_UNSIGNED_LONG_LONG unsigned long long\n#else /* MHD_LONG_LONG */\n_MHD_DEPR_MACRO(\"Macro MHD_LONG_LONG is deprecated, use MHD_UNSIGNED_LONG_LONG\")\n#endif\n/**\n * Format string for printing a variable of type #MHD_LONG_LONG.\n * You should only redefine this if you also define #MHD_LONG_LONG.\n */\n#ifndef MHD_LONG_LONG_PRINTF\n/**\n * @deprecated use #MHD_UNSIGNED_LONG_LONG_PRINTF instead!\n */\n#define MHD_LONG_LONG_PRINTF \"ll\"\n#define MHD_UNSIGNED_LONG_LONG_PRINTF \"%llu\"\n#else /* MHD_LONG_LONG_PRINTF */\n_MHD_DEPR_MACRO(\"Macro MHD_LONG_LONG_PRINTF is deprecated, use MHD_UNSIGNED_LONG_LONG_PRINTF\")\n#endif\n\n\n/**\n * @defgroup httpcode HTTP response codes.\n * These are the status codes defined for HTTP responses.\n * @{\n */\n#define MHD_HTTP_CONTINUE 100\n#define MHD_HTTP_SWITCHING_PROTOCOLS 101\n#define MHD_HTTP_PROCESSING 102\n\n#define MHD_HTTP_OK 200\n#define MHD_HTTP_CREATED 201\n#define MHD_HTTP_ACCEPTED 202\n#define MHD_HTTP_NON_AUTHORITATIVE_INFORMATION 203\n#define MHD_HTTP_NO_CONTENT 204\n#define MHD_HTTP_RESET_CONTENT 205\n#define MHD_HTTP_PARTIAL_CONTENT 206\n#define MHD_HTTP_MULTI_STATUS 207\n\n#define MHD_HTTP_MULTIPLE_CHOICES 300\n#define MHD_HTTP_MOVED_PERMANENTLY 301\n#define MHD_HTTP_FOUND 302\n#define MHD_HTTP_SEE_OTHER 303\n#define MHD_HTTP_NOT_MODIFIED 304\n#define MHD_HTTP_USE_PROXY 305\n#define MHD_HTTP_SWITCH_PROXY 306\n#define MHD_HTTP_TEMPORARY_REDIRECT 307\n#define MHD_HTTP_PERMANENT_REDIRECT 308\n\n#define MHD_HTTP_BAD_REQUEST 400\n#define MHD_HTTP_UNAUTHORIZED 401\n#define MHD_HTTP_PAYMENT_REQUIRED 402\n#define MHD_HTTP_FORBIDDEN 403\n#define MHD_HTTP_NOT_FOUND 404\n#define MHD_HTTP_METHOD_NOT_ALLOWED 405\n#define MHD_HTTP_NOT_ACCEPTABLE 406\n/** @deprecated */\n#define MHD_HTTP_METHOD_NOT_ACCEPTABLE \\\n  _MHD_DEPR_IN_MACRO(\"Value MHD_HTTP_METHOD_NOT_ACCEPTABLE is deprecated, use MHD_HTTP_NOT_ACCEPTABLE\") 406\n#define MHD_HTTP_PROXY_AUTHENTICATION_REQUIRED 407\n#define MHD_HTTP_REQUEST_TIMEOUT 408\n#define MHD_HTTP_CONFLICT 409\n#define MHD_HTTP_GONE 410\n#define MHD_HTTP_LENGTH_REQUIRED 411\n#define MHD_HTTP_PRECONDITION_FAILED 412\n#define MHD_HTTP_REQUEST_ENTITY_TOO_LARGE 413\n#define MHD_HTTP_REQUEST_URI_TOO_LONG 414\n#define MHD_HTTP_UNSUPPORTED_MEDIA_TYPE 415\n#define MHD_HTTP_REQUESTED_RANGE_NOT_SATISFIABLE 416\n#define MHD_HTTP_EXPECTATION_FAILED 417\n#define MHD_HTTP_UNPROCESSABLE_ENTITY 422\n#define MHD_HTTP_LOCKED 423\n#define MHD_HTTP_FAILED_DEPENDENCY 424\n#define MHD_HTTP_UNORDERED_COLLECTION 425\n#define MHD_HTTP_UPGRADE_REQUIRED 426\n#define MHD_HTTP_NO_RESPONSE 444\n#define MHD_HTTP_RETRY_WITH 449\n#define MHD_HTTP_BLOCKED_BY_WINDOWS_PARENTAL_CONTROLS 450\n#define MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS 451\n\n#define MHD_HTTP_INTERNAL_SERVER_ERROR 500\n#define MHD_HTTP_NOT_IMPLEMENTED 501\n#define MHD_HTTP_BAD_GATEWAY 502\n#define MHD_HTTP_SERVICE_UNAVAILABLE 503\n#define MHD_HTTP_GATEWAY_TIMEOUT 504\n#define MHD_HTTP_HTTP_VERSION_NOT_SUPPORTED 505\n#define MHD_HTTP_VARIANT_ALSO_NEGOTIATES 506\n#define MHD_HTTP_INSUFFICIENT_STORAGE 507\n#define MHD_HTTP_BANDWIDTH_LIMIT_EXCEEDED 509\n#define MHD_HTTP_NOT_EXTENDED 510\n\n/** @} */ /* end of group httpcode */\n\n/**\n * Returns the string reason phrase for a response code.\n *\n * If we don't have a string for a status code, we give the first\n * message in that status code class.\n */\n_MHD_EXTERN const char *\nMHD_get_reason_phrase_for (unsigned int code);\n\n\n/**\n * Flag to be or-ed with MHD_HTTP status code for\n * SHOUTcast.  This will cause the response to begin\n * with the SHOUTcast \"ICY\" line instad of \"HTTP\".\n * @ingroup specialized\n */\n#define MHD_ICY_FLAG ((uint32_t)(((uint32_t)1) << 31))\n\n/**\n * @defgroup headers HTTP headers\n * These are the standard headers found in HTTP requests and responses.\n * @{\n */\n/* See also: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html */\n#define MHD_HTTP_HEADER_ACCEPT \"Accept\"\n#define MHD_HTTP_HEADER_ACCEPT_CHARSET \"Accept-Charset\"\n#define MHD_HTTP_HEADER_ACCEPT_ENCODING \"Accept-Encoding\"\n#define MHD_HTTP_HEADER_ACCEPT_LANGUAGE \"Accept-Language\"\n#define MHD_HTTP_HEADER_ACCEPT_RANGES \"Accept-Ranges\"\n#define MHD_HTTP_HEADER_AGE \"Age\"\n#define MHD_HTTP_HEADER_ALLOW \"Allow\"\n#define MHD_HTTP_HEADER_AUTHORIZATION \"Authorization\"\n#define MHD_HTTP_HEADER_CACHE_CONTROL \"Cache-Control\"\n#define MHD_HTTP_HEADER_CONNECTION \"Connection\"\n#define MHD_HTTP_HEADER_CONTENT_ENCODING \"Content-Encoding\"\n#define MHD_HTTP_HEADER_CONTENT_LANGUAGE \"Content-Language\"\n#define MHD_HTTP_HEADER_CONTENT_LENGTH \"Content-Length\"\n#define MHD_HTTP_HEADER_CONTENT_LOCATION \"Content-Location\"\n#define MHD_HTTP_HEADER_CONTENT_MD5 \"Content-MD5\"\n#define MHD_HTTP_HEADER_CONTENT_RANGE \"Content-Range\"\n#define MHD_HTTP_HEADER_CONTENT_TYPE \"Content-Type\"\n#define MHD_HTTP_HEADER_COOKIE \"Cookie\"\n#define MHD_HTTP_HEADER_DATE \"Date\"\n#define MHD_HTTP_HEADER_ETAG \"ETag\"\n#define MHD_HTTP_HEADER_EXPECT \"Expect\"\n#define MHD_HTTP_HEADER_EXPIRES \"Expires\"\n#define MHD_HTTP_HEADER_FROM \"From\"\n#define MHD_HTTP_HEADER_HOST \"Host\"\n#define MHD_HTTP_HEADER_IF_MATCH \"If-Match\"\n#define MHD_HTTP_HEADER_IF_MODIFIED_SINCE \"If-Modified-Since\"\n#define MHD_HTTP_HEADER_IF_NONE_MATCH \"If-None-Match\"\n#define MHD_HTTP_HEADER_IF_RANGE \"If-Range\"\n#define MHD_HTTP_HEADER_IF_UNMODIFIED_SINCE \"If-Unmodified-Since\"\n#define MHD_HTTP_HEADER_LAST_MODIFIED \"Last-Modified\"\n#define MHD_HTTP_HEADER_LOCATION \"Location\"\n#define MHD_HTTP_HEADER_MAX_FORWARDS \"Max-Forwards\"\n#define MHD_HTTP_HEADER_PRAGMA \"Pragma\"\n#define MHD_HTTP_HEADER_PROXY_AUTHENTICATE \"Proxy-Authenticate\"\n#define MHD_HTTP_HEADER_PROXY_AUTHORIZATION \"Proxy-Authorization\"\n#define MHD_HTTP_HEADER_RANGE \"Range\"\n/* This is not a typo, see HTTP spec */\n#define MHD_HTTP_HEADER_REFERER \"Referer\"\n#define MHD_HTTP_HEADER_RETRY_AFTER \"Retry-After\"\n#define MHD_HTTP_HEADER_SERVER \"Server\"\n#define MHD_HTTP_HEADER_SET_COOKIE \"Set-Cookie\"\n#define MHD_HTTP_HEADER_SET_COOKIE2 \"Set-Cookie2\"\n#define MHD_HTTP_HEADER_TE \"TE\"\n#define MHD_HTTP_HEADER_TRAILER \"Trailer\"\n#define MHD_HTTP_HEADER_TRANSFER_ENCODING \"Transfer-Encoding\"\n#define MHD_HTTP_HEADER_UPGRADE \"Upgrade\"\n#define MHD_HTTP_HEADER_USER_AGENT \"User-Agent\"\n#define MHD_HTTP_HEADER_VARY \"Vary\"\n#define MHD_HTTP_HEADER_VIA \"Via\"\n#define MHD_HTTP_HEADER_WARNING \"Warning\"\n#define MHD_HTTP_HEADER_WWW_AUTHENTICATE \"WWW-Authenticate\"\n#define MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN \"Access-Control-Allow-Origin\"\n#define MHD_HTTP_HEADER_CONTENT_DISPOSITION \"Content-Disposition\"\n\n/** @} */ /* end of group headers */\n\n/**\n * @defgroup versions HTTP versions\n * These strings should be used to match against the first line of the\n * HTTP header.\n * @{\n */\n#define MHD_HTTP_VERSION_1_0 \"HTTP/1.0\"\n#define MHD_HTTP_VERSION_1_1 \"HTTP/1.1\"\n\n/** @} */ /* end of group versions */\n\n/**\n * @defgroup methods HTTP methods\n * Standard HTTP methods (as strings).\n * @{\n */\n#define MHD_HTTP_METHOD_CONNECT \"CONNECT\"\n#define MHD_HTTP_METHOD_DELETE \"DELETE\"\n#define MHD_HTTP_METHOD_GET \"GET\"\n#define MHD_HTTP_METHOD_HEAD \"HEAD\"\n#define MHD_HTTP_METHOD_OPTIONS \"OPTIONS\"\n#define MHD_HTTP_METHOD_POST \"POST\"\n#define MHD_HTTP_METHOD_PUT \"PUT\"\n#define MHD_HTTP_METHOD_PATCH \"PATCH\"\n#define MHD_HTTP_METHOD_TRACE \"TRACE\"\n\n/** @} */ /* end of group methods */\n\n/**\n * @defgroup postenc HTTP POST encodings\n * See also: http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4\n * @{\n */\n#define MHD_HTTP_POST_ENCODING_FORM_URLENCODED \"application/x-www-form-urlencoded\"\n#define MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA \"multipart/form-data\"\n\n/** @} */ /* end of group postenc */\n\n\n/**\n * @brief Handle for the daemon (listening on a socket for HTTP traffic).\n * @ingroup event\n */\nstruct MHD_Daemon;\n\n/**\n * @brief Handle for a connection / HTTP request.\n *\n * With HTTP/1.1, multiple requests can be run over the same\n * connection.  However, MHD will only show one request per TCP\n * connection to the client at any given time.\n * @ingroup request\n */\nstruct MHD_Connection;\n\n/**\n * @brief Handle for a response.\n * @ingroup response\n */\nstruct MHD_Response;\n\n/**\n * @brief Handle for POST processing.\n * @ingroup response\n */\nstruct MHD_PostProcessor;\n\n\n/**\n * @brief Flags for the `struct MHD_Daemon`.\n *\n * Note that if neither #MHD_USE_THREAD_PER_CONNECTION nor\n * #MHD_USE_SELECT_INTERNALLY is used, the client wants control over\n * the process and will call the appropriate microhttpd callbacks.\n *\n * Starting the daemon may also fail if a particular option is not\n * implemented or not supported on the target platform (i.e. no\n * support for SSL, threads or IPv6).\n */\nenum MHD_FLAG\n{\n  /**\n   * No options selected.\n   */\n  MHD_NO_FLAG = 0,\n\n  /**\n   * Run in debug mode.  If this flag is used, the library should\n   * print error messages and warnings to `stderr`.\n   */\n  MHD_USE_DEBUG = 1,\n\n  /**\n   * Run in HTTPS mode.\n   */\n  MHD_USE_SSL = 2,\n\n  /**\n   * Run using one thread per connection.\n   */\n  MHD_USE_THREAD_PER_CONNECTION = 4,\n\n  /**\n   * Run using an internal thread (or thread pool) doing `select()`.\n   */\n  MHD_USE_SELECT_INTERNALLY = 8,\n\n  /**\n   * Run using the IPv6 protocol (otherwise, MHD will just support\n   * IPv4).  If you want MHD to support IPv4 and IPv6 using a single\n   * socket, pass #MHD_USE_DUAL_STACK, otherwise, if you only pass\n   * this option, MHD will try to bind to IPv6-only (resulting in\n   * no IPv4 support).\n   */\n  MHD_USE_IPv6 = 16,\n\n  /**\n   * Be pedantic about the protocol (as opposed to as tolerant as\n   * possible).  Specifically, at the moment, this flag causes MHD to\n   * reject HTTP 1.1 connections without a \"Host\" header.  This is\n   * required by the standard, but of course in violation of the \"be\n   * as liberal as possible in what you accept\" norm.  It is\n   * recommended to turn this ON if you are testing clients against\n   * MHD, and OFF in production.\n   */\n  MHD_USE_PEDANTIC_CHECKS = 32,\n\n  /**\n   * Use `poll()` instead of `select()`. This allows sockets with `fd >=\n   * FD_SETSIZE`.  This option is not compatible with using an\n   * 'external' `select()` mode (as there is no API to get the file\n   * descriptors for the external select from MHD) and must also not\n   * be used in combination with #MHD_USE_EPOLL.\n   */\n  MHD_USE_POLL = 64,\n\n  /**\n   * Run using an internal thread (or thread pool) doing `poll()`.\n   */\n  MHD_USE_POLL_INTERNALLY = MHD_USE_SELECT_INTERNALLY | MHD_USE_POLL,\n\n  /**\n   * Suppress (automatically) adding the 'Date:' header to HTTP responses.\n   * This option should ONLY be used on systems that do not have a clock\n   * and that DO provide other mechanisms for cache control.  See also\n   * RFC 2616, section 14.18 (exception 3).\n   */\n  MHD_SUPPRESS_DATE_NO_CLOCK = 128,\n\n  /**\n   * Run without a listen socket.  This option only makes sense if\n   * #MHD_add_connection is to be used exclusively to connect HTTP\n   * clients to the HTTP server.  This option is incompatible with\n   * using a thread pool; if it is used, #MHD_OPTION_THREAD_POOL_SIZE\n   * is ignored.\n   */\n  MHD_USE_NO_LISTEN_SOCKET = 256,\n\n  /**\n   * Use `epoll()` instead of `select()` or `poll()` for the event loop.\n   * This option is only available on some systems; using the option on\n   * systems without epoll will cause #MHD_start_daemon to fail.  Using\n   * this option is not supported with #MHD_USE_THREAD_PER_CONNECTION.\n   * @sa ::MHD_FEATURE_EPOLL\n   */\n  MHD_USE_EPOLL = 512,\n\n/** @deprecated */\n#define MHD_USE_EPOLL_LINUX_ONLY \\\n  _MHD_DEPR_IN_MACRO(\"Value MHD_USE_EPOLL_LINUX_ONLY is deprecated, use MHD_USE_EPOLL\") \\\n  MHD_USE_EPOLL\n\n  /**\n   * Run using an internal thread (or thread pool) doing `epoll()`.\n   * This option is only available on Linux; using the option on\n   * non-Linux systems will cause #MHD_start_daemon to fail.\n   */\n  MHD_USE_EPOLL_INTERNALLY = MHD_USE_SELECT_INTERNALLY | MHD_USE_EPOLL,\n\n/** @deprecated */\n#define MHD_USE_EPOLL_INTERNALLY_LINUX_ONLY \\\n  _MHD_DEPR_IN_MACRO(\"Value MHD_USE_EPOLL_INTERNALLY_LINUX_ONLY is deprecated, use MHD_USE_EPOLL_INTERNALLY\") \\\n  MHD_USE_EPOLL_INTERNALLY\n\n  /**\n   * Force MHD to use a signal pipe to notify the event loop (of\n   * threads) of our shutdown.  This is required if an appliction uses\n   * #MHD_USE_SELECT_INTERNALLY or #MHD_USE_THREAD_PER_CONNECTION and\n   * then performs #MHD_quiesce_daemon (which eliminates our ability\n   * to signal termination via the listen socket).  In these modes,\n   * #MHD_quiesce_daemon will fail if this option was not set.  Also,\n   * use of this option is automatic (as in, you do not even have to\n   * specify it), if #MHD_USE_NO_LISTEN_SOCKET is specified.  In\n   * \"external\" `select()` mode, this option is always simply ignored.\n   * MHD can be build for use a pair of sockets instead of a pipe.\n   * Pair of sockets is forced on W32.\n   *\n   * You must also use this option if you use internal select mode\n   * or a thread pool in conjunction with #MHD_add_connection.\n   */\n  MHD_USE_PIPE_FOR_SHUTDOWN = 1024,\n\n  /**\n   * Use a single socket for IPv4 and IPv6.\n   */\n  MHD_USE_DUAL_STACK = MHD_USE_IPv6 | 2048,\n\n  /**\n   * Enable `epoll()` turbo.  Disables certain calls to `shutdown()`\n   * and enables aggressive non-blocking optimisitc reads.\n   * Most effects only happen with #MHD_USE_EPOLL.\n   * Enalbed always on W32 as winsock does not properly behave\n   * with `shutdown()` and this then fixes potential problems.\n   */\n  MHD_USE_EPOLL_TURBO = 4096,\n\n  /**\n   * Enable suspend/resume functions, which also implies setting up\n   * pipes to signal resume.\n   */\n  MHD_USE_SUSPEND_RESUME = 8192 | MHD_USE_PIPE_FOR_SHUTDOWN,\n\n  /**\n   * Enable TCP_FASTOPEN option.  This option is only available on Linux with a\n   * kernel >= 3.6.  On other systems, using this option cases #MHD_start_daemon\n   * to fail.\n   */\n  MHD_USE_TCP_FASTOPEN = 16384\n\n};\n\n\n/**\n * Type of a callback function used for logging by MHD.\n *\n * @param cls closure\n * @param fm format string (`printf()`-style)\n * @param ap arguments to @a fm\n * @ingroup logging\n */\ntypedef void\n(*MHD_LogCallback)(void *cls,\n                   const char *fm,\n                   va_list ap);\n\n\n/**\n * @brief MHD options.\n *\n * Passed in the varargs portion of #MHD_start_daemon.\n */\nenum MHD_OPTION\n{\n\n  /**\n   * No more options / last option.  This is used\n   * to terminate the VARARGs list.\n   */\n  MHD_OPTION_END = 0,\n\n  /**\n   * Maximum memory size per connection (followed by a `size_t`).\n   * Default is 32 kb (#MHD_POOL_SIZE_DEFAULT).\n   * Values above 128k are unlikely to result in much benefit, as half\n   * of the memory will be typically used for IO, and TCP buffers are\n   * unlikely to support window sizes above 64k on most systems.\n   */\n  MHD_OPTION_CONNECTION_MEMORY_LIMIT = 1,\n\n  /**\n   * Maximum number of concurrent connections to\n   * accept (followed by an `unsigned int`).\n   */\n  MHD_OPTION_CONNECTION_LIMIT = 2,\n\n  /**\n   * After how many seconds of inactivity should a\n   * connection automatically be timed out? (followed\n   * by an `unsigned int`; use zero for no timeout).\n   */\n  MHD_OPTION_CONNECTION_TIMEOUT = 3,\n\n  /**\n   * Register a function that should be called whenever a request has\n   * been completed (this can be used for application-specific clean\n   * up).  Requests that have never been presented to the application\n   * (via #MHD_AccessHandlerCallback) will not result in\n   * notifications.\n   *\n   * This option should be followed by TWO pointers.  First a pointer\n   * to a function of type #MHD_RequestCompletedCallback and second a\n   * pointer to a closure to pass to the request completed callback.\n   * The second pointer maybe NULL.\n   */\n  MHD_OPTION_NOTIFY_COMPLETED = 4,\n\n  /**\n   * Limit on the number of (concurrent) connections made to the\n   * server from the same IP address.  Can be used to prevent one\n   * IP from taking over all of the allowed connections.  If the\n   * same IP tries to establish more than the specified number of\n   * connections, they will be immediately rejected.  The option\n   * should be followed by an `unsigned int`.  The default is\n   * zero, which means no limit on the number of connections\n   * from the same IP address.\n   */\n  MHD_OPTION_PER_IP_CONNECTION_LIMIT = 5,\n\n  /**\n   * Bind daemon to the supplied `struct sockaddr`. This option should\n   * be followed by a `struct sockaddr *`.  If #MHD_USE_IPv6 is\n   * specified, the `struct sockaddr*` should point to a `struct\n   * sockaddr_in6`, otherwise to a `struct sockaddr_in`.\n   */\n  MHD_OPTION_SOCK_ADDR = 6,\n\n  /**\n   * Specify a function that should be called before parsing the URI from\n   * the client.  The specified callback function can be used for processing\n   * the URI (including the options) before it is parsed.  The URI after\n   * parsing will no longer contain the options, which maybe inconvenient for\n   * logging.  This option should be followed by two arguments, the first\n   * one must be of the form\n   *\n   *     void * my_logger(void *cls, const char *uri, struct MHD_Connection *con)\n   *\n   * where the return value will be passed as\n   * (`* con_cls`) in calls to the #MHD_AccessHandlerCallback\n   * when this request is processed later; returning a\n   * value of NULL has no special significance (however,\n   * note that if you return non-NULL, you can no longer\n   * rely on the first call to the access handler having\n   * `NULL == *con_cls` on entry;)\n   * \"cls\" will be set to the second argument following\n   * #MHD_OPTION_URI_LOG_CALLBACK.  Finally, uri will\n   * be the 0-terminated URI of the request.\n   *\n   * Note that during the time of this call, most of the connection's\n   * state is not initialized (as we have not yet parsed he headers).\n   * However, information about the connecting client (IP, socket)\n   * is available.\n   */\n  MHD_OPTION_URI_LOG_CALLBACK = 7,\n\n  /**\n   * Memory pointer for the private key (key.pem) to be used by the\n   * HTTPS daemon.  This option should be followed by a\n   * `const char *` argument.\n   * This should be used in conjunction with #MHD_OPTION_HTTPS_MEM_CERT.\n   */\n  MHD_OPTION_HTTPS_MEM_KEY = 8,\n\n  /**\n   * Memory pointer for the certificate (cert.pem) to be used by the\n   * HTTPS daemon.  This option should be followed by a\n   * `const char *` argument.\n   * This should be used in conjunction with #MHD_OPTION_HTTPS_MEM_KEY.\n   */\n  MHD_OPTION_HTTPS_MEM_CERT = 9,\n\n  /**\n   * Daemon credentials type.\n   * Followed by an argument of type\n   * `gnutls_credentials_type_t`.\n   */\n  MHD_OPTION_HTTPS_CRED_TYPE = 10,\n\n  /**\n   * Memory pointer to a `const char *` specifying the\n   * cipher algorithm (default: \"NORMAL\").\n   */\n  MHD_OPTION_HTTPS_PRIORITIES = 11,\n\n  /**\n   * Pass a listen socket for MHD to use (systemd-style).  If this\n   * option is used, MHD will not open its own listen socket(s). The\n   * argument passed must be of type `MHD_socket` and refer to an\n   * existing socket that has been bound to a port and is listening.\n   */\n  MHD_OPTION_LISTEN_SOCKET = 12,\n\n  /**\n   * Use the given function for logging error messages.  This option\n   * must be followed by two arguments; the first must be a pointer to\n   * a function of type #MHD_LogCallback and the second a pointer\n   * `void *` which will be passed as the first argument to the log\n   * callback.\n   *\n   * Note that MHD will not generate any log messages\n   * if it was compiled without the \"--enable-messages\"\n   * flag being set.\n   */\n  MHD_OPTION_EXTERNAL_LOGGER = 13,\n\n  /**\n   * Number (`unsigned int`) of threads in thread pool. Enable\n   * thread pooling by setting this value to to something\n   * greater than 1. Currently, thread model must be\n   * #MHD_USE_SELECT_INTERNALLY if thread pooling is enabled\n   * (#MHD_start_daemon returns NULL for an unsupported thread\n   * model).\n   */\n  MHD_OPTION_THREAD_POOL_SIZE = 14,\n\n  /**\n   * Additional options given in an array of `struct MHD_OptionItem`.\n   * The array must be terminated with an entry `{MHD_OPTION_END, 0, NULL}`.\n   * An example for code using #MHD_OPTION_ARRAY is:\n   *\n   *     struct MHD_OptionItem ops[] = {\n   *       { MHD_OPTION_CONNECTION_LIMIT, 100, NULL },\n   *       { MHD_OPTION_CONNECTION_TIMEOUT, 10, NULL },\n   *       { MHD_OPTION_END, 0, NULL }\n   *     };\n   *     d = MHD_start_daemon (0, 8080, NULL, NULL, dh, NULL,\n   *                           MHD_OPTION_ARRAY, ops,\n   *                           MHD_OPTION_END);\n   *\n   * For options that expect a single pointer argument, the\n   * second member of the `struct MHD_OptionItem` is ignored.\n   * For options that expect two pointer arguments, the first\n   * argument must be cast to `intptr_t`.\n   */\n  MHD_OPTION_ARRAY = 15,\n\n  /**\n   * Specify a function that should be called for unescaping escape\n   * sequences in URIs and URI arguments.  Note that this function\n   * will NOT be used by the `struct MHD_PostProcessor`.  If this\n   * option is not specified, the default method will be used which\n   * decodes escape sequences of the form \"%HH\".  This option should\n   * be followed by two arguments, the first one must be of the form\n   *\n   *     size_t my_unescaper(void *cls,\n   *                         struct MHD_Connection *c,\n   *                         char *s)\n   *\n   * where the return value must be \"strlen(s)\" and \"s\" should be\n   * updated.  Note that the unescape function must not lengthen \"s\"\n   * (the result must be shorter than the input and still be\n   * 0-terminated).  \"cls\" will be set to the second argument\n   * following #MHD_OPTION_UNESCAPE_CALLBACK.\n   */\n  MHD_OPTION_UNESCAPE_CALLBACK = 16,\n\n  /**\n   * Memory pointer for the random values to be used by the Digest\n   * Auth module. This option should be followed by two arguments.\n   * First an integer of type  `size_t` which specifies the size\n   * of the buffer pointed to by the second argument in bytes.\n   * Note that the application must ensure that the buffer of the\n   * second argument remains allocated and unmodified while the\n   * deamon is running.\n   */\n  MHD_OPTION_DIGEST_AUTH_RANDOM = 17,\n\n  /**\n   * Size of the internal array holding the map of the nonce and\n   * the nonce counter. This option should be followed by an `unsigend int`\n   * argument.\n   */\n  MHD_OPTION_NONCE_NC_SIZE = 18,\n\n  /**\n   * Desired size of the stack for threads created by MHD. Followed\n   * by an argument of type `size_t`.  Use 0 for system default.\n   */\n  MHD_OPTION_THREAD_STACK_SIZE = 19,\n\n  /**\n   * Memory pointer for the certificate (ca.pem) to be used by the\n   * HTTPS daemon for client authentification.\n   * This option should be followed by a `const char *` argument.\n   */\n  MHD_OPTION_HTTPS_MEM_TRUST = 20,\n\n  /**\n   * Increment to use for growing the read buffer (followed by a\n   * `size_t`). Must fit within #MHD_OPTION_CONNECTION_MEMORY_LIMIT.\n   */\n  MHD_OPTION_CONNECTION_MEMORY_INCREMENT = 21,\n\n  /**\n   * Use a callback to determine which X.509 certificate should be\n   * used for a given HTTPS connection.  This option should be\n   * followed by a argument of type `gnutls_certificate_retrieve_function2 *`.\n   * This option provides an\n   * alternative to #MHD_OPTION_HTTPS_MEM_KEY,\n   * #MHD_OPTION_HTTPS_MEM_CERT.  You must use this version if\n   * multiple domains are to be hosted at the same IP address using\n   * TLS's Server Name Indication (SNI) extension.  In this case,\n   * the callback is expected to select the correct certificate\n   * based on the SNI information provided.  The callback is expected\n   * to access the SNI data using `gnutls_server_name_get()`.\n   * Using this option requires GnuTLS 3.0 or higher.\n   */\n  MHD_OPTION_HTTPS_CERT_CALLBACK = 22,\n\n  /**\n   * When using #MHD_USE_TCP_FASTOPEN, this option changes the default TCP\n   * fastopen queue length of 50.  Note that having a larger queue size can\n   * cause resource exhaustion attack as the TCP stack has to now allocate\n   * resources for the SYN packet along with its DATA.  This option should be\n   * followed by an `unsigned int` argument.\n   */\n  MHD_OPTION_TCP_FASTOPEN_QUEUE_SIZE = 23,\n\n  /**\n   * Memory pointer for the Diffie-Hellman parameters (dh.pem) to be used by the\n   * HTTPS daemon for key exchange.\n   * This option must be followed by a `const char *` argument.\n   */\n  MHD_OPTION_HTTPS_MEM_DHPARAMS = 24,\n\n  /**\n   * If present and set to true, allow reusing address:port socket\n   * (by using SO_REUSEPORT on most platform, or platform-specific ways).\n   * If present and set to false, disallow reusing address:port socket\n   * (does nothing on most plaform, but uses SO_EXCLUSIVEADDRUSE on Windows).\n   * This option must be followed by a `unsigned int` argument.\n   */\n  MHD_OPTION_LISTENING_ADDRESS_REUSE = 25,\n\n  /**\n   * Memory pointer for a password that decrypts the private key (key.pem)\n   * to be used by the HTTPS daemon. This option should be followed by a\n   * `const char *` argument.\n   * This should be used in conjunction with #MHD_OPTION_HTTPS_MEM_KEY.\n   * @sa ::MHD_FEATURE_HTTPS_KEY_PASSWORD\n   */\n  MHD_OPTION_HTTPS_KEY_PASSWORD = 26,\n\n  /**\n   * Register a function that should be called whenever a connection is\n   * started or closed.\n   *\n   * This option should be followed by TWO pointers.  First a pointer\n   * to a function of type #MHD_NotifyConnectionCallback and second a\n   * pointer to a closure to pass to the request completed callback.\n   * The second pointer maybe NULL.\n   */\n  MHD_OPTION_NOTIFY_CONNECTION = 27,\n\n  /**\n   * Allow to change maximum length of the queue of pending connections on\n   * listen socket. If not present than default platform-specific SOMAXCONN\n   * value is used. This option should be followed by an `unsigned int`\n   * argument.\n   */\n  MHD_OPTION_LISTEN_BACKLOG_SIZE = 28\n};\n\n\n/**\n * Entry in an #MHD_OPTION_ARRAY.\n */\nstruct MHD_OptionItem\n{\n  /**\n   * Which option is being given.  Use #MHD_OPTION_END\n   * to terminate the array.\n   */\n  enum MHD_OPTION option;\n\n  /**\n   * Option value (for integer arguments, and for options requiring\n   * two pointer arguments); should be 0 for options that take no\n   * arguments or only a single pointer argument.\n   */\n  intptr_t value;\n\n  /**\n   * Pointer option value (use NULL for options taking no arguments\n   * or only an integer option).\n   */\n  void *ptr_value;\n\n};\n\n\n/**\n * The `enum MHD_ValueKind` specifies the source of\n * the key-value pairs in the HTTP protocol.\n */\nenum MHD_ValueKind\n{\n\n  /**\n   * Response header\n   */\n  MHD_RESPONSE_HEADER_KIND = 0,\n\n  /**\n   * HTTP header.\n   */\n  MHD_HEADER_KIND = 1,\n\n  /**\n   * Cookies.  Note that the original HTTP header containing\n   * the cookie(s) will still be available and intact.\n   */\n  MHD_COOKIE_KIND = 2,\n\n  /**\n   * POST data.  This is available only if a content encoding\n   * supported by MHD is used (currently only URL encoding),\n   * and only if the posted content fits within the available\n   * memory pool.  Note that in that case, the upload data\n   * given to the #MHD_AccessHandlerCallback will be\n   * empty (since it has already been processed).\n   */\n  MHD_POSTDATA_KIND = 4,\n\n  /**\n   * GET (URI) arguments.\n   */\n  MHD_GET_ARGUMENT_KIND = 8,\n\n  /**\n   * HTTP footer (only for HTTP 1.1 chunked encodings).\n   */\n  MHD_FOOTER_KIND = 16\n};\n\n\n/**\n * The `enum MHD_RequestTerminationCode` specifies reasons\n * why a request has been terminated (or completed).\n * @ingroup request\n */\nenum MHD_RequestTerminationCode\n{\n\n  /**\n   * We finished sending the response.\n   * @ingroup request\n   */\n  MHD_REQUEST_TERMINATED_COMPLETED_OK = 0,\n\n  /**\n   * Error handling the connection (resources\n   * exhausted, other side closed connection,\n   * application error accepting request, etc.)\n   * @ingroup request\n   */\n  MHD_REQUEST_TERMINATED_WITH_ERROR = 1,\n\n  /**\n   * No activity on the connection for the number\n   * of seconds specified using\n   * #MHD_OPTION_CONNECTION_TIMEOUT.\n   * @ingroup request\n   */\n  MHD_REQUEST_TERMINATED_TIMEOUT_REACHED = 2,\n\n  /**\n   * We had to close the session since MHD was being\n   * shut down.\n   * @ingroup request\n   */\n  MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN = 3,\n\n  /**\n   * We tried to read additional data, but the other side closed the\n   * connection.  This error is similar to\n   * #MHD_REQUEST_TERMINATED_WITH_ERROR, but specific to the case where\n   * the connection died because the other side did not send expected\n   * data.\n   * @ingroup request\n   */\n  MHD_REQUEST_TERMINATED_READ_ERROR = 4,\n\n  /**\n   * The client terminated the connection by closing the socket\n   * for writing (TCP half-closed); MHD aborted sending the\n   * response according to RFC 2616, section 8.1.4.\n   * @ingroup request\n   */\n  MHD_REQUEST_TERMINATED_CLIENT_ABORT = 5\n\n};\n\n\n/**\n * The `enum MHD_ConnectionNotificationCode` specifies types\n * of connection notifications.\n * @ingroup request\n */\nenum MHD_ConnectionNotificationCode\n{\n\n  /**\n   * A new connection has been started.\n   * @ingroup request\n   */\n  MHD_CONNECTION_NOTIFY_STARTED = 0,\n\n  /**\n   * A connection is closed.\n   * @ingroup request\n   */\n  MHD_CONNECTION_NOTIFY_CLOSED = 1\n\n};\n\n\n/**\n * Information about a connection.\n */\nunion MHD_ConnectionInfo\n{\n\n  /**\n   * Cipher algorithm used, of type \"enum gnutls_cipher_algorithm\".\n   */\n  int /* enum gnutls_cipher_algorithm */ cipher_algorithm;\n\n  /**\n   * Protocol used, of type \"enum gnutls_protocol\".\n   */\n  int /* enum gnutls_protocol */ protocol;\n\n  /**\n   * The suspended status of a connection.\n   */\n  int /* MHD_YES or MHD_NO */ suspended;\n\n  /**\n   * Connect socket\n   */\n  MHD_socket connect_fd;\n\n  /**\n   * GNUtls session handle, of type \"gnutls_session_t\".\n   */\n  void * /* gnutls_session_t */ tls_session;\n\n  /**\n   * GNUtls client certificate handle, of type \"gnutls_x509_crt_t\".\n   */\n  void * /* gnutls_x509_crt_t */ client_cert;\n\n  /**\n   * Address information for the client.\n   */\n  struct sockaddr *client_addr;\n\n  /**\n   * Which daemon manages this connection (useful in case there are many\n   * daemons running).\n   */\n  struct MHD_Daemon *daemon;\n\n  /**\n   * Socket-specific client context.  Points to the same address as\n   * the \"socket_context\" of the #MHD_NotifyConnectionCallback.\n   */\n  void **socket_context;\n};\n\n\n/**\n * Values of this enum are used to specify what\n * information about a connection is desired.\n * @ingroup request\n */\nenum MHD_ConnectionInfoType\n{\n  /**\n   * What cipher algorithm is being used.\n   * Takes no extra arguments.\n   * @ingroup request\n   */\n  MHD_CONNECTION_INFO_CIPHER_ALGO,\n\n  /**\n   *\n   * Takes no extra arguments.\n   * @ingroup request\n   */\n  MHD_CONNECTION_INFO_PROTOCOL,\n\n  /**\n   * Obtain IP address of the client.  Takes no extra arguments.\n   * Returns essentially a `struct sockaddr **` (since the API returns\n   * a `union MHD_ConnectionInfo *` and that union contains a `struct\n   * sockaddr *`).\n   * @ingroup request\n   */\n  MHD_CONNECTION_INFO_CLIENT_ADDRESS,\n\n  /**\n   * Get the gnuTLS session handle.\n   * @ingroup request\n   */\n  MHD_CONNECTION_INFO_GNUTLS_SESSION,\n\n  /**\n   * Get the gnuTLS client certificate handle.  Dysfunctional (never\n   * implemented, deprecated).  Use #MHD_CONNECTION_INFO_GNUTLS_SESSION\n   * to get the `gnutls_session_t` and then call\n   * gnutls_certificate_get_peers().\n   */\n  MHD_CONNECTION_INFO_GNUTLS_CLIENT_CERT,\n\n  /**\n   * Get the `struct MHD_Daemon *` responsible for managing this connection.\n   * @ingroup request\n   */\n  MHD_CONNECTION_INFO_DAEMON,\n\n  /**\n   * Request the file descriptor for the listening socket.\n   * No extra arguments should be passed.\n   * @ingroup request\n   */\n  MHD_CONNECTION_INFO_CONNECTION_FD,\n\n  /**\n   * Returns the client-specific pointer to a `void *` that was (possibly)\n   * set during a #MHD_NotifyConnectionCallback when the socket was\n   * first accepted.  Note that this is NOT the same as the \"con_cls\"\n   * argument of the #MHD_AccessHandlerCallback.  The \"con_cls\" is\n   * fresh for each HTTP request, while the \"socket_context\" is fresh\n   * for each socket.\n   */\n  MHD_CONNECTION_INFO_SOCKET_CONTEXT,\n\n  /**\n   * Check wheter the connection is suspended.\n   * @ingroup request\n   */\n  MHD_CONNECTION_INFO_CONNECTION_SUSPENDED\n};\n\n\n/**\n * Values of this enum are used to specify what\n * information about a deamon is desired.\n */\nenum MHD_DaemonInfoType\n{\n  /**\n   * No longer supported (will return NULL).\n   */\n  MHD_DAEMON_INFO_KEY_SIZE,\n\n  /**\n   * No longer supported (will return NULL).\n   */\n  MHD_DAEMON_INFO_MAC_KEY_SIZE,\n\n  /**\n   * Request the file descriptor for the listening socket.\n   * No extra arguments should be passed.\n   */\n  MHD_DAEMON_INFO_LISTEN_FD,\n\n  /**\n   * Request the file descriptor for the external epoll.\n   * No extra arguments should be passed.\n   */\n  MHD_DAEMON_INFO_EPOLL_FD_LINUX_ONLY,\n\n  /**\n   * Request the number of current connections handled by the daemon.\n   * No extra arguments should be passed.\n   */\n  MHD_DAEMON_INFO_CURRENT_CONNECTIONS\n};\n\n\n/**\n * Callback for serious error condition. The default action is to print\n * an error message and `abort()`.\n *\n * @param cls user specified value\n * @param file where the error occured\n * @param line where the error occured\n * @param reason error detail, may be NULL\n * @ingroup logging\n */\ntypedef void\n(*MHD_PanicCallback) (void *cls,\n                      const char *file,\n                      unsigned int line,\n                      const char *reason);\n\n/**\n * Allow or deny a client to connect.\n *\n * @param cls closure\n * @param addr address information from the client\n * @param addrlen length of @a addr\n * @return #MHD_YES if connection is allowed, #MHD_NO if not\n */\ntypedef int\n(*MHD_AcceptPolicyCallback) (void *cls,\n                             const struct sockaddr *addr,\n                             socklen_t addrlen);\n\n\n/**\n * A client has requested the given url using the given method\n * (#MHD_HTTP_METHOD_GET, #MHD_HTTP_METHOD_PUT,\n * #MHD_HTTP_METHOD_DELETE, #MHD_HTTP_METHOD_POST, etc).  The callback\n * must call MHD callbacks to provide content to give back to the\n * client and return an HTTP status code (i.e. #MHD_HTTP_OK,\n * #MHD_HTTP_NOT_FOUND, etc.).\n *\n * @param cls argument given together with the function\n *        pointer when the handler was registered with MHD\n * @param url the requested url\n * @param method the HTTP method used (#MHD_HTTP_METHOD_GET,\n *        #MHD_HTTP_METHOD_PUT, etc.)\n * @param version the HTTP version string (i.e.\n *        #MHD_HTTP_VERSION_1_1)\n * @param upload_data the data being uploaded (excluding HEADERS,\n *        for a POST that fits into memory and that is encoded\n *        with a supported encoding, the POST data will NOT be\n *        given in upload_data and is instead available as\n *        part of #MHD_get_connection_values; very large POST\n *        data *will* be made available incrementally in\n *        @a upload_data)\n * @param upload_data_size set initially to the size of the\n *        @a upload_data provided; the method must update this\n *        value to the number of bytes NOT processed;\n * @param con_cls pointer that the callback can set to some\n *        address and that will be preserved by MHD for future\n *        calls for this request; since the access handler may\n *        be called many times (i.e., for a PUT/POST operation\n *        with plenty of upload data) this allows the application\n *        to easily associate some request-specific state.\n *        If necessary, this state can be cleaned up in the\n *        global #MHD_RequestCompletedCallback (which\n *        can be set with the #MHD_OPTION_NOTIFY_COMPLETED).\n *        Initially, `*con_cls` will be NULL.\n * @return #MHD_YES if the connection was handled successfully,\n *         #MHD_NO if the socket must be closed due to a serios\n *         error while handling the request\n */\ntypedef int\n(*MHD_AccessHandlerCallback) (void *cls,\n                              struct MHD_Connection *connection,\n                              const char *url,\n                              const char *method,\n                              const char *version,\n                              const char *upload_data,\n                              size_t *upload_data_size,\n                              void **con_cls);\n\n\n/**\n * Signature of the callback used by MHD to notify the\n * application about completed requests.\n *\n * @param cls client-defined closure\n * @param connection connection handle\n * @param con_cls value as set by the last call to\n *        the #MHD_AccessHandlerCallback\n * @param toe reason for request termination\n * @see #MHD_OPTION_NOTIFY_COMPLETED\n * @ingroup request\n */\ntypedef void\n(*MHD_RequestCompletedCallback) (void *cls,\n                                 struct MHD_Connection *connection,\n                                 void **con_cls,\n                                 enum MHD_RequestTerminationCode toe);\n\n/**\n * Signature of the callback used by MHD to notify the\n * application about started/stopped connections\n *\n * @param cls client-defined closure\n * @param connection connection handle\n * @param socket_context socket-specific pointer where the\n *                       client can associate some state specific\n *                       to the TCP connection; note that this is\n *                       different from the \"con_cls\" which is per\n *                       HTTP request.  The client can initialize\n *                       during #MHD_CONNECTION_NOTIFY_STARTED and\n *                       cleanup during #MHD_CONNECTION_NOTIFY_CLOSED\n *                       and access in the meantime using\n *                       #MHD_CONNECTION_INFO_SOCKET_CONTEXT.\n * @param toe reason for connection notification\n * @see #MHD_OPTION_NOTIFY_CONNECTION\n * @ingroup request\n */\ntypedef void\n(*MHD_NotifyConnectionCallback) (void *cls,\n                                 struct MHD_Connection *connection,\n                                 void **socket_context,\n                                 enum MHD_ConnectionNotificationCode toe);\n\n\n/**\n * Iterator over key-value pairs.  This iterator\n * can be used to iterate over all of the cookies,\n * headers, or POST-data fields of a request, and\n * also to iterate over the headers that have been\n * added to a response.\n *\n * @param cls closure\n * @param kind kind of the header we are looking at\n * @param key key for the value, can be an empty string\n * @param value corresponding value, can be NULL\n * @return #MHD_YES to continue iterating,\n *         #MHD_NO to abort the iteration\n * @ingroup request\n */\ntypedef int\n(*MHD_KeyValueIterator) (void *cls,\n                         enum MHD_ValueKind kind,\n                         const char *key,\n                         const char *value);\n\n\n/**\n * Callback used by libmicrohttpd in order to obtain content.  The\n * callback is to copy at most @a max bytes of content into @a buf.  The\n * total number of bytes that has been placed into @a buf should be\n * returned.\n *\n * Note that returning zero will cause libmicrohttpd to try again.\n * Thus, returning zero should only be used in conjunction\n * with MHD_suspend_connection() to avoid busy waiting.\n *\n * @param cls extra argument to the callback\n * @param pos position in the datastream to access;\n *        note that if a `struct MHD_Response` object is re-used,\n *        it is possible for the same content reader to\n *        be queried multiple times for the same data;\n *        however, if a `struct MHD_Response` is not re-used,\n *        libmicrohttpd guarantees that \"pos\" will be\n *        the sum of all non-negative return values\n *        obtained from the content reader so far.\n * @param buf where to copy the data\n * @param max maximum number of bytes to copy to @a buf (size of @a buf)\n * @return number of bytes written to @a buf;\n *  0 is legal unless we are running in internal select mode (since\n *    this would cause busy-waiting); 0 in external select mode\n *    will cause this function to be called again once the external\n *    select calls MHD again;\n *  #MHD_CONTENT_READER_END_OF_STREAM (-1) for the regular\n *    end of transmission (with chunked encoding, MHD will then\n *    terminate the chunk and send any HTTP footers that might be\n *    present; without chunked encoding and given an unknown\n *    response size, MHD will simply close the connection; note\n *    that while returning #MHD_CONTENT_READER_END_OF_STREAM is not technically\n *    legal if a response size was specified, MHD accepts this\n *    and treats it just as #MHD_CONTENT_READER_END_WITH_ERROR;\n *  #MHD_CONTENT_READER_END_WITH_ERROR (-2) to indicate a server\n *    error generating the response; this will cause MHD to simply\n *    close the connection immediately.  If a response size was\n *    given or if chunked encoding is in use, this will indicate\n *    an error to the client.  Note, however, that if the client\n *    does not know a response size and chunked encoding is not in\n *    use, then clients will not be able to tell the difference between\n *    #MHD_CONTENT_READER_END_WITH_ERROR and #MHD_CONTENT_READER_END_OF_STREAM.\n *    This is not a limitation of MHD but rather of the HTTP protocol.\n */\ntypedef ssize_t\n(*MHD_ContentReaderCallback) (void *cls,\n                              uint64_t pos,\n                              char *buf,\n                              size_t max);\n\n\n/**\n * This method is called by libmicrohttpd if we\n * are done with a content reader.  It should\n * be used to free resources associated with the\n * content reader.\n *\n * @param cls closure\n * @ingroup response\n */\ntypedef void\n(*MHD_ContentReaderFreeCallback) (void *cls);\n\n\n/**\n * Iterator over key-value pairs where the value\n * maybe made available in increments and/or may\n * not be zero-terminated.  Used for processing\n * POST data.\n *\n * @param cls user-specified closure\n * @param kind type of the value, always #MHD_POSTDATA_KIND when called from MHD\n * @param key 0-terminated key for the value\n * @param filename name of the uploaded file, NULL if not known\n * @param content_type mime-type of the data, NULL if not known\n * @param transfer_encoding encoding of the data, NULL if not known\n * @param data pointer to @a size bytes of data at the\n *              specified offset\n * @param off offset of data in the overall value\n * @param size number of bytes in @a data available\n * @return #MHD_YES to continue iterating,\n *         #MHD_NO to abort the iteration\n */\ntypedef int\n(*MHD_PostDataIterator) (void *cls,\n                         enum MHD_ValueKind kind,\n                         const char *key,\n                         const char *filename,\n                         const char *content_type,\n                         const char *transfer_encoding,\n                         const char *data,\n                         uint64_t off,\n                         size_t size);\n\n/* **************** Daemon handling functions ***************** */\n\n/**\n * Start a webserver on the given port.\n *\n * @param flags combination of `enum MHD_FLAG` values\n * @param port port to bind to (in host byte order)\n * @param apc callback to call to check which clients\n *        will be allowed to connect; you can pass NULL\n *        in which case connections from any IP will be\n *        accepted\n * @param apc_cls extra argument to apc\n * @param dh handler called for all requests (repeatedly)\n * @param dh_cls extra argument to @a dh\n * @param ap list of options (type-value pairs,\n *        terminated with #MHD_OPTION_END).\n * @return NULL on error, handle to daemon on success\n * @ingroup event\n */\n_MHD_EXTERN struct MHD_Daemon *\nMHD_start_daemon_va (unsigned int flags,\n\t\t     uint16_t port,\n\t\t     MHD_AcceptPolicyCallback apc, void *apc_cls,\n\t\t     MHD_AccessHandlerCallback dh, void *dh_cls,\n\t\t     va_list ap);\n\n\n/**\n * Start a webserver on the given port.  Variadic version of\n * #MHD_start_daemon_va.\n *\n * @param flags combination of `enum MHD_FLAG` values\n * @param port port to bind to\n * @param apc callback to call to check which clients\n *        will be allowed to connect; you can pass NULL\n *        in which case connections from any IP will be\n *        accepted\n * @param apc_cls extra argument to apc\n * @param dh handler called for all requests (repeatedly)\n * @param dh_cls extra argument to @a dh\n * @return NULL on error, handle to daemon on success\n * @ingroup event\n */\n_MHD_EXTERN struct MHD_Daemon *\nMHD_start_daemon (unsigned int flags,\n\t\t  uint16_t port,\n\t\t  MHD_AcceptPolicyCallback apc, void *apc_cls,\n\t\t  MHD_AccessHandlerCallback dh, void *dh_cls,\n\t\t  ...);\n\n\n/**\n * Stop accepting connections from the listening socket.  Allows\n * clients to continue processing, but stops accepting new\n * connections.  Note that the caller is responsible for closing the\n * returned socket; however, if MHD is run using threads (anything but\n * external select mode), it must not be closed until AFTER\n * #MHD_stop_daemon has been called (as it is theoretically possible\n * that an existing thread is still using it).\n *\n * Note that some thread modes require the caller to have passed\n * #MHD_USE_PIPE_FOR_SHUTDOWN when using this API.  If this daemon is\n * in one of those modes and this option was not given to\n * #MHD_start_daemon, this function will return #MHD_INVALID_SOCKET.\n *\n * @param daemon daemon to stop accepting new connections for\n * @return old listen socket on success, #MHD_INVALID_SOCKET if\n *         the daemon was already not listening anymore\n * @ingroup specialized\n */\n_MHD_EXTERN MHD_socket\nMHD_quiesce_daemon (struct MHD_Daemon *daemon);\n\n\n/**\n * Shutdown an HTTP daemon.\n *\n * @param daemon daemon to stop\n * @ingroup event\n */\n_MHD_EXTERN void\nMHD_stop_daemon (struct MHD_Daemon *daemon);\n\n\n/**\n * Add another client connection to the set of connections managed by\n * MHD.  This API is usually not needed (since MHD will accept inbound\n * connections on the server socket).  Use this API in special cases,\n * for example if your HTTP server is behind NAT and needs to connect\n * out to the HTTP client, or if you are building a proxy.\n *\n * If you use this API in conjunction with a internal select or a\n * thread pool, you must set the option\n * #MHD_USE_PIPE_FOR_SHUTDOWN to ensure that the freshly added\n * connection is immediately processed by MHD.\n *\n * The given client socket will be managed (and closed!) by MHD after\n * this call and must no longer be used directly by the application\n * afterwards.\n *\n * Per-IP connection limits are ignored when using this API.\n *\n * @param daemon daemon that manages the connection\n * @param client_socket socket to manage (MHD will expect\n *        to receive an HTTP request from this socket next).\n * @param addr IP address of the client\n * @param addrlen number of bytes in @a addr\n * @return #MHD_YES on success, #MHD_NO if this daemon could\n *        not handle the connection (i.e. `malloc()` failed, etc).\n *        The socket will be closed in any case; `errno` is\n *        set to indicate further details about the error.\n * @ingroup specialized\n */\n_MHD_EXTERN int\nMHD_add_connection (struct MHD_Daemon *daemon,\n\t\t    MHD_socket client_socket,\n\t\t    const struct sockaddr *addr,\n\t\t    socklen_t addrlen);\n\n\n/**\n * Obtain the `select()` sets for this daemon.\n * Daemon's FDs will be added to fd_sets. To get only\n * daemon FDs in fd_sets, call FD_ZERO for each fd_set\n * before calling this function. FD_SETSIZE is assumed\n * to be platform's default.\n *\n * @param daemon daemon to get sets from\n * @param read_fd_set read set\n * @param write_fd_set write set\n * @param except_fd_set except set\n * @param max_fd increased to largest FD added (if larger\n *               than existing value); can be NULL\n * @return #MHD_YES on success, #MHD_NO if this\n *         daemon was not started with the right\n *         options for this call or any FD didn't\n *         fit fd_set.\n * @ingroup event\n */\n_MHD_EXTERN int\nMHD_get_fdset (struct MHD_Daemon *daemon,\n               fd_set *read_fd_set,\n               fd_set *write_fd_set,\n\t       fd_set *except_fd_set,\n\t       MHD_socket *max_fd);\n\n\n/**\n * Obtain the `select()` sets for this daemon.\n * Daemon's FDs will be added to fd_sets. To get only\n * daemon FDs in fd_sets, call FD_ZERO for each fd_set\n * before calling this function. Passing custom FD_SETSIZE\n * as @a fd_setsize allow usage of larger/smaller than\n * platform's default fd_sets.\n *\n * @param daemon daemon to get sets from\n * @param read_fd_set read set\n * @param write_fd_set write set\n * @param except_fd_set except set\n * @param max_fd increased to largest FD added (if larger\n *               than existing value); can be NULL\n * @param fd_setsize value of FD_SETSIZE\n * @return #MHD_YES on success, #MHD_NO if this\n *         daemon was not started with the right\n *         options for this call or any FD didn't\n *         fit fd_set.\n * @ingroup event\n */\n_MHD_EXTERN int\nMHD_get_fdset2 (struct MHD_Daemon *daemon,\n               fd_set *read_fd_set,\n               fd_set *write_fd_set,\n               fd_set *except_fd_set,\n               MHD_socket *max_fd,\n               unsigned int fd_setsize);\n\n\n/**\n * Obtain the `select()` sets for this daemon.\n * Daemon's FDs will be added to fd_sets. To get only\n * daemon FDs in fd_sets, call FD_ZERO for each fd_set\n * before calling this function. Size of fd_set is\n * determined by current value of FD_SETSIZE.\n *\n * @param daemon daemon to get sets from\n * @param read_fd_set read set\n * @param write_fd_set write set\n * @param except_fd_set except set\n * @param max_fd increased to largest FD added (if larger\n *               than existing value); can be NULL\n * @return #MHD_YES on success, #MHD_NO if this\n *         daemon was not started with the right\n *         options for this call or any FD didn't\n *         fit fd_set.\n * @ingroup event\n */\n#define MHD_get_fdset(daemon,read_fd_set,write_fd_set,except_fd_set,max_fd) \\\n  MHD_get_fdset2((daemon),(read_fd_set),(write_fd_set),(except_fd_set),(max_fd),FD_SETSIZE)\n\n\n/**\n * Obtain timeout value for `select()` for this daemon (only needed if\n * connection timeout is used).  The returned value is how many milliseconds\n * `select()` or `poll()` should at most block, not the timeout value set for\n * connections.  This function MUST NOT be called if MHD is running with\n * #MHD_USE_THREAD_PER_CONNECTION.\n *\n * @param daemon daemon to query for timeout\n * @param timeout set to the timeout (in milliseconds)\n * @return #MHD_YES on success, #MHD_NO if timeouts are\n *        not used (or no connections exist that would\n *        necessiate the use of a timeout right now).\n * @ingroup event\n */\n_MHD_EXTERN int\nMHD_get_timeout (struct MHD_Daemon *daemon,\n\t\t MHD_UNSIGNED_LONG_LONG *timeout);\n\n\n/**\n * Run webserver operations (without blocking unless in client\n * callbacks).  This method should be called by clients in combination\n * with #MHD_get_fdset if the client-controlled select method is used.\n *\n * This function is a convenience method, which is useful if the\n * fd_sets from #MHD_get_fdset were not directly passed to `select()`;\n * with this function, MHD will internally do the appropriate `select()`\n * call itself again.  While it is always safe to call #MHD_run (in\n * external select mode), you should call #MHD_run_from_select if\n * performance is important (as it saves an expensive call to\n * `select()`).\n *\n * @param daemon daemon to run\n * @return #MHD_YES on success, #MHD_NO if this\n *         daemon was not started with the right\n *         options for this call.\n * @ingroup event\n */\n_MHD_EXTERN int\nMHD_run (struct MHD_Daemon *daemon);\n\n\n/**\n * Run webserver operations. This method should be called by clients\n * in combination with #MHD_get_fdset if the client-controlled select\n * method is used.\n *\n * You can use this function instead of #MHD_run if you called\n * `select()` on the result from #MHD_get_fdset.  File descriptors in\n * the sets that are not controlled by MHD will be ignored.  Calling\n * this function instead of #MHD_run is more efficient as MHD will\n * not have to call `select()` again to determine which operations are\n * ready.\n *\n * @param daemon daemon to run select loop for\n * @param read_fd_set read set\n * @param write_fd_set write set\n * @param except_fd_set except set (not used, can be NULL)\n * @return #MHD_NO on serious errors, #MHD_YES on success\n * @ingroup event\n */\n_MHD_EXTERN int\nMHD_run_from_select (struct MHD_Daemon *daemon,\n\t\t     const fd_set *read_fd_set,\n\t\t     const fd_set *write_fd_set,\n\t\t     const fd_set *except_fd_set);\n\n\n\n\n/* **************** Connection handling functions ***************** */\n\n/**\n * Get all of the headers from the request.\n *\n * @param connection connection to get values from\n * @param kind types of values to iterate over, can be a bitmask\n * @param iterator callback to call on each header;\n *        maybe NULL (then just count headers)\n * @param iterator_cls extra argument to @a iterator\n * @return number of entries iterated over\n * @ingroup request\n */\n_MHD_EXTERN int\nMHD_get_connection_values (struct MHD_Connection *connection,\n                           enum MHD_ValueKind kind,\n                           MHD_KeyValueIterator iterator,\n                           void *iterator_cls);\n\n\n/**\n * This function can be used to add an entry to the HTTP headers of a\n * connection (so that the #MHD_get_connection_values function will\n * return them -- and the `struct MHD_PostProcessor` will also see\n * them).  This maybe required in certain situations (see Mantis\n * #1399) where (broken) HTTP implementations fail to supply values\n * needed by the post processor (or other parts of the application).\n *\n * This function MUST only be called from within the\n * #MHD_AccessHandlerCallback (otherwise, access maybe improperly\n * synchronized).  Furthermore, the client must guarantee that the key\n * and value arguments are 0-terminated strings that are NOT freed\n * until the connection is closed.  (The easiest way to do this is by\n * passing only arguments to permanently allocated strings.).\n *\n * @param connection the connection for which a\n *  value should be set\n * @param kind kind of the value\n * @param key key for the value\n * @param value the value itself\n * @return #MHD_NO if the operation could not be\n *         performed due to insufficient memory;\n *         #MHD_YES on success\n * @ingroup request\n */\n_MHD_EXTERN int\nMHD_set_connection_value (struct MHD_Connection *connection,\n                          enum MHD_ValueKind kind,\n                          const char *key,\n\t\t\t  const char *value);\n\n\n/**\n * Sets the global error handler to a different implementation.  @a cb\n * will only be called in the case of typically fatal, serious\n * internal consistency issues.  These issues should only arise in the\n * case of serious memory corruption or similar problems with the\n * architecture.  While @a cb is allowed to return and MHD will then\n * try to continue, this is never safe.\n *\n * The default implementation that is used if no panic function is set\n * simply prints an error message and calls `abort()`.  Alternative\n * implementations might call `exit()` or other similar functions.\n *\n * @param cb new error handler\n * @param cls passed to @a cb\n * @ingroup logging\n */\n_MHD_EXTERN void\nMHD_set_panic_func (MHD_PanicCallback cb, void *cls);\n\n\n/**\n * Process escape sequences ('%HH') Updates val in place; the\n * result should be UTF-8 encoded and cannot be larger than the input.\n * The result must also still be 0-terminated.\n *\n * @param val value to unescape (modified in the process)\n * @return length of the resulting val (`strlen(val)` may be\n *  shorter afterwards due to elimination of escape sequences)\n */\n_MHD_EXTERN size_t\nMHD_http_unescape (char *val);\n\n\n/**\n * Get a particular header value.  If multiple\n * values match the kind, return any one of them.\n *\n * @param connection connection to get values from\n * @param kind what kind of value are we looking for\n * @param key the header to look for, NULL to lookup 'trailing' value without a key\n * @return NULL if no such item was found\n * @ingroup request\n */\n_MHD_EXTERN const char *\nMHD_lookup_connection_value (struct MHD_Connection *connection,\n\t\t\t     enum MHD_ValueKind kind,\n\t\t\t     const char *key);\n\n\n/**\n * Queue a response to be transmitted to the client (as soon as\n * possible but after #MHD_AccessHandlerCallback returns).\n *\n * @param connection the connection identifying the client\n * @param status_code HTTP status code (i.e. #MHD_HTTP_OK)\n * @param response response to transmit\n * @return #MHD_NO on error (i.e. reply already sent),\n *         #MHD_YES on success or if message has been queued\n * @ingroup response\n */\n_MHD_EXTERN int\nMHD_queue_response (struct MHD_Connection *connection,\n                    unsigned int status_code,\n\t\t    struct MHD_Response *response);\n\n\n/**\n * Suspend handling of network data for a given connection.  This can\n * be used to dequeue a connection from MHD's event loop (external\n * select, internal select or thread pool; not applicable to\n * thread-per-connection!) for a while.\n *\n * If you use this API in conjunction with a internal select or a\n * thread pool, you must set the option #MHD_USE_PIPE_FOR_SHUTDOWN to\n * ensure that a resumed connection is immediately processed by MHD.\n *\n * Suspended connections continue to count against the total number of\n * connections allowed (per daemon, as well as per IP, if such limits\n * are set).  Suspended connections will NOT time out; timeouts will\n * restart when the connection handling is resumed.  While a\n * connection is suspended, MHD will not detect disconnects by the\n * client.\n *\n * The only safe time to suspend a connection is from the\n * #MHD_AccessHandlerCallback.\n *\n * Finally, it is an API violation to call #MHD_stop_daemon while\n * having suspended connections (this will at least create memory and\n * socket leaks or lead to undefined behavior).  You must explicitly\n * resume all connections before stopping the daemon.\n *\n * @param connection the connection to suspend\n */\n_MHD_EXTERN void\nMHD_suspend_connection (struct MHD_Connection *connection);\n\n\n/**\n * Resume handling of network data for suspended connection.  It is\n * safe to resume a suspended connection at any time.  Calling this\n * function on a connection that was not previously suspended will\n * result in undefined behavior.\n *\n * @param connection the connection to resume\n */\n_MHD_EXTERN void\nMHD_resume_connection (struct MHD_Connection *connection);\n\n\n/* **************** Response manipulation functions ***************** */\n\n\n/**\n * Flags for special handling of responses.\n */\nenum MHD_ResponseFlags\n{\n  /**\n   * Default: no special flags.\n   */\n  MHD_RF_NONE = 0,\n\n  /**\n   * Only respond in conservative HTTP 1.0-mode.   In particular,\n   * do not (automatically) sent \"Connection\" headers and always\n   * close the connection after generating the response.\n   */\n  MHD_RF_HTTP_VERSION_1_0_ONLY = 1\n\n};\n\n\n/**\n * MHD options (for future extensions).\n */\nenum MHD_ResponseOptions\n{\n  /**\n   * End of the list of options.\n   */\n  MHD_RO_END = 0\n};\n\n\n/**\n * Set special flags and options for a response.\n *\n * @param response the response to modify\n * @param flags to set for the response\n * @param ... #MHD_RO_END terminated list of options\n * @return #MHD_YES on success, #MHD_NO on error\n */\n_MHD_EXTERN int\nMHD_set_response_options (struct MHD_Response *response,\n                          enum MHD_ResponseFlags flags,\n                          ...);\n\n\n/**\n * Create a response object.  The response object can be extended with\n * header information and then be used any number of times.\n *\n * @param size size of the data portion of the response, #MHD_SIZE_UNKNOWN for unknown\n * @param block_size preferred block size for querying crc (advisory only,\n *                   MHD may still call @a crc using smaller chunks); this\n *                   is essentially the buffer size used for IO, clients\n *                   should pick a value that is appropriate for IO and\n *                   memory performance requirements\n * @param crc callback to use to obtain response data\n * @param crc_cls extra argument to @a crc\n * @param crfc callback to call to free @a crc_cls resources\n * @return NULL on error (i.e. invalid arguments, out of memory)\n * @ingroup response\n */\n_MHD_EXTERN struct MHD_Response *\nMHD_create_response_from_callback (uint64_t size,\n\t\t\t\t   size_t block_size,\n\t\t\t\t   MHD_ContentReaderCallback crc, void *crc_cls,\n\t\t\t\t   MHD_ContentReaderFreeCallback crfc);\n\n\n/**\n * Create a response object.  The response object can be extended with\n * header information and then be used any number of times.\n *\n * @param size size of the @a data portion of the response\n * @param data the data itself\n * @param must_free libmicrohttpd should free data when done\n * @param must_copy libmicrohttpd must make a copy of @a data\n *        right away, the data maybe released anytime after\n *        this call returns\n * @return NULL on error (i.e. invalid arguments, out of memory)\n * @deprecated use #MHD_create_response_from_buffer instead\n * @ingroup response\n */\n_MHD_DEPR_FUNC(\"MHD_create_response_from_data() is deprecated, use MHD_create_response_from_buffer()\") \\\n_MHD_EXTERN struct MHD_Response *\nMHD_create_response_from_data (size_t size,\n\t\t\t       void *data,\n\t\t\t       int must_free,\n\t\t\t       int must_copy);\n\n\n/**\n * Specification for how MHD should treat the memory buffer\n * given for the response.\n * @ingroup response\n */\nenum MHD_ResponseMemoryMode\n{\n\n  /**\n   * Buffer is a persistent (static/global) buffer that won't change\n   * for at least the lifetime of the response, MHD should just use\n   * it, not free it, not copy it, just keep an alias to it.\n   * @ingroup response\n   */\n  MHD_RESPMEM_PERSISTENT,\n\n  /**\n   * Buffer is heap-allocated with `malloc()` (or equivalent) and\n   * should be freed by MHD after processing the response has\n   * concluded (response reference counter reaches zero).\n   * @ingroup response\n   */\n  MHD_RESPMEM_MUST_FREE,\n\n  /**\n   * Buffer is in transient memory, but not on the heap (for example,\n   * on the stack or non-`malloc()` allocated) and only valid during the\n   * call to #MHD_create_response_from_buffer.  MHD must make its\n   * own private copy of the data for processing.\n   * @ingroup response\n   */\n  MHD_RESPMEM_MUST_COPY\n\n};\n\n\n/**\n * Create a response object.  The response object can be extended with\n * header information and then be used any number of times.\n *\n * @param size size of the data portion of the response\n * @param buffer size bytes containing the response's data portion\n * @param mode flags for buffer management\n * @return NULL on error (i.e. invalid arguments, out of memory)\n * @ingroup response\n */\n_MHD_EXTERN struct MHD_Response *\nMHD_create_response_from_buffer (size_t size,\n\t\t\t\t void *buffer,\n\t\t\t\t enum MHD_ResponseMemoryMode mode);\n\n\n/**\n * Create a response object.  The response object can be extended with\n * header information and then be used any number of times.\n *\n * @param size size of the data portion of the response\n * @param fd file descriptor referring to a file on disk with the\n *        data; will be closed when response is destroyed;\n *        fd should be in 'blocking' mode\n * @return NULL on error (i.e. invalid arguments, out of memory)\n * @ingroup response\n */\n_MHD_EXTERN struct MHD_Response *\nMHD_create_response_from_fd (size_t size,\n                               int fd);\n\n\n/**\n * Create a response object.  The response object can be extended with\n * header information and then be used any number of times.\n *\n * @param size size of the data portion of the response;\n *        sizes larger than 2 GiB may be not supported by OS or\n *        MHD build; see ::MHD_FEATURE_LARGE_FILE\n * @param fd file descriptor referring to a file on disk with the\n *        data; will be closed when response is destroyed;\n *        fd should be in 'blocking' mode\n * @return NULL on error (i.e. invalid arguments, out of memory)\n * @ingroup response\n */\n_MHD_EXTERN struct MHD_Response *\nMHD_create_response_from_fd64 (uint64_t size,\n                               int fd);\n\n\n/**\n * Create a response object.  The response object can be extended with\n * header information and then be used any number of times.\n *\n * @param size size of the data portion of the response\n * @param fd file descriptor referring to a file on disk with the\n *        data; will be closed when response is destroyed;\n *        fd should be in 'blocking' mode\n * @param offset offset to start reading from in the file;\n *        Be careful! `off_t` may have been compiled to be a\n *        64-bit variable for MHD, in which case your application\n *        also has to be compiled using the same options! Read\n *        the MHD manual for more details.\n * @return NULL on error (i.e. invalid arguments, out of memory)\n * @ingroup response\n */\n_MHD_DEPR_FUNC(\"Function MHD_create_response_from_fd_at_offset() is deprecated, use MHD_create_response_from_fd_at_offset64()\") \\\n_MHD_EXTERN struct MHD_Response *\nMHD_create_response_from_fd_at_offset (size_t size,\n                                       int fd,\n                                       off_t offset);\n\n#if !defined(_MHD_NO_DEPR_IN_MACRO) || defined(_MHD_NO_DEPR_FUNC)\n/* Substitute MHD_create_response_from_fd_at_offset64() instead of MHD_create_response_from_fd_at_offset()\n   to minimize potential problems with different off_t sizes */\n#define MHD_create_response_from_fd_at_offset(size,fd,offset) \\\n  _MHD_DEPR_IN_MACRO(\"Usage of MHD_create_response_from_fd_at_offset() is deprecated, use MHD_create_response_from_fd_at_offset64()\") \\\n  MHD_create_response_from_fd_at_offset64((size),(fd),(offset))\n#endif /* !_MHD_NO_DEPR_IN_MACRO || _MHD_NO_DEPR_FUNC */\n\n\n/**\n * Create a response object.  The response object can be extended with\n * header information and then be used any number of times.\n *\n * @param size size of the data portion of the response;\n *        sizes larger than 2 GiB may be not supported by OS or\n *        MHD build; see ::MHD_FEATURE_LARGE_FILE\n * @param fd file descriptor referring to a file on disk with the\n *        data; will be closed when response is destroyed;\n *        fd should be in 'blocking' mode\n * @param offset offset to start reading from in the file;\n *        reading file beyond 2 GiB may be not supported by OS or\n *        MHD build; see ::MHD_FEATURE_LARGE_FILE\n * @return NULL on error (i.e. invalid arguments, out of memory)\n * @ingroup response\n */\n_MHD_EXTERN struct MHD_Response *\nMHD_create_response_from_fd_at_offset64 (uint64_t size,\n                                         int fd,\n                                         uint64_t offset);\n\n\n#if 0\n/**\n * Enumeration for actions MHD should perform on the underlying socket\n * of the upgrade.  This API is not finalized, and in particular\n * the final set of actions is yet to be decided. This is just an\n * idea for what we might want.\n */\nenum MHD_UpgradeAction\n{\n\n  /**\n   * Close the socket, the application is done with it.\n   *\n   * Takes no extra arguments.\n   */\n  MHD_UPGRADE_ACTION_CLOSE = 0,\n\n  /**\n   * Uncork the TCP write buffer (that is, tell the OS to transmit all\n   * bytes in the buffer now, and to not use TCP-CORKing).\n   *\n   * Takes no extra arguments.\n   *\n   * NOTE: it is unclear if we want to have this in the\n   * \"final\" API, this is just an idea right now.\n   */\n  MHD_UPGRADE_ACTION_CORK\n\n};\n\n\n/**\n * Handle given to the application to manage special\n * actions relating to MHD responses that \"upgrade\"\n * the HTTP protocol (i.e. to WebSockets).\n */\nstruct MHD_UpgradeResponseHandle;\n\n\n/**\n * This connection-specific callback is provided by MHD to\n * applications (unusual) during the #MHD_UpgradeHandler.\n * It allows applications to perform 'special' actions on\n * the underlying socket from the upgrade.\n *\n * @param urh the handle identifying the connection to perform\n *            the upgrade @a action on.\n * @param action which action should be performed\n * @param ... arguments to the action (depends on the action)\n * @return #MHD_NO on error, #MHD_YES on success\n */\n_MHD_EXTERN int\nMHD_upgrade_action (struct MHD_UpgradeResponseHandle *urh,\n                    enum MHD_UpgradeAction action,\n                    ...);\n\n\n/**\n * Function called after a protocol \"upgrade\" response was sent\n * successfully and the socket should now be controlled by some\n * protocol other than HTTP.\n *\n * Any data received on the socket will be made available in\n * 'data_in'.  The function should update 'data_in_size' to\n * reflect the number of bytes consumed from 'data_in' (the remaining\n * bytes will be made available in the next call to the handler).\n *\n * Any data that should be transmitted on the socket should be\n * stored in 'data_out'.  '*data_out_size' is initially set to\n * the available buffer space in 'data_out'.  It should be set to\n * the number of bytes stored in 'data_out' (which can be zero).\n *\n * The return value is a BITMASK that indicates how the function\n * intends to interact with the event loop.  It can request to be\n * notified for reading, writing, request to UNCORK the send buffer\n * (which MHD is allowed to ignore, if it is not possible to uncork on\n * the local platform), to wait for the 'external' select loop to\n * trigger another round.  It is also possible to specify \"no events\"\n * to terminate the connection; in this case, the\n * #MHD_RequestCompletedCallback will be called and all resources of\n * the connection will be released.\n *\n * Except when in 'thread-per-connection' mode, implementations\n * of this function should never block (as it will still be called\n * from within the main event loop).\n *\n * @param cls closure, whatever was given to #MHD_create_response_for_upgrade().\n * @param connection original HTTP connection handle,\n *                   giving the function a last chance\n *                   to inspect the original HTTP request\n * @param extra_in if we happened to have read bytes after the\n *                 HTTP header already (because the client sent\n *                 more than the HTTP header of the request before\n *                 we sent the upgrade response),\n *                 these are the extra bytes already read from @a sock\n *                 by MHD.  The application should treat these as if\n *                 it had read them from @a sock.\n * @param extra_in_size number of bytes in @a extra_in\n * @param sock socket to use for bi-directional communication\n *        with the client.  For HTTPS, this may not be a socket\n *        that is directly connected to the client and thus certain\n *        operations (TCP-specific setsockopt(), getsockopt(), etc.)\n *        may not work as expected (as the socket could be from a\n *        socketpair() or a TCP-loopback)\n * @param urh argument for #MHD_upgrade_action()s on this @a connection.\n *        Applications must eventually use this callback to perform the\n *        close() action on the @a sock.\n */\ntypedef void\n(*MHD_UpgradeHandler)(void *cls,\n                      struct MHD_Connection *connection,\n                      const char *extra_in,\n                      size_t extra_in_size,\n                      MHD_SOCKET sock,\n                      struct MHD_UpgradeResponseHandle *urh);\n\n\n/**\n * Create a response object that can be used for 101 UPGRADE\n * responses, for example to implement WebSockets.  After sending the\n * response, control over the data stream is given to the callback (which\n * can then, for example, start some bi-directional communication).\n * If the response is queued for multiple connections, the callback\n * will be called for each connection.  The callback\n * will ONLY be called after the response header was successfully passed\n * to the OS; if there are communication errors before, the usual MHD\n * connection error handling code will be performed.\n *\n * Setting the correct HTTP code (i.e. MHD_HTTP_SWITCHING_PROTOCOLS)\n * and setting correct HTTP headers for the upgrade must be done\n * manually (this way, it is possible to implement most existing\n * WebSocket versions using this API; in fact, this API might be useful\n * for any protocol switch, not just WebSockets).  Note that\n * draft-ietf-hybi-thewebsocketprotocol-00 cannot be implemented this\n * way as the header \"HTTP/1.1 101 WebSocket Protocol Handshake\"\n * cannot be generated; instead, MHD will always produce \"HTTP/1.1 101\n * Switching Protocols\" (if the response code 101 is used).\n *\n * As usual, the response object can be extended with header\n * information and then be used any number of times (as long as the\n * header information is not connection-specific).\n *\n * @param upgrade_handler function to call with the 'upgraded' socket\n * @param upgrade_handler_cls closure for @a upgrade_handler\n * @return NULL on error (i.e. invalid arguments, out of memory)\n */\n_MHD_EXTERN struct MHD_Response *\nMHD_create_response_for_upgrade (MHD_UpgradeHandler upgrade_handler,\n\t\t\t\t void *upgrade_handler_cls);\n#endif\n\n/**\n * Destroy a response object and associated resources.  Note that\n * libmicrohttpd may keep some of the resources around if the response\n * is still in the queue for some clients, so the memory may not\n * necessarily be freed immediatley.\n *\n * @param response response to destroy\n * @ingroup response\n */\n_MHD_EXTERN void\nMHD_destroy_response (struct MHD_Response *response);\n\n\n/**\n * Add a header line to the response.\n *\n * @param response response to add a header to\n * @param header the header to add\n * @param content value to add\n * @return #MHD_NO on error (i.e. invalid header or content format),\n *         or out of memory\n * @ingroup response\n */\n_MHD_EXTERN int\nMHD_add_response_header (struct MHD_Response *response,\n                         const char *header,\n\t\t\t const char *content);\n\n\n/**\n * Add a footer line to the response.\n *\n * @param response response to remove a header from\n * @param footer the footer to delete\n * @param content value to delete\n * @return #MHD_NO on error (i.e. invalid footer or content format).\n * @ingroup response\n */\n_MHD_EXTERN int\nMHD_add_response_footer (struct MHD_Response *response,\n                         const char *footer,\n\t\t\t const char *content);\n\n\n/**\n * Delete a header (or footer) line from the response.\n *\n * @param response response to remove a header from\n * @param header the header to delete\n * @param content value to delete\n * @return #MHD_NO on error (no such header known)\n * @ingroup response\n */\n_MHD_EXTERN int\nMHD_del_response_header (struct MHD_Response *response,\n                         const char *header,\n\t\t\t const char *content);\n\n\n/**\n * Get all of the headers (and footers) added to a response.\n *\n * @param response response to query\n * @param iterator callback to call on each header;\n *        maybe NULL (then just count headers)\n * @param iterator_cls extra argument to @a iterator\n * @return number of entries iterated over\n * @ingroup response\n */\n_MHD_EXTERN int\nMHD_get_response_headers (struct MHD_Response *response,\n                          MHD_KeyValueIterator iterator, void *iterator_cls);\n\n\n/**\n * Get a particular header (or footer) from the response.\n *\n * @param response response to query\n * @param key which header to get\n * @return NULL if header does not exist\n * @ingroup response\n */\n_MHD_EXTERN const char *\nMHD_get_response_header (struct MHD_Response *response,\n\t\t\t const char *key);\n\n\n/* ********************** PostProcessor functions ********************** */\n\n/**\n * Create a `struct MHD_PostProcessor`.\n *\n * A `struct MHD_PostProcessor` can be used to (incrementally) parse\n * the data portion of a POST request.  Note that some buggy browsers\n * fail to set the encoding type.  If you want to support those, you\n * may have to call #MHD_set_connection_value with the proper encoding\n * type before creating a post processor (if no supported encoding\n * type is set, this function will fail).\n *\n * @param connection the connection on which the POST is\n *        happening (used to determine the POST format)\n * @param buffer_size maximum number of bytes to use for\n *        internal buffering (used only for the parsing,\n *        specifically the parsing of the keys).  A\n *        tiny value (256-1024) should be sufficient.\n *        Do NOT use a value smaller than 256.  For good\n *        performance, use 32 or 64k (i.e. 65536).\n * @param iter iterator to be called with the parsed data,\n *        Must NOT be NULL.\n * @param iter_cls first argument to @a iter\n * @return NULL on error (out of memory, unsupported encoding),\n *         otherwise a PP handle\n * @ingroup request\n */\n_MHD_EXTERN struct MHD_PostProcessor *\nMHD_create_post_processor (struct MHD_Connection *connection,\n\t\t\t   size_t buffer_size,\n\t\t\t   MHD_PostDataIterator iter, void *iter_cls);\n\n\n/**\n * Parse and process POST data.  Call this function when POST data is\n * available (usually during an #MHD_AccessHandlerCallback) with the\n * \"upload_data\" and \"upload_data_size\".  Whenever possible, this will\n * then cause calls to the #MHD_PostDataIterator.\n *\n * @param pp the post processor\n * @param post_data @a post_data_len bytes of POST data\n * @param post_data_len length of @a post_data\n * @return #MHD_YES on success, #MHD_NO on error\n *         (out-of-memory, iterator aborted, parse error)\n * @ingroup request\n */\n_MHD_EXTERN int\nMHD_post_process (struct MHD_PostProcessor *pp,\n                  const char *post_data, size_t post_data_len);\n\n\n/**\n * Release PostProcessor resources.\n *\n * @param pp the PostProcessor to destroy\n * @return #MHD_YES if processing completed nicely,\n *         #MHD_NO if there were spurious characters / formatting\n *                problems; it is common to ignore the return\n *                value of this function\n * @ingroup request\n */\n_MHD_EXTERN int\nMHD_destroy_post_processor (struct MHD_PostProcessor *pp);\n\n\n/* ********************* Digest Authentication functions *************** */\n\n\n/**\n * Constant to indicate that the nonce of the provided\n * authentication code was wrong.\n * @ingroup authentication\n */\n#define MHD_INVALID_NONCE -1\n\n\n/**\n * Get the username from the authorization header sent by the client\n *\n * @param connection The MHD connection structure\n * @return NULL if no username could be found, a pointer\n * \t\t\tto the username if found\n * @ingroup authentication\n */\n_MHD_EXTERN char *\nMHD_digest_auth_get_username (struct MHD_Connection *connection);\n\n\n/**\n * Authenticates the authorization header sent by the client\n *\n * @param connection The MHD connection structure\n * @param realm The realm presented to the client\n * @param username The username needs to be authenticated\n * @param password The password used in the authentication\n * @param nonce_timeout The amount of time for a nonce to be\n * \t\t\tinvalid in seconds\n * @return #MHD_YES if authenticated, #MHD_NO if not,\n * \t\t\t#MHD_INVALID_NONCE if nonce is invalid\n * @ingroup authentication\n */\n_MHD_EXTERN int\nMHD_digest_auth_check (struct MHD_Connection *connection,\n\t\t       const char *realm,\n\t\t       const char *username,\n\t\t       const char *password,\n\t\t       unsigned int nonce_timeout);\n\n\n/**\n * Queues a response to request authentication from the client\n *\n * @param connection The MHD connection structure\n * @param realm The realm presented to the client\n * @param opaque string to user for opaque value\n * @param response reply to send; should contain the \"access denied\"\n *        body; note that this function will set the \"WWW Authenticate\"\n *        header and that the caller should not do this\n * @param signal_stale #MHD_YES if the nonce is invalid to add\n * \t\t\t'stale=true' to the authentication header\n * @return #MHD_YES on success, #MHD_NO otherwise\n * @ingroup authentication\n */\n_MHD_EXTERN int\nMHD_queue_auth_fail_response (struct MHD_Connection *connection,\n\t\t\t      const char *realm,\n\t\t\t      const char *opaque,\n\t\t\t      struct MHD_Response *response,\n\t\t\t      int signal_stale);\n\n\n/**\n * Get the username and password from the basic authorization header sent by the client\n *\n * @param connection The MHD connection structure\n * @param password a pointer for the password\n * @return NULL if no username could be found, a pointer\n * \t\t\tto the username if found\n * @ingroup authentication\n */\n_MHD_EXTERN char *\nMHD_basic_auth_get_username_password (struct MHD_Connection *connection,\n\t\t\t\t      char** password);\n\n\n/**\n * Queues a response to request basic authentication from the client\n * The given response object is expected to include the payload for\n * the response; the \"WWW-Authenticate\" header will be added and the\n * response queued with the 'UNAUTHORIZED' status code.\n *\n * @param connection The MHD connection structure\n * @param realm the realm presented to the client\n * @param response response object to modify and queue\n * @return #MHD_YES on success, #MHD_NO otherwise\n * @ingroup authentication\n */\n_MHD_EXTERN int\nMHD_queue_basic_auth_fail_response (struct MHD_Connection *connection,\n\t\t\t\t    const char *realm,\n\t\t\t\t    struct MHD_Response *response);\n\n/* ********************** generic query functions ********************** */\n\n\n/**\n * Obtain information about the given connection.\n *\n * @param connection what connection to get information about\n * @param info_type what information is desired?\n * @param ... depends on @a info_type\n * @return NULL if this information is not available\n *         (or if the @a info_type is unknown)\n * @ingroup specialized\n */\n_MHD_EXTERN const union MHD_ConnectionInfo *\nMHD_get_connection_info (struct MHD_Connection *connection,\n\t\t\t enum MHD_ConnectionInfoType info_type,\n\t\t\t ...);\n\n\n/**\n * MHD connection options.  Given to #MHD_set_connection_option to\n * set custom options for a particular connection.\n */\nenum MHD_CONNECTION_OPTION\n{\n\n  /**\n   * Set a custom timeout for the given connection.  Specified\n   * as the number of seconds, given as an `unsigned int`.  Use\n   * zero for no timeout.\n   */\n  MHD_CONNECTION_OPTION_TIMEOUT\n\n};\n\n\n/**\n * Set a custom option for the given connection, overriding defaults.\n *\n * @param connection connection to modify\n * @param option option to set\n * @param ... arguments to the option, depending on the option type\n * @return #MHD_YES on success, #MHD_NO if setting the option failed\n * @ingroup specialized\n */\n_MHD_EXTERN int\nMHD_set_connection_option (struct MHD_Connection *connection,\n\t\t\t   enum MHD_CONNECTION_OPTION option,\n\t\t\t   ...);\n\n\n/**\n * Information about an MHD daemon.\n */\nunion MHD_DaemonInfo\n{\n  /**\n   * Size of the key, no longer supported.\n   * @deprecated\n   */\n  size_t key_size;\n\n  /**\n   * Size of the mac key, no longer supported.\n   * @deprecated\n   */\n  size_t mac_key_size;\n\n  /**\n   * Listen socket file descriptor, for #MHD_DAEMON_INFO_EPOLL_FD_LINUX_ONLY\n   * and #MHD_DAEMON_INFO_LISTEN_FD.\n   */\n  MHD_socket listen_fd;\n\n  /**\n   * Number of active connections, for #MHD_DAEMON_INFO_CURRENT_CONNECTIONS.\n   */\n  unsigned int num_connections;\n};\n\n\n/**\n * Obtain information about the given daemon\n * (not fully implemented!).\n *\n * @param daemon what daemon to get information about\n * @param info_type what information is desired?\n * @param ... depends on @a info_type\n * @return NULL if this information is not available\n *         (or if the @a info_type is unknown)\n * @ingroup specialized\n */\n_MHD_EXTERN const union MHD_DaemonInfo *\nMHD_get_daemon_info (struct MHD_Daemon *daemon,\n\t\t     enum MHD_DaemonInfoType info_type,\n\t\t     ...);\n\n\n/**\n * Obtain the version of this library\n *\n * @return static version string, e.g. \"0.9.9\"\n * @ingroup specialized\n */\n_MHD_EXTERN const char*\nMHD_get_version (void);\n\n\n/**\n * Types of information about MHD features,\n * used by #MHD_is_feature_supported().\n */\nenum MHD_FEATURE\n{\n  /**\n   * Get whether messages are supported. If supported then in debug\n   * mode messages can be printed to stderr or to external logger.\n   */\n  MHD_FEATURE_MESSGES = 1,\n\n  /**\n   * Get whether HTTPS is supported.  If supported then flag\n   * #MHD_USE_SSL and options #MHD_OPTION_HTTPS_MEM_KEY,\n   * #MHD_OPTION_HTTPS_MEM_CERT, #MHD_OPTION_HTTPS_MEM_TRUST,\n   * #MHD_OPTION_HTTPS_MEM_DHPARAMS, #MHD_OPTION_HTTPS_CRED_TYPE,\n   * #MHD_OPTION_HTTPS_PRIORITIES can be used.\n   */\n  MHD_FEATURE_SSL = 2,\n\n  /**\n   * Get whether option #MHD_OPTION_HTTPS_CERT_CALLBACK is\n   * supported.\n   */\n  MHD_FEATURE_HTTPS_CERT_CALLBACK = 3,\n\n  /**\n   * Get whether IPv6 is supported. If supported then flag\n   * #MHD_USE_IPv6 can be used.\n   */\n  MHD_FEATURE_IPv6 = 4,\n\n  /**\n   * Get whether IPv6 without IPv4 is supported. If not supported\n   * then IPv4 is always enabled in IPv6 sockets and\n   * flag #MHD_USE_DUAL_STACK if always used when #MHD_USE_IPv6 is\n   * specified.\n   */\n  MHD_FEATURE_IPv6_ONLY = 5,\n\n  /**\n   * Get whether `poll()` is supported. If supported then flag\n   * #MHD_USE_POLL can be used.\n   */\n  MHD_FEATURE_POLL = 6,\n\n  /**\n   * Get whether `epoll()` is supported. If supported then Flags\n   * #MHD_USE_EPOLL and\n   * #MHD_USE_EPOLL_INTERNALLY can be used.\n   */\n  MHD_FEATURE_EPOLL = 7,\n\n  /**\n   * Get whether shutdown on listen socket to signal other\n   * threads is supported. If not supported flag\n   * #MHD_USE_PIPE_FOR_SHUTDOWN is automatically forced.\n   */\n  MHD_FEATURE_SHUTDOWN_LISTEN_SOCKET = 8,\n\n  /**\n   * Get whether socketpair is used internally instead of pipe to\n   * signal other threads.\n   */\n  MHD_FEATURE_SOCKETPAIR = 9,\n\n  /**\n   * Get whether TCP Fast Open is supported. If supported then\n   * flag #MHD_USE_TCP_FASTOPEN and option\n   * #MHD_OPTION_TCP_FASTOPEN_QUEUE_SIZE can be used.\n   */\n  MHD_FEATURE_TCP_FASTOPEN = 10,\n\n  /**\n   * Get whether HTTP Basic authorization is supported. If supported\n   * then functions #MHD_basic_auth_get_username_password and\n   * #MHD_queue_basic_auth_fail_response can be used.\n   */\n  MHD_FEATURE_BASIC_AUTH = 11,\n\n  /**\n   * Get whether HTTP Digest authorization is supported. If\n   * supported then options #MHD_OPTION_DIGEST_AUTH_RANDOM,\n   * #MHD_OPTION_NONCE_NC_SIZE and\n   * #MHD_digest_auth_check() can be used.\n   */\n  MHD_FEATURE_DIGEST_AUTH = 12,\n\n  /**\n   * Get whether postprocessor is supported. If supported then\n   * functions #MHD_create_post_processor(), #MHD_post_process() and\n   * #MHD_destroy_post_processor() can\n   * be used.\n   */\n  MHD_FEATURE_POSTPROCESSOR = 13,\n\n  /**\n  * Get whether password encrypted private key for HTTPS daemon is\n  * supported. If supported then option\n  * ::MHD_OPTION_HTTPS_KEY_PASSWORD can be used.\n  */\n  MHD_FEATURE_HTTPS_KEY_PASSWORD = 14,\n\n  /**\n   * Get whether reading files beyond 2 GiB boundary is supported.\n   * If supported then #MHD_create_response_from_fd(),\n   * #MHD_create_response_from_fd64 #MHD_create_response_from_fd_at_offset()\n   * and #MHD_create_response_from_fd_at_offset64() can be used with sizes and\n   * offsets larger than 2 GiB. If not supported value of size+offset is\n   * limited to 2 GiB.\n   */\n  MHD_FEATURE_LARGE_FILE = 15,\n\n  /**\n   * Get whether MHD set names on generated threads.\n   */\n  MHD_THREAD_NAMES = 16\n};\n\n\n/**\n * Get information about supported MHD features.\n * Indicate that MHD was compiled with or without support for\n * particular feature. Some features require additional support\n * by kernel. Kernel support is not checked by this function.\n *\n * @param feature type of requested information\n * @return #MHD_YES if feature is supported by MHD, #MHD_NO if\n * feature is not supported or feature is unknown.\n * @ingroup specialized\n */\n_MHD_EXTERN int\nMHD_is_feature_supported (enum MHD_FEATURE feature);\n\n\n#if 0                           /* keep Emacsens' auto-indent happy */\n{\n#endif\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "minethd.cpp",
    "content": "/*\n  * This program is free software: you can redistribute it and/or modify\n  * it under the terms of the GNU General Public License as published by\n  * the Free Software Foundation, either version 3 of the License, or\n  * any later version.\n  *\n  * This program is distributed in the hope that it will be useful,\n  * but WITHOUT ANY WARRANTY; without even the implied warranty of\n  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n  * GNU General Public License for more details.\n  *\n  * You should have received a copy of the GNU General Public License\n  * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n  *\n  * Additional permission under GNU GPL version 3 section 7\n  *\n  * If you modify this Program, or any covered work, by linking or combining\n  * it with OpenSSL (or a modified version of that library), containing parts\n  * covered by the terms of OpenSSL License and SSLeay License, the licensors\n  * of this Program grant you additional permission to convey the resulting work.\n  *\n  */\n\n#include <assert.h>\n#include <cmath>\n#include <chrono>\n#include <thread>\n#include \"console.h\"\n\n#ifdef _WIN32\n#include <windows.h>\n\nvoid thd_setaffinity(std::thread::native_handle_type h, uint64_t cpu_id)\n{\n\tSetThreadAffinityMask(h, 1ULL << cpu_id);\n}\n\n#else\n#include <pthread.h>\n\n#if defined(__APPLE__)\n#include <mach/thread_policy.h>\n#include <mach/thread_act.h>\n#define SYSCTL_CORE_COUNT   \"machdep.cpu.core_count\"\n#endif\n\nvoid thd_setaffinity(std::thread::native_handle_type h, uint64_t cpu_id)\n{\n#if defined(__APPLE__)\n\tthread_port_t mach_thread;\n\tthread_affinity_policy_data_t policy = { cpu_id };\n\tmach_thread = pthread_mach_thread_np(h);\n\tthread_policy_set(mach_thread, THREAD_AFFINITY_POLICY, (thread_policy_t)&policy, 1);\n#else\n\tcpu_set_t mn;\n\tCPU_ZERO(&mn);\n\tCPU_SET(cpu_id, &mn);\n\tpthread_setaffinity_np(h, sizeof(cpu_set_t), &mn);\n#endif\n}\n#endif // _WIN32\n\n#include \"executor.h\"\n#include \"minethd.h\"\n#include \"jconf.h\"\n#include \"crypto/cryptonight.h\"\n\ntelemetry::telemetry(size_t iThd)\n{\n\tppHashCounts = new uint64_t*[iThd];\n\tppTimestamps = new uint64_t*[iThd];\n\tiBucketTop = new uint32_t[iThd];\n\n\tfor (size_t i = 0; i < iThd; i++)\n\t{\n\t\tppHashCounts[i] = new uint64_t[iBucketSize];\n\t\tppTimestamps[i] = new uint64_t[iBucketSize];\n\t\tiBucketTop[i] = 0;\n\t\tmemset(ppHashCounts[0], 0, sizeof(uint64_t) * iBucketSize);\n\t\tmemset(ppTimestamps[0], 0, sizeof(uint64_t) * iBucketSize);\n\t}\n}\n\ndouble telemetry::calc_telemetry_data(size_t iLastMilisec, size_t iThread)\n{\n\tusing namespace std::chrono;\n\tuint64_t iTimeNow = time_point_cast<milliseconds>(high_resolution_clock::now()).time_since_epoch().count();\n\n\tuint64_t iEarliestHashCnt = 0;\n\tuint64_t iEarliestStamp = 0;\n\tuint64_t iLastestStamp = 0;\n\tuint64_t iLastestHashCnt = 0;\n\tbool bHaveFullSet = false;\n\n\t//Start at 1, buckettop points to next empty\n\tfor (size_t i = 1; i < iBucketSize; i++)\n\t{\n\t\tsize_t idx = (iBucketTop[iThread] - i) & iBucketMask; //overflow expected here\n\n\t\tif (ppTimestamps[iThread][idx] == 0)\n\t\t\tbreak; //That means we don't have the data yet\n\n\t\tif (iLastestStamp == 0)\n\t\t{\n\t\t\tiLastestStamp = ppTimestamps[iThread][idx];\n\t\t\tiLastestHashCnt = ppHashCounts[iThread][idx];\n\t\t}\n\n\t\tif (iTimeNow - ppTimestamps[iThread][idx] > iLastMilisec)\n\t\t{\n\t\t\tbHaveFullSet = true;\n\t\t\tbreak; //We are out of the requested time period\n\t\t}\n\n\t\tiEarliestStamp = ppTimestamps[iThread][idx];\n\t\tiEarliestHashCnt = ppHashCounts[iThread][idx];\n\t}\n\n\tif (!bHaveFullSet || iEarliestStamp == 0 || iLastestStamp == 0)\n\t\treturn nan(\"\");\n\n\tdouble fHashes, fTime;\n\tfHashes = iLastestHashCnt - iEarliestHashCnt;\n\tfTime = iLastestStamp - iEarliestStamp;\n\tfTime /= 1000.0;\n\n\treturn fHashes / fTime;\n}\n\nvoid telemetry::push_perf_value(size_t iThd, uint64_t iHashCount, uint64_t iTimestamp)\n{\n\tsize_t iTop = iBucketTop[iThd];\n\tppHashCounts[iThd][iTop] = iHashCount;\n\tppTimestamps[iThd][iTop] = iTimestamp;\n\n\tiBucketTop[iThd] = (iTop + 1) & iBucketMask;\n}\n\nminethd::minethd(miner_work& pWork, size_t iNo, GpuContext* ctx)\n{\n\toWork = pWork;\n\tbQuit = 0;\n\tiThreadNo = (uint8_t)iNo;\n\tiJobNo = 0;\n\tiHashCount = 0;\n\tiTimestamp = 0;\n\tpGpuCtx = ctx;\n\n\toWorkThd = std::thread(&minethd::work_main, this);\n}\n\nbool minethd::init_gpus()\n{\n\tsize_t i, n = jconf::inst()->GetThreadCount();\n\n\tprinter::inst()->print_msg(L1, \"Compiling code and initializing GPUs. This will take a while...\");\n\tvGpuData.resize(n);\n\n\tjconf::thd_cfg cfg;\n\tfor(i = 0; i < n; i++)\n\t{\n\t\tjconf::inst()->GetThreadConfig(i, cfg);\n\t\tvGpuData[i].deviceIdx = cfg.index;\n\t\tvGpuData[i].rawIntensity = cfg.intensity;\n\t\tvGpuData[i].workSize = cfg.w_size;\n\t}\n\n\treturn InitOpenCL(vGpuData.data(), n, jconf::inst()->GetPlatformIdx()) == ERR_SUCCESS;\n}\n\nstd::atomic<uint64_t> minethd::iGlobalJobNo;\nstd::atomic<uint64_t> minethd::iConsumeCnt; //Threads get jobs as they are initialized\nminethd::miner_work minethd::oGlobalWork;\nuint64_t minethd::iThreadCount = 0;\nstd::vector<GpuContext> minethd::vGpuData;\n\nstd::vector<minethd*>* minethd::thread_starter(miner_work& pWork)\n{\n\tiGlobalJobNo = 0;\n\tiConsumeCnt = 0;\n\tstd::vector<minethd*>* pvThreads = new std::vector<minethd*>;\n\n\tsize_t i, n = jconf::inst()->GetThreadCount();\n\tpvThreads->reserve(n);\n\n\tjconf::thd_cfg cfg;\n\tfor (i = 0; i < n; i++)\n\t{\n\t\tjconf::inst()->GetThreadConfig(i, cfg);\n\t\tminethd* thd = new minethd(pWork, i, &vGpuData[i]);\n\n\t\tif(cfg.cpu_aff >= 0)\n\t\t{\n#if defined(__APPLE__)\n\t\t\tprinter::inst()->print_msg(L1, \"WARNING on MacOS thread affinity is only advisory.\");\n#endif\n\t\t\tthd_setaffinity(thd->oWorkThd.native_handle(), cfg.cpu_aff);\n\t\t}\n\n\t\tpvThreads->push_back(thd);\n\t\tif(cfg.cpu_aff >= 0)\n\t\t\tprinter::inst()->print_msg(L1, \"Starting GPU thread, affinity: %d.\", (int)cfg.cpu_aff);\n\t\telse\n\t\t\tprinter::inst()->print_msg(L1, \"Starting GPU thread, no affinity.\");\n\t}\n\n\tiThreadCount = n;\n\treturn pvThreads;\n}\n\nvoid minethd::switch_work(miner_work& pWork)\n{\n\t// iConsumeCnt is a basic lock-like polling mechanism just in case we happen to push work\n\t// faster than threads can consume them. This should never happen in real life.\n\t// Pool cant physically send jobs faster than every 250ms or so due to net latency.\n\n\twhile (iConsumeCnt.load(std::memory_order_seq_cst) < iThreadCount)\n\t\tstd::this_thread::sleep_for(std::chrono::milliseconds(100));\n\n\toGlobalWork = pWork;\n\tiConsumeCnt.store(0, std::memory_order_seq_cst);\n\tiGlobalJobNo++;\n}\n\nvoid minethd::consume_work()\n{\n\tmemcpy(&oWork, &oGlobalWork, sizeof(miner_work));\n\tiJobNo++;\n\tiConsumeCnt++;\n\n\tif(!oWork.bStall)\n\t{\n\t\tpGpuCtx->Nonce = calc_start_nonce(oWork.iResumeCnt);\n\t\tXMRSetJob(pGpuCtx, oWork.bWorkBlob, oWork.iWorkSize, oWork.iTarget);\n\t}\n}\n\nvoid minethd::work_main()\n{\n\tuint64_t iCount = 0;\n\tiConsumeCnt++;\n\twhile (bQuit == 0)\n\t{\n\t\tif (oWork.bStall)\n\t\t{\n\t\t\t/*  We are stalled here because the executor didn't find a job for us yet,\n\t\t\t    either because of network latency, or a socket problem. Since we are\n\t\t\t    raison d'etre of this software it us sensible to just wait until we have something*/\n\n\t\t\twhile (iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo)\n\t\t\t\tstd::this_thread::sleep_for(std::chrono::milliseconds(100));\n\n\t\t\tconsume_work();\n\t\t\tcontinue;\n\t\t}\n\n\t\tassert(sizeof(job_result::sJobID) == sizeof(pool_job::sJobID));\n\n\t\twhile(iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo)\n\t\t{\n\t\t\tcl_uint results[0x100] = { 0 };\n\n\t\t\tXMRRunJob(pGpuCtx, results);\n\n\t\t\tfor(size_t i = 0; i < results[0xFF]; i++)\n\t\t\t{\n\t\t\t\texecutor::inst()->push_event(ex_event(job_result(oWork.sJobID, oWork.bWorkBlob,\n\t\t\t\t\toWork.iWorkSize, oWork.iTarget, results[i]), oWork.iPoolId));\n\t\t\t}\n\n\t\t\tiCount += pGpuCtx->rawIntensity;\n\t\t\tusing namespace std::chrono;\n\t\t\tuint64_t iStamp = time_point_cast<milliseconds>(high_resolution_clock::now()).time_since_epoch().count();\n\t\t\tiHashCount.store(iCount, std::memory_order_relaxed);\n\t\t\tiTimestamp.store(iStamp, std::memory_order_relaxed);\n\t\t\tstd::this_thread::yield();\n\t\t}\n\n\t\tconsume_work();\n\t}\n}\n"
  },
  {
    "path": "minethd.h",
    "content": "#pragma once\n#include <thread>\n#include <atomic>\n\n#include \"amd_gpu/gpu.h\"\n\nclass telemetry\n{\npublic:\n\ttelemetry(size_t iThd);\n\tvoid push_perf_value(size_t iThd, uint64_t iHashCount, uint64_t iTimestamp);\n\tdouble calc_telemetry_data(size_t iLastMilisec, size_t iThread);\n\nprivate:\n\tconstexpr static size_t iBucketSize = 2 << 11; //Power of 2 to simplify calculations\n\tconstexpr static size_t iBucketMask = iBucketSize - 1;\n\tuint32_t* iBucketTop;\n\tuint64_t** ppHashCounts;\n\tuint64_t** ppTimestamps;\n};\n\nclass minethd\n{\npublic:\n\tstruct miner_work\n\t{\n\t\tchar        sJobID[64];\n\t\tuint8_t     bWorkBlob[88];\n\t\tuint32_t    iWorkSize;\n\t\tuint32_t    iResumeCnt;\n\t\tuint32_t    iTarget;\n\t\tbool        bStall;\n\t\tsize_t      iPoolId;\n\n\t\tminer_work() : iWorkSize(0), bStall(true), iPoolId(0) { }\n\n\t\tminer_work(const char* sJobID, const uint8_t* bWork, uint32_t iWorkSize, uint32_t iResumeCnt,\n\t\t\tuint64_t iTarget, size_t iPoolId) : iWorkSize(iWorkSize), iResumeCnt(iResumeCnt),\n\t\t\tiTarget(iTarget), bStall(false), iPoolId(iPoolId)\n\t\t{\n\t\t\tassert(iWorkSize <= sizeof(bWorkBlob));\n\t\t\tmemcpy(this->sJobID, sJobID, sizeof(miner_work::sJobID));\n\t\t\tmemcpy(this->bWorkBlob, bWork, iWorkSize);\n\t\t}\n\n\t\tminer_work(miner_work const&) = delete;\n\n\t\tminer_work& operator=(miner_work const& from)\n\t\t{\n\t\t\tassert(this != &from);\n\n\t\t\tiWorkSize = from.iWorkSize;\n\t\t\tiResumeCnt = from.iResumeCnt;\n\t\t\tiTarget = from.iTarget;\n\t\t\tbStall = from.bStall;\n\t\t\tiPoolId = from.iPoolId;\n\n\t\t\tassert(iWorkSize <= sizeof(bWorkBlob));\n\t\t\tmemcpy(sJobID, from.sJobID, sizeof(sJobID));\n\t\t\tmemcpy(bWorkBlob, from.bWorkBlob, iWorkSize);\n\n\t\t\treturn *this;\n\t\t}\n\n\t\tminer_work(miner_work&& from) : iWorkSize(from.iWorkSize), iTarget(from.iTarget),\n\t\t\tbStall(from.bStall), iPoolId(from.iPoolId)\n\t\t{\n\t\t\tassert(iWorkSize <= sizeof(bWorkBlob));\n\t\t\tmemcpy(sJobID, from.sJobID, sizeof(sJobID));\n\t\t\tmemcpy(bWorkBlob, from.bWorkBlob, iWorkSize);\n\t\t}\n\n\t\tminer_work& operator=(miner_work&& from)\n\t\t{\n\t\t\tassert(this != &from);\n\n\t\t\tiWorkSize = from.iWorkSize;\n\t\t\tiResumeCnt = from.iResumeCnt;\n\t\t\tiTarget = from.iTarget;\n\t\t\tbStall = from.bStall;\n\t\t\tiPoolId = from.iPoolId;\n\n\t\t\tassert(iWorkSize <= sizeof(bWorkBlob));\n\t\t\tmemcpy(sJobID, from.sJobID, sizeof(sJobID));\n\t\t\tmemcpy(bWorkBlob, from.bWorkBlob, iWorkSize);\n\n\t\t\treturn *this;\n\t\t}\n\t};\n\n\tstatic void switch_work(miner_work& pWork);\n\tstatic std::vector<minethd*>* thread_starter(miner_work& pWork);\n\tstatic bool init_gpus();\n\n\tstd::atomic<uint64_t> iHashCount;\n\tstd::atomic<uint64_t> iTimestamp;\n\nprivate:\n\tminethd(miner_work& pWork, size_t iNo, GpuContext* ctx);\n\n\t// We use the top 8 bits of the nonce for thread and resume\n\t// This allows us to resume up to 64 threads 4 times before\n\t// we get nonce collisions\n\t// Bottom 24 bits allow for an hour of work at 4000 H/s\n\tinline uint32_t calc_start_nonce(uint32_t resume)\n\t\t{ return (resume * iThreadCount + iThreadNo) << 24; }\n\n\tvoid work_main();\n\tvoid double_work_main();\n\tvoid consume_work();\n\n\tstatic std::atomic<uint64_t> iGlobalJobNo;\n\tstatic std::atomic<uint64_t> iConsumeCnt;\n\tstatic uint64_t iThreadCount;\n\tuint64_t iJobNo;\n\n\tstatic miner_work oGlobalWork;\n\tminer_work oWork;\n\n\tstd::thread oWorkThd;\n\tuint8_t iThreadNo;\n\n\tbool bQuit;\n\tbool bNoPrefetch;\n\n\t//Mutable ptr to vector below, different for each thread\n\tGpuContext* pGpuCtx;\n\n\t// WARNING - this vector (but not its contents) must be immutable\n\t// once the threads are started\n\tstatic std::vector<GpuContext> vGpuData;\n};\n\n"
  },
  {
    "path": "msgstruct.h",
    "content": "#pragma once\n#include <string>\n#include <string.h>\n#include <assert.h>\n\n// Structures that we use to pass info between threads constructors are here just to make\n// the stack allocation take up less space, heap is a shared resouce that needs locks too of course\n\nstruct pool_job\n{\n\tchar\t\tsJobID[64];\n\tuint8_t\t\tbWorkBlob[88];\n\tuint32_t\tiTarget;\n\tuint32_t\tiWorkLen;\n\tuint32_t\tiResumeCnt;\n\n\tpool_job() : iWorkLen(0), iResumeCnt(0) {}\n\tpool_job(const char* sJobID, uint64_t iTarget, const uint8_t* bWorkBlob, uint32_t iWorkLen) :\n\t\tiTarget(iTarget), iWorkLen(iWorkLen), iResumeCnt(0)\n\t{\n\t\tassert(iWorkLen <= sizeof(pool_job::bWorkBlob));\n\t\tmemcpy(this->sJobID, sJobID, sizeof(pool_job::sJobID));\n\t\tmemcpy(this->bWorkBlob, bWorkBlob, iWorkLen);\n\t}\n};\n\nstruct job_result\n{\n\tuint8_t\t\tbResult[32];\n\tchar\t\tsJobID[64];\n\tuint8_t\t\tbWorkBlob[88];\n\tuint32_t\tiTarget;\n\tuint32_t\tiWorkLen;\n\tuint32_t\tiNonce;\n\n\tjob_result() {}\n\tjob_result(const char* sJobID, uint8_t* bWorkBlob, uint32_t iWorkLen, uint32_t iTarget, uint32_t iNonce) :\n\t\tiTarget(iTarget), iWorkLen(iWorkLen), iNonce(iNonce)\n\t{\n\t\tassert(iWorkLen <= sizeof(job_result::bWorkBlob));\n\n\t\tmemcpy(this->sJobID, sJobID, sizeof(job_result::sJobID));\n\t\tmemcpy(this->bWorkBlob, bWorkBlob, iWorkLen);\n\t\tmemset(this->bResult, 0, sizeof(job_result::bResult));\n\t}\n};\n\nenum ex_event_name { EV_INVALID_VAL, EV_SOCK_READY, EV_SOCK_ERROR,\n\tEV_POOL_HAVE_JOB, EV_MINER_HAVE_RESULT, EV_PERF_TICK, EV_RECONNECT,\n\tEV_SWITCH_POOL, EV_DEV_POOL_EXIT, EV_USR_HASHRATE, EV_USR_RESULTS, EV_USR_CONNSTAT,\n\tEV_HASHRATE_LOOP, EV_HTML_HASHRATE, EV_HTML_RESULTS, EV_HTML_CONNSTAT };\n\n/*\n   This is how I learned to stop worrying and love c++11 =).\n   Ghosts of endless heap allocations have finally been exorcised. Thanks\n   to the nifty magic of move semantics, string will only be allocated\n   once on the heap. Considering that it makes a jorney across stack,\n   heap alloced queue, to another stack before being finally processed\n   I think it is kind of nifty, don't you?\n   Also note that for non-arg events we only copy two qwords\n*/\n\nstruct ex_event\n{\n\tex_event_name iName;\n\tsize_t iPoolId;\n\n\tunion\n\t{\n\t\tpool_job oPoolJob;\n\t\tjob_result oJobResult;\n\t\tstd::string sSocketError;\n\t};\n\n\tex_event() { iName = EV_INVALID_VAL; iPoolId = 0;}\n\tex_event(std::string&& err, size_t id) : iName(EV_SOCK_ERROR), iPoolId(id), sSocketError(std::move(err)) { }\n\tex_event(job_result dat, size_t id) : iName(EV_MINER_HAVE_RESULT), iPoolId(id), oJobResult(dat) {}\n\tex_event(pool_job dat, size_t id) : iName(EV_POOL_HAVE_JOB), iPoolId(id), oPoolJob(dat) {}\n\tex_event(ex_event_name ev, size_t id = 0) : iName(ev), iPoolId(id) {}\n\n\t// Delete the copy operators to make sure we are moving only what is needed\n\tex_event(ex_event const&) = delete;\n\tex_event& operator=(ex_event const&) = delete;\n\n\tex_event(ex_event&& from)\n\t{\n\t\tiName = from.iName;\n\t\tiPoolId = from.iPoolId;\n\n\t\tswitch(iName)\n\t\t{\n\t\tcase EV_SOCK_ERROR:\n\t\t\tnew (&sSocketError) std::string(std::move(from.sSocketError));\n\t\t\tbreak;\n\t\tcase EV_MINER_HAVE_RESULT:\n\t\t\toJobResult = from.oJobResult;\n\t\t\tbreak;\n\t\tcase EV_POOL_HAVE_JOB:\n\t\t\toPoolJob = from.oPoolJob;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tex_event& operator=(ex_event&& from)\n\t{\n\t\tassert(this != &from);\n\n\t\tif(iName == EV_SOCK_ERROR)\n\t\t\tsSocketError.~basic_string();\n\n\t\tiName = from.iName;\n\t\tiPoolId = from.iPoolId;\n\n\t\tswitch(iName)\n\t\t{\n\t\tcase EV_SOCK_ERROR:\n\t\t\tnew (&sSocketError) std::string();\n\t\t\tsSocketError = std::move(from.sSocketError);\n\t\t\tbreak;\n\t\tcase EV_MINER_HAVE_RESULT:\n\t\t\toJobResult = from.oJobResult;\n\t\t\tbreak;\n\t\tcase EV_POOL_HAVE_JOB:\n\t\t\toPoolJob = from.oPoolJob;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\n\t\treturn *this;\n\t}\n\n\t~ex_event()\n\t{\n\t\tif(iName == EV_SOCK_ERROR)\n\t\t\tsSocketError.~basic_string();\n\t}\n};\n"
  },
  {
    "path": "opencl/blake256.cl",
    "content": "/*\n* blake256 kernel implementation.\n*\n* ==========================(LICENSE BEGIN)============================\n* Copyright (c) 2014 djm34\n* Copyright (c) 2014 tpruvot\n* Permission is hereby granted, free of charge, to any person obtaining\n* a copy of this software and associated documentation files (the\n* \"Software\"), to deal in the Software without restriction, including\n* without limitation the rights to use, copy, modify, merge, publish,\n* distribute, sublicense, and/or sell copies of the Software, and to\n* permit persons to whom the Software is furnished to do so, subject to\n* the following conditions:\n*\n* The above copyright notice and this permission notice shall be\n* included in all copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n*\n* ===========================(LICENSE END)=============================\n*\n* @author   djm34\n*/\n__constant static const int sigma[16][16] = {\n\t\t{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },\n\t\t{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },\n\t\t{ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },\n\t\t{ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },\n\t\t{ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },\n\t\t{ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },\n\t\t{ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 },\n\t\t{ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },\n\t\t{ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },\n\t\t{ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 },\n\t\t{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },\n\t\t{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },\n\t\t{ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },\n\t\t{ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },\n\t\t{ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },\n\t\t{ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 }\n};\n\n\n__constant static const sph_u32  c_IV256[8] = {\n\t0x6A09E667, 0xBB67AE85,\n\t0x3C6EF372, 0xA54FF53A,\n\t0x510E527F, 0x9B05688C,\n\t0x1F83D9AB, 0x5BE0CD19\n};\n\n/* Second part (64-80) msg never change, store it */\n__constant static const sph_u32  c_Padding[16] = {\n\t0, 0, 0, 0,\n\t0x80000000, 0, 0, 0,\n\t0, 0, 0, 0,\n\t0, 1, 0, 640,\n};\n__constant static const sph_u32  c_u256[16] = {\n\t0x243F6A88, 0x85A308D3,\n\t0x13198A2E, 0x03707344,\n\t0xA4093822, 0x299F31D0,\n\t0x082EFA98, 0xEC4E6C89,\n\t0x452821E6, 0x38D01377,\n\t0xBE5466CF, 0x34E90C6C,\n\t0xC0AC29B7, 0xC97C50DD,\n\t0x3F84D5B5, 0xB5470917\n};\n\n#define GS(a,b,c,d,x) { \\\n\tconst sph_u32 idx1 = sigma[r][x]; \\\n\tconst sph_u32 idx2 = sigma[r][x+1]; \\\n\tv[a] += (m[idx1] ^ c_u256[idx2]) + v[b]; \\\n\tv[d] ^= v[a]; \\\n    v[d] = rotate(v[d], 16U); \\\n\tv[c] += v[d]; \\\n    v[b] ^= v[c]; \\\n\tv[b] = rotate(v[b], 20U); \\\n\\\n\tv[a] += (m[idx2] ^ c_u256[idx1]) + v[b]; \\\n    v[d] ^= v[a]; \\\n\tv[d] = rotate(v[d], 24U); \\\n\tv[c] += v[d]; \\\n    v[b] ^= v[c]; \\\n\tv[b] = rotate(v[b], 25U); \\\n}\n\n\n\n\n\n"
  },
  {
    "path": "opencl/cryptonight.cl",
    "content": "/*\n  * This program is free software: you can redistribute it and/or modify\n  * it under the terms of the GNU General Public License as published by\n  * the Free Software Foundation, either version 3 of the License, or\n  * any later version.\n  *\n  * This program is distributed in the hope that it will be useful,\n  * but WITHOUT ANY WARRANTY; without even the implied warranty of\n  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n  * GNU General Public License for more details.\n  *\n  * You should have received a copy of the GNU General Public License\n  * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n  */\n\n#pragma OPENCL EXTENSION cl_amd_media_ops2 : enable\n\n#include \"opencl/wolf-aes.cl\"\n#include \"opencl/wolf-skein.cl\"\n#include \"opencl/jh.cl\"\n#include \"opencl/blake256.cl\"\n#include \"opencl/groestl256.cl\"\n\nstatic const __constant ulong keccakf_rndc[24] = \n{\n    0x0000000000000001, 0x0000000000008082, 0x800000000000808a,\n    0x8000000080008000, 0x000000000000808b, 0x0000000080000001,\n    0x8000000080008081, 0x8000000000008009, 0x000000000000008a,\n    0x0000000000000088, 0x0000000080008009, 0x000000008000000a,\n    0x000000008000808b, 0x800000000000008b, 0x8000000000008089,\n    0x8000000000008003, 0x8000000000008002, 0x8000000000000080, \n    0x000000000000800a, 0x800000008000000a, 0x8000000080008081,\n    0x8000000000008080, 0x0000000080000001, 0x8000000080008008\n};\n\nstatic const __constant uchar sbox[256] = \n{\n\t0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,\n\t0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,\n\t0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,\n\t0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,\n\t0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,\n\t0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,\n\t0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,\n\t0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,\n\t0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,\n\t0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,\n\t0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,\n\t0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,\n\t0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,\n\t0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,\n\t0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,\n\t0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16\n};\n\n\nvoid keccakf1600(ulong *s)\n{\n    for(int i = 0; i < 24; ++i) \n    {\n\t\tulong bc[5], tmp1, tmp2;\n        bc[0] = s[0] ^ s[5] ^ s[10] ^ s[15] ^ s[20] ^ rotate(s[2] ^ s[7] ^ s[12] ^ s[17] ^ s[22], 1UL);\n        bc[1] = s[1] ^ s[6] ^ s[11] ^ s[16] ^ s[21] ^ rotate(s[3] ^ s[8] ^ s[13] ^ s[18] ^ s[23], 1UL);\n        bc[2] = s[2] ^ s[7] ^ s[12] ^ s[17] ^ s[22] ^ rotate(s[4] ^ s[9] ^ s[14] ^ s[19] ^ s[24], 1UL);\n        bc[3] = s[3] ^ s[8] ^ s[13] ^ s[18] ^ s[23] ^ rotate(s[0] ^ s[5] ^ s[10] ^ s[15] ^ s[20], 1UL);\n        bc[4] = s[4] ^ s[9] ^ s[14] ^ s[19] ^ s[24] ^ rotate(s[1] ^ s[6] ^ s[11] ^ s[16] ^ s[21], 1UL);\n        \n        tmp1 = s[1] ^ bc[0];\n        \n        s[0] ^= bc[4];\n        s[1] = rotate(s[6] ^ bc[0], 44UL);\n        s[6] = rotate(s[9] ^ bc[3], 20UL);\n        s[9] = rotate(s[22] ^ bc[1], 61UL);\n        s[22] = rotate(s[14] ^ bc[3], 39UL);\n        s[14] = rotate(s[20] ^ bc[4], 18UL);\n        s[20] = rotate(s[2] ^ bc[1], 62UL);\n        s[2] = rotate(s[12] ^ bc[1], 43UL);\n        s[12] = rotate(s[13] ^ bc[2], 25UL);\n        s[13] = rotate(s[19] ^ bc[3], 8UL);\n        s[19] = rotate(s[23] ^ bc[2], 56UL);\n        s[23] = rotate(s[15] ^ bc[4], 41UL);\n        s[15] = rotate(s[4] ^ bc[3], 27UL);\n        s[4] = rotate(s[24] ^ bc[3], 14UL);\n        s[24] = rotate(s[21] ^ bc[0], 2UL);\n        s[21] = rotate(s[8] ^ bc[2], 55UL);\n        s[8] = rotate(s[16] ^ bc[0], 35UL);\n        s[16] = rotate(s[5] ^ bc[4], 36UL);\n        s[5] = rotate(s[3] ^ bc[2], 28UL);\n        s[3] = rotate(s[18] ^ bc[2], 21UL);\n        s[18] = rotate(s[17] ^ bc[1], 15UL);\n        s[17] = rotate(s[11] ^ bc[0], 10UL);\n        s[11] = rotate(s[7] ^ bc[1], 6UL);\n        s[7] = rotate(s[10] ^ bc[4], 3UL);\n        s[10] = rotate(tmp1, 1UL);\n        \n        tmp1 = s[0]; tmp2 = s[1]; s[0] = bitselect(s[0] ^ s[2], s[0], s[1]); s[1] = bitselect(s[1] ^ s[3], s[1], s[2]); s[2] = bitselect(s[2] ^ s[4], s[2], s[3]); s[3] = bitselect(s[3] ^ tmp1, s[3], s[4]); s[4] = bitselect(s[4] ^ tmp2, s[4], tmp1);\n        tmp1 = s[5]; tmp2 = s[6]; s[5] = bitselect(s[5] ^ s[7], s[5], s[6]); s[6] = bitselect(s[6] ^ s[8], s[6], s[7]); s[7] = bitselect(s[7] ^ s[9], s[7], s[8]); s[8] = bitselect(s[8] ^ tmp1, s[8], s[9]); s[9] = bitselect(s[9] ^ tmp2, s[9], tmp1);\n        tmp1 = s[10]; tmp2 = s[11]; s[10] = bitselect(s[10] ^ s[12], s[10], s[11]); s[11] = bitselect(s[11] ^ s[13], s[11], s[12]); s[12] = bitselect(s[12] ^ s[14], s[12], s[13]); s[13] = bitselect(s[13] ^ tmp1, s[13], s[14]); s[14] = bitselect(s[14] ^ tmp2, s[14], tmp1);\n        tmp1 = s[15]; tmp2 = s[16]; s[15] = bitselect(s[15] ^ s[17], s[15], s[16]); s[16] = bitselect(s[16] ^ s[18], s[16], s[17]); s[17] = bitselect(s[17] ^ s[19], s[17], s[18]); s[18] = bitselect(s[18] ^ tmp1, s[18], s[19]); s[19] = bitselect(s[19] ^ tmp2, s[19], tmp1);\n        tmp1 = s[20]; tmp2 = s[21]; s[20] = bitselect(s[20] ^ s[22], s[20], s[21]); s[21] = bitselect(s[21] ^ s[23], s[21], s[22]); s[22] = bitselect(s[22] ^ s[24], s[22], s[23]); s[23] = bitselect(s[23] ^ tmp1, s[23], s[24]); s[24] = bitselect(s[24] ^ tmp2, s[24], tmp1);\n        s[0] ^= keccakf_rndc[i];\n    }\n}\n\nstatic const __constant uint keccakf_rotc[24] = \n{\n    1,  3,  6,  10, 15, 21, 28, 36, 45, 55, 2,  14, \n    27, 41, 56, 8,  25, 43, 62, 18, 39, 61, 20, 44\n};\n\nstatic const __constant uint keccakf_piln[24] = \n{\n    10, 7,  11, 17, 18, 3, 5,  16, 8,  21, 24, 4, \n    15, 23, 19, 13, 12, 2, 20, 14, 22, 9,  6,  1 \n};\n\nvoid keccakf1600_1(ulong *st)\n{\n    int i, round;\n    ulong t, bc[5];\n\t\n\t#pragma unroll 1\n    for(round = 0; round < 24; ++round)\n    {\n\n        // Theta\n        bc[0] = st[0] ^ st[5] ^ st[10] ^ st[15] ^ st[20];\n        bc[1] = st[1] ^ st[6] ^ st[11] ^ st[16] ^ st[21];\n        bc[2] = st[2] ^ st[7] ^ st[12] ^ st[17] ^ st[22];\n        bc[3] = st[3] ^ st[8] ^ st[13] ^ st[18] ^ st[23];\n        bc[4] = st[4] ^ st[9] ^ st[14] ^ st[19] ^ st[24];\n\t\t\n\t\t#pragma unroll 1\n        for (i = 0; i < 5; ++i) {\n            t = bc[(i + 4) % 5] ^ rotate(bc[(i + 1) % 5], 1UL);\n            st[i     ] ^= t;\n            st[i +  5] ^= t;\n            st[i + 10] ^= t;\n            st[i + 15] ^= t;\n            st[i + 20] ^= t;\n        }\n\n        // Rho Pi\n        t = st[1];\n        #pragma unroll\n        for (i = 0; i < 24; ++i) {\n            bc[0] = st[keccakf_piln[i]];\n            st[keccakf_piln[i]] = rotate(t, (ulong)keccakf_rotc[i]);\n            t = bc[0];\n        }\n\n        //ulong tmp1 = st[0]; ulong tmp2 = st[1]; st[0] = bitselect(st[0] ^ st[2], st[0], st[1]); st[1] = bitselect(st[1] ^ st[3], st[1], st[2]); st[2] = bitselect(st[2] ^ st[4], st[2], st[3]); st[3] = bitselect(st[3] ^ tmp1, st[3], st[4]); st[4] = bitselect(st[4] ^ tmp2, st[4], tmp1);\n        //tmp1 = st[5]; tmp2 = st[6]; st[5] = bitselect(st[5] ^ st[7], st[5], st[6]); st[6] = bitselect(st[6] ^ st[8], st[6], st[7]); st[7] = bitselect(st[7] ^ st[9], st[7], st[8]); st[8] = bitselect(st[8] ^ tmp1, st[8], st[9]); st[9] = bitselect(st[9] ^ tmp2, st[9], tmp1);\n        //tmp1 = st[10]; tmp2 = st[11]; st[10] = bitselect(st[10] ^ st[12], st[10], st[11]); st[11] = bitselect(st[11] ^ st[13], st[11], st[12]); st[12] = bitselect(st[12] ^ st[14], st[12], st[13]); st[13] = bitselect(st[13] ^ tmp1, st[13], st[14]); st[14] = bitselect(st[14] ^ tmp2, st[14], tmp1);\n        //tmp1 = st[15]; tmp2 = st[16]; st[15] = bitselect(st[15] ^ st[17], st[15], st[16]); st[16] = bitselect(st[16] ^ st[18], st[16], st[17]); st[17] = bitselect(st[17] ^ st[19], st[17], st[18]); st[18] = bitselect(st[18] ^ tmp1, st[18], st[19]); st[19] = bitselect(st[19] ^ tmp2, st[19], tmp1);\n        //tmp1 = st[20]; tmp2 = st[21]; st[20] = bitselect(st[20] ^ st[22], st[20], st[21]); st[21] = bitselect(st[21] ^ st[23], st[21], st[22]); st[22] = bitselect(st[22] ^ st[24], st[22], st[23]); st[23] = bitselect(st[23] ^ tmp1, st[23], st[24]); st[24] = bitselect(st[24] ^ tmp2, st[24], tmp1);\n        \n        #pragma unroll 1\n        for(int i = 0; i < 25; i += 5)\n        {\t\n\t\t\tulong tmp[5];\n\t\t\t\n\t\t\t#pragma unroll 1\n\t\t\tfor(int x = 0; x < 5; ++x)\n\t\t\t\ttmp[x] = bitselect(st[i + x] ^ st[i + ((x + 2) % 5)], st[i + x], st[i + ((x + 1) % 5)]);\n\t\t\t\n\t\t\t#pragma unroll 1\n\t\t\tfor(int x = 0; x < 5; ++x) st[i + x] = tmp[x];\n        }\n        \n        //  Iota\n        st[0] ^= keccakf_rndc[round];\n    }\n}\n\nvoid keccakf1600_2(ulong *st)\n{\n    int i, round;\n    ulong t, bc[5];\n\t\n\t#pragma unroll 1\n    for(round = 0; round < 24; ++round)\n    {\n\n        // Theta\n        //bc[0] = st[0] ^ st[5] ^ st[10] ^ st[15] ^ st[20];\n        //bc[1] = st[1] ^ st[6] ^ st[11] ^ st[16] ^ st[21];\n        //bc[2] = st[2] ^ st[7] ^ st[12] ^ st[17] ^ st[22];\n        //bc[3] = st[3] ^ st[8] ^ st[13] ^ st[18] ^ st[23];\n        //bc[4] = st[4] ^ st[9] ^ st[14] ^ st[19] ^ st[24];\n\t\t\n\t\t/*\n\t\t#pragma unroll\n        for (i = 0; i < 5; ++i) {\n            t = bc[(i + 4) % 5] ^ rotate(bc[(i + 1) % 5], 1UL);\n            st[i     ] ^= t;\n            st[i +  5] ^= t;\n            st[i + 10] ^= t;\n            st[i + 15] ^= t;\n            st[i + 20] ^= t;\n        }\n\t\t*/\n\t\t\n\t\tbc[0] = st[0] ^ st[5] ^ st[10] ^ st[15] ^ st[20] ^ rotate(st[2] ^ st[7] ^ st[12] ^ st[17] ^ st[22], 1UL);\n\t\tbc[1] = st[1] ^ st[6] ^ st[11] ^ st[16] ^ st[21] ^ rotate(st[3] ^ st[8] ^ st[13] ^ st[18] ^ st[23], 1UL);\n\t\tbc[2] = st[2] ^ st[7] ^ st[12] ^ st[17] ^ st[22] ^ rotate(st[4] ^ st[9] ^ st[14] ^ st[19] ^ st[24], 1UL);\n\t\tbc[3] = st[3] ^ st[8] ^ st[13] ^ st[18] ^ st[23] ^ rotate(st[0] ^ st[5] ^ st[10] ^ st[15] ^ st[20], 1UL);\n\t\tbc[4] = st[4] ^ st[9] ^ st[14] ^ st[19] ^ st[24] ^ rotate(st[1] ^ st[6] ^ st[11] ^ st[16] ^ st[21], 1UL);\n\t\t\n\t\tst[0] ^= bc[4];\n\t\tst[5] ^= bc[4];\n\t\tst[10] ^= bc[4];\n\t\tst[15] ^= bc[4];\n\t\tst[20] ^= bc[4];\n\t\t\n\t\tst[1] ^= bc[0];\n\t\tst[6] ^= bc[0];\n\t\tst[11] ^= bc[0];\n\t\tst[16] ^= bc[0];\n\t\tst[21] ^= bc[0];\n\t\t\n\t\tst[2] ^= bc[1];\n\t\tst[7] ^= bc[1];\n\t\tst[12] ^= bc[1];\n\t\tst[17] ^= bc[1];\n\t\tst[22] ^= bc[1];\n\t\t\n\t\tst[3] ^= bc[2];\n\t\tst[8] ^= bc[2];\n\t\tst[13] ^= bc[2];\n\t\tst[18] ^= bc[2];\n\t\tst[23] ^= bc[2];\n\t\t\n\t\tst[4] ^= bc[3];\n\t\tst[9] ^= bc[3];\n\t\tst[14] ^= bc[3];\n\t\tst[19] ^= bc[3];\n\t\tst[24] ^= bc[3];\n\t\t\n        // Rho Pi\n        t = st[1];\n        #pragma unroll\n        for (i = 0; i < 24; ++i) {\n            bc[0] = st[keccakf_piln[i]];\n            st[keccakf_piln[i]] = rotate(t, (ulong)keccakf_rotc[i]);\n            t = bc[0];\n        }\n\t\t\n\t\t\n\t\t\n\t\t/*ulong tmp1 = st[1] ^ bc[0];\n        \n        st[0] ^= bc[4];\n        st[1] = rotate(st[6] ^ bc[0], 44UL);\n        st[6] = rotate(st[9] ^ bc[3], 20UL);\n        st[9] = rotate(st[22] ^ bc[1], 61UL);\n        st[22] = rotate(st[14] ^ bc[3], 39UL);\n        st[14] = rotate(st[20] ^ bc[4], 18UL);\n        st[20] = rotate(st[2] ^ bc[1], 62UL);\n        st[2] = rotate(st[12] ^ bc[1], 43UL);\n        st[12] = rotate(st[13] ^ bc[2], 25UL);\n        st[13] = rotate(st[19] ^ bc[3], 8UL);\n        st[19] = rotate(st[23] ^ bc[2], 56UL);\n        st[23] = rotate(st[15] ^ bc[4], 41UL);\n        st[15] = rotate(st[4] ^ bc[3], 27UL);\n        st[4] = rotate(st[24] ^ bc[3], 14UL);\n        st[24] = rotate(st[21] ^ bc[0], 2UL);\n        st[21] = rotate(st[8] ^ bc[2], 55UL);\n        st[8] = rotate(st[16] ^ bc[0], 35UL);\n        st[16] = rotate(st[5] ^ bc[4], 36UL);\n        st[5] = rotate(st[3] ^ bc[2], 28UL);\n        st[3] = rotate(st[18] ^ bc[2], 21UL);\n        st[18] = rotate(st[17] ^ bc[1], 15UL);\n        st[17] = rotate(st[11] ^ bc[0], 10UL);\n        st[11] = rotate(st[7] ^ bc[1], 6UL);\n        st[7] = rotate(st[10] ^ bc[4], 3UL);\n        st[10] = rotate(tmp1, 1UL);\n\t\t*/\n\t\t\n\t\t\n        //ulong tmp1 = st[0]; ulong tmp2 = st[1]; st[0] = bitselect(st[0] ^ st[2], st[0], st[1]); st[1] = bitselect(st[1] ^ st[3], st[1], st[2]); st[2] = bitselect(st[2] ^ st[4], st[2], st[3]); st[3] = bitselect(st[3] ^ tmp1, st[3], st[4]); st[4] = bitselect(st[4] ^ tmp2, st[4], tmp1);\n        //tmp1 = st[5]; tmp2 = st[6]; st[5] = bitselect(st[5] ^ st[7], st[5], st[6]); st[6] = bitselect(st[6] ^ st[8], st[6], st[7]); st[7] = bitselect(st[7] ^ st[9], st[7], st[8]); st[8] = bitselect(st[8] ^ tmp1, st[8], st[9]); st[9] = bitselect(st[9] ^ tmp2, st[9], tmp1);\n        //tmp1 = st[10]; tmp2 = st[11]; st[10] = bitselect(st[10] ^ st[12], st[10], st[11]); st[11] = bitselect(st[11] ^ st[13], st[11], st[12]); st[12] = bitselect(st[12] ^ st[14], st[12], st[13]); st[13] = bitselect(st[13] ^ tmp1, st[13], st[14]); st[14] = bitselect(st[14] ^ tmp2, st[14], tmp1);\n        //tmp1 = st[15]; tmp2 = st[16]; st[15] = bitselect(st[15] ^ st[17], st[15], st[16]); st[16] = bitselect(st[16] ^ st[18], st[16], st[17]); st[17] = bitselect(st[17] ^ st[19], st[17], st[18]); st[18] = bitselect(st[18] ^ tmp1, st[18], st[19]); st[19] = bitselect(st[19] ^ tmp2, st[19], tmp1);\n        //tmp1 = st[20]; tmp2 = st[21]; st[20] = bitselect(st[20] ^ st[22], st[20], st[21]); st[21] = bitselect(st[21] ^ st[23], st[21], st[22]); st[22] = bitselect(st[22] ^ st[24], st[22], st[23]); st[23] = bitselect(st[23] ^ tmp1, st[23], st[24]); st[24] = bitselect(st[24] ^ tmp2, st[24], tmp1);\n        \n        #pragma unroll\n        for(int i = 0; i < 25; i += 5)\n        {\n\t\t\tulong tmp1 = st[i], tmp2 = st[i + 1];\n\t\t\t\n\t\t\tst[i] = bitselect(st[i] ^ st[i + 2], st[i], st[i + 1]);\n\t\t\tst[i + 1] = bitselect(st[i + 1] ^ st[i + 3], st[i + 1], st[i + 2]);\n\t\t\tst[i + 2] = bitselect(st[i + 2] ^ st[i + 4], st[i + 2], st[i + 3]);\n\t\t\tst[i + 3] = bitselect(st[i + 3] ^ tmp1, st[i + 3], st[i + 4]);\n\t\t\tst[i + 4] = bitselect(st[i + 4] ^ tmp2, st[i + 4], tmp1);\n        }\n        \n        //  Iota\n        st[0] ^= keccakf_rndc[round];\n    }\n}\n\nvoid CNKeccak(ulong *output, ulong *input)\n{\n\tulong st[25];\n\t\n\t// Copy 72 bytes\n\tfor(int i = 0; i < 9; ++i) st[i] = input[i];\n\t\n\t// Last four and '1' bit for padding\n\t//st[9] = as_ulong((uint2)(((uint *)input)[18], 0x00000001U));\n\t\n\tst[9] = (input[9] & 0x00000000FFFFFFFFUL) | 0x0000000100000000UL;\n\t\n\tfor(int i = 10; i < 25; ++i) st[i] = 0x00UL;\n\t\n\t// Last bit of padding\n\tst[16] = 0x8000000000000000UL;\n\t\n\tkeccakf1600_1(st);\n\t\n\tfor(int i = 0; i < 25; ++i) output[i] = st[i];\n}\n\nstatic const __constant uchar rcon[8] = { 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40 };\n\n#pragma OPENCL EXTENSION cl_amd_media_ops2 : enable\n\n#define BYTE(x, y)\t(amd_bfe((x), (y) << 3U, 8U))\n\n#define SubWord(inw)\t\t((sbox[BYTE(inw, 3)] << 24) | (sbox[BYTE(inw, 2)] << 16) | (sbox[BYTE(inw, 1)] << 8) | sbox[BYTE(inw, 0)])\n\nvoid AESExpandKey256(uint *keybuf)\n{\n\t//#pragma unroll 4\n\tfor(uint c = 8, i = 1; c < 60; ++c)\n\t{\n\t\t// For 256-bit keys, an sbox permutation is done every other 4th uint generated, AND every 8th\n\t\tuint t = ((!(c & 7)) || ((c & 7) == 4)) ? SubWord(keybuf[c - 1]) : keybuf[c - 1];\n\t\t\n\t\t// If the uint we're generating has an index that is a multiple of 8, rotate and XOR with the round constant,\n\t\t// then XOR this with previously generated uint. If it's 4 after a multiple of 8, only the sbox permutation\n\t\t// is done, followed by the XOR. If neither are true, only the XOR with the previously generated uint is done.\n\t\tkeybuf[c] = keybuf[c - 8] ^ ((!(c & 7)) ? rotate(t, 24U) ^ as_uint((uchar4)(rcon[i++], 0U, 0U, 0U)) : t);\n\t}\n}\n\n#define IDX(x)\t(x)\n\n__attribute__((reqd_work_group_size(WORKSIZE, 8, 1)))\n__kernel void cn0(__global ulong *input, __global uint4 *Scratchpad, __global ulong *states)\n{\n\tulong State[25];\n\tuint ExpandedKey1[256];\n\t__local uint AES0[256], AES1[256], AES2[256], AES3[256];\n\tuint4 text;\n\t\n\tstates += (25 * (get_global_id(0) - get_global_offset(0)));\n\tScratchpad += ((get_global_id(0) - get_global_offset(0))) * (0x80000 >> 2);\n\t\n\tfor(int i = get_local_id(0); i < 256; i += WORKSIZE)\n\t{\n\t\tconst uint tmp = AES0_C[i];\n\t\tAES0[i] = tmp;\n\t\tAES1[i] = rotate(tmp, 8U);\n\t\tAES2[i] = rotate(tmp, 16U);\n\t\tAES3[i] = rotate(tmp, 24U);\n\t}\n\tbarrier(CLK_LOCAL_MEM_FENCE);\n\t\n\t((ulong8 *)State)[0] = vload8(0, input);\n\tState[8] = input[8];\n\tState[9] = input[9];\n\tState[10] = input[10];\n\n\t((uint *)State)[9] &= 0x00FFFFFFU;\n\t((uint *)State)[9] |= ((get_global_id(0)) & 0xFF) << 24;\n\t((uint *)State)[10] &= 0xFF000000U;\n\t((uint *)State)[10] |= ((get_global_id(0) >> 8));\n\t\n\tfor(int i = 11; i < 25; ++i) State[i] = 0x00UL;\n\t\n\t// Last bit of padding\n\tState[16] = 0x8000000000000000UL;\n\t\n\tkeccakf1600_2(State);\n\t\n\tmem_fence(CLK_GLOBAL_MEM_FENCE);\n\t\n\t#pragma unroll\n\tfor(int i = 0; i < 25; ++i) states[i] = State[i];\n\t\n\ttext = vload4(get_local_id(1) + 4, (__global uint *)(states));\n\t\n\t#pragma unroll\n\tfor(int i = 0; i < 4; ++i) ((ulong *)ExpandedKey1)[i] = states[i];\n\t\n\tAESExpandKey256(ExpandedKey1);\n\t\n\tmem_fence(CLK_LOCAL_MEM_FENCE);\n\t\n\t#pragma unroll 2\n\tfor(int i = 0; i < 0x4000; ++i)\n\t{\n\t\t#pragma unroll\n\t\tfor(int j = 0; j < 10; ++j)\n\t\t\ttext = AES_Round(AES0, AES1, AES2, AES3, text, ((uint4 *)ExpandedKey1)[j]);\n\t\t\n\t\tScratchpad[IDX((i << 3) + get_local_id(1))] = text;\n\t}\n\t\n\tmem_fence(CLK_GLOBAL_MEM_FENCE);\n}\n\n__attribute__((reqd_work_group_size(WORKSIZE, 1, 1)))\n__kernel void cn1(__global uint4 *Scratchpad, __global ulong *states)\n{\n\tulong a[2], b[2];\n\t__local uint AES0[256], AES1[256], AES2[256], AES3[256];\n\t\n\tScratchpad += ((get_global_id(0) - get_global_offset(0))) * (0x80000 >> 2);\n\tstates += (25 * (get_global_id(0) - get_global_offset(0)));\n\t\n\tfor(int i = get_local_id(0); i < 256; i += WORKSIZE)\n\t{\n\t\tconst uint tmp = AES0_C[i];\n\t\tAES0[i] = tmp;\n\t\tAES1[i] = rotate(tmp, 8U);\n\t\tAES2[i] = rotate(tmp, 16U);\n\t\tAES3[i] = rotate(tmp, 24U);\n\t}\n\tbarrier(CLK_LOCAL_MEM_FENCE);\n\t\n\ta[0] = states[0] ^ states[4];\n\tb[0] = states[2] ^ states[6];\n\ta[1] = states[1] ^ states[5];\n\tb[1] = states[3] ^ states[7];\n\t\n\tuint4 b_x = ((uint4 *)b)[0];\n\t\n\tmem_fence(CLK_LOCAL_MEM_FENCE);\n\t\n\t#pragma unroll 8\n\tfor(int i = 0; i < 0x80000; ++i)\n\t{\n\t\tulong c[2];\n\t\t\n\t\t((uint4 *)c)[0] = Scratchpad[IDX((a[0] & 0x1FFFF0) >> 4)];\n\t\t((uint4 *)c)[0] = AES_Round(AES0, AES1, AES2, AES3, ((uint4 *)c)[0], ((uint4 *)a)[0]);\n\t\t//b_x ^= ((uint4 *)c)[0];\n\t\t\n\t\tScratchpad[IDX((a[0] & 0x1FFFF0) >> 4)] = b_x ^ ((uint4 *)c)[0];\n\t\t\n\t\tuint4 tmp;\n\t\ttmp = Scratchpad[IDX((c[0] & 0x1FFFF0) >> 4)];\n\t\t\n\t\ta[1] += c[0] * as_ulong2(tmp).s0;\n\t\ta[0] += mul_hi(c[0], as_ulong2(tmp).s0);\n\t\t\n\t\tScratchpad[IDX((c[0] & 0x1FFFF0) >> 4)] = ((uint4 *)a)[0];\n\t\t\n\t\t((uint4 *)a)[0] ^= tmp;\n\t\t\n\t\tb_x = ((uint4 *)c)[0];\n\t}\n\t\n\tmem_fence(CLK_GLOBAL_MEM_FENCE);\n}\n\n__attribute__((reqd_work_group_size(WORKSIZE, 8, 1)))\n__kernel void cn2(__global uint4 *Scratchpad, __global ulong *states, __global uint *Branch0, __global uint *Branch1, __global uint *Branch2, __global uint *Branch3)\n{\n\t__local uint AES0[256], AES1[256], AES2[256], AES3[256];\n\tuint ExpandedKey2[256];\n\tulong State[25];\n\tuint4 text;\n\t\n\tScratchpad += ((get_global_id(0) - get_global_offset(0))) * (0x80000 >> 2);\n\tstates += (25 * (get_global_id(0) - get_global_offset(0)));\n\t\n\tfor(int i = get_local_id(0); i < 256; i += WORKSIZE)\n\t{\n\t\tconst uint tmp = AES0_C[i];\n\t\tAES0[i] = tmp;\n\t\tAES1[i] = rotate(tmp, 8U);\n\t\tAES2[i] = rotate(tmp, 16U);\n\t\tAES3[i] = rotate(tmp, 24U);\n\t}\n\tbarrier(CLK_LOCAL_MEM_FENCE);\n\t\n\t#if defined(__Tahiti__) || defined(__Pitcairn__)\n\t\n\tfor(int i = 0; i < 4; ++i) ((ulong *)ExpandedKey2)[i] = states[i + 4];\n\ttext = vload4(get_local_id(1) + 4, (__global uint *)states);\n\t\n\t#else\n\t\n\ttext = vload4(get_local_id(1) + 4, (__global uint *)states);\n\t((uint8 *)ExpandedKey2)[0] = vload8(1, (__global uint *)states);\n\t\n\t#endif\n\t\n\tAESExpandKey256(ExpandedKey2);\n\t\n\tbarrier(CLK_LOCAL_MEM_FENCE);\n\t\n\t#pragma unroll 2\n\tfor(int i = 0; i < 0x4000; ++i)\n\t{\t\t\n\t\ttext ^= Scratchpad[IDX((i << 3) + get_local_id(1))];\n\t\t\n\t\t#pragma unroll\n\t\tfor(int j = 0; j < 10; ++j)\n\t\t\ttext = AES_Round(AES0, AES1, AES2, AES3, text, ((uint4 *)ExpandedKey2)[j]);\n\t}\n\t\n\tvstore2(as_ulong2(text), get_local_id(1) + 4, states);\n\t\n\tbarrier(CLK_GLOBAL_MEM_FENCE);\n\t\n\tif(!get_local_id(1))\n\t{\n\t\tfor(int i = 0; i < 25; ++i) State[i] = states[i];\n\t\t\n\t\tkeccakf1600_2(State);\n\t\t\n\t\tfor(int i = 0; i < 25; ++i) states[i] = State[i];\n\t\t\n\t\tswitch(State[0] & 3)\n\t\t{\n\t\t\tcase 0:\n\t\t\t\tBranch0[atomic_inc(Branch0 + get_global_size(0))] = get_global_id(0) - get_global_offset(0);\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\tBranch1[atomic_inc(Branch1 + get_global_size(0))] = get_global_id(0) - get_global_offset(0);\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\tBranch2[atomic_inc(Branch2 + get_global_size(0))] = get_global_id(0) - get_global_offset(0);\n\t\t\t\tbreak;\n\t\t\tcase 3:\n\t\t\t\tBranch3[atomic_inc(Branch3 + get_global_size(0))] = get_global_id(0) - get_global_offset(0);\n\t\t\t\tbreak;\n\t\t}\n\t}\n\t\n\tmem_fence(CLK_GLOBAL_MEM_FENCE);\n}\n\n/*\n__kernel void cryptonight(__global ulong *input, __global uint4 *Scratchpad, __global ulong *states, __global uint *Branch0, __global uint *Branch1, __global uint *Branch2, __global uint *Branch3, ulong ThreadCount)\n{\n\tuchar State[200];\n\t__local uint AES0[256], AES1[256], AES2[256], AES3[256];\n\tuchar ExpandedKey1[256], ExpandedKey2[256];\n\tulong inbuf[10], a[2], b[2];\n\tuint4 text[8];\n\t\n\tfor(int i = 0; i < 256; ++i)\n\t{\n\t\tconst uint tmp = AES0_C[i];\n\t\tAES0[i] = tmp;\n\t\tAES1[i] = rotate(tmp, 8U);\n\t\tAES2[i] = rotate(tmp, 16U);\n\t\tAES3[i] = rotate(tmp, 24U);\n\t}\n\t\n\t((ulong8 *)inbuf)[0] = vload8(0, input);\n\tinbuf[8] = input[8];\n\tinbuf[9] = (ulong)((__global uint *)input)[18];\n\t\n\t((uint *)(((uchar *)inbuf) + 39))[0] = get_global_id(0);\n\tCNKeccak((ulong *)State, inbuf);\n\t\n\ta[0] = ((ulong *)State)[0] ^ ((ulong *)State)[4];\n\tb[0] = ((ulong *)State)[2] ^ ((ulong *)State)[6];\n\ta[1] = ((ulong *)State)[1] ^ ((ulong *)State)[5];\n\tb[1] = ((ulong *)State)[3] ^ ((ulong *)State)[7];\n\t\n\tfor(uint i = 0; i < 8; ++i) text[i] = vload4(i + 4, (uint *)(State));\n\t\n\tfor(int i = 0; i < 4; ++i) ((ulong *)ExpandedKey1)[i] = ((ulong *)State)[i];\n\tfor(int i = 0; i < 4; ++i) ((ulong *)ExpandedKey2)[i] = ((ulong *)State)[i + 4];\n\t\t\n\tAESExpandKey256(ExpandedKey1);\n\tAESExpandKey256(ExpandedKey2);\n\t\n\tmem_fence(CLK_LOCAL_MEM_FENCE);\n\t\n\tScratchpad += ((1 << 17) * (get_global_id(0) - get_global_offset(0)));\n\t\n\t//#pragma unroll 1\n\tfor(int i = 0; i < (1 << 17); i += 8)\n\t{\n\t\t#pragma unroll\n\t\tfor(int j = 0; j < 10; ++j)\n\t\t{\n\t\t\t#pragma unroll\n\t\t\tfor(int x = 0; x < 8; ++x)\n\t\t\t\ttext[x] = AES_Round(AES0, AES1, AES2, AES3, text[x], ((uint4 *)ExpandedKey1)[j]);\n\t\t}\n\t\t\n\t\tfor(int j = 0; j < 8; ++j) *(Scratchpad + i + j) = text[j];\n\t}\n\t\n\t\n\tuint4 b_x = ((uint4 *)b)[0];\n\t\n\t//#pragma unroll 1\n\tfor(int i = 0; i < 0x80000; ++i)\n\t{\n\t\tulong c[2];\n\t\t\n\t\t((uint4 *)c)[0] = Scratchpad[(a[0] & 0x1FFFF0) >> 4];\n\t\t((uint4 *)c)[0] = AES_Round(AES0, AES1, AES2, AES3, ((uint4 *)c)[0], ((uint4 *)a)[0]);\n\t\tb_x ^= ((uint4 *)c)[0];\n\t\t\n\t\tScratchpad[(a[0] & 0x1FFFF0) >> 4] = b_x;\n\t\t\n\t\tuint4 tmp;\n\t\ttmp = Scratchpad[(c[0] & 0x1FFFF0) >> 4];\n\t\t\n\t\ta[1] += c[0] * as_ulong2(tmp).s0;\n\t\ta[0] += mul_hi(c[0], as_ulong2(tmp).s0);\n\t\t\n\t\tScratchpad[(c[0] & 0x1FFFF0) >> 4] = ((uint4 *)a)[0];\n\t\t\n\t\t((uint4 *)a)[0] ^= tmp;\n\t\t\n\t\tb_x = ((uint4 *)c)[0];\n\t}\n\t\n\tfor(uint i = 0; i < 8; ++i) text[i] = vload4(i + 4, (uint *)(State));\n\t\n\tfor(int i = 0; i < (1 << 17); i += 8)\n\t{\n\t\t#pragma unroll\n\t\tfor(int j = 0; j < 8; ++j) text[j] ^= Scratchpad[i + j];\n\t\t\n\t\t#pragma unroll 1\n\t\tfor(int j = 0; j < 10; ++j)\n\t\t{\n\t\t\t#pragma unroll\n\t\t\tfor(int x = 0; x < 8; ++x)\n\t\t\t\ttext[x] = AES_Round(AES0, AES1, AES2, AES3, text[x], ((uint4 *)ExpandedKey2)[j]);\n\t\t}\n\t}\n\t\n\tfor(uint i = 0; i < 8; ++i) vstore4(text[i], i + 4, (uint *)(State));\n\t\n\tkeccakf1600((ulong *)State);\n\t\t\n\tstates += (25 * (get_global_id(0) - get_global_offset(0)));\n\t\n\tfor(int i = 0; i < 25; ++i) states[i] = ((ulong *)State)[i];\n\t\n\tswitch(State[0] & 3)\n\t{\n\t\tcase 0:\n\t\t\tBranch0[atomic_inc(Branch0 + ThreadCount)] = get_global_id(0) - get_global_offset(0);\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tBranch1[atomic_inc(Branch1 + ThreadCount)] = get_global_id(0) - get_global_offset(0);\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tBranch2[atomic_inc(Branch2 + ThreadCount)] = get_global_id(0) - get_global_offset(0);\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tBranch3[atomic_inc(Branch3 + ThreadCount)] = get_global_id(0) - get_global_offset(0);\n\t\t\tbreak;\n\t}\t\n}\n*/\n\n#define VSWAP8(x)\t(((x) >> 56) | (((x) >> 40) & 0x000000000000FF00UL) | (((x) >> 24) & 0x0000000000FF0000UL) \\\n          | (((x) >>  8) & 0x00000000FF000000UL) | (((x) <<  8) & 0x000000FF00000000UL) \\\n          | (((x) << 24) & 0x0000FF0000000000UL) | (((x) << 40) & 0x00FF000000000000UL) | (((x) << 56) & 0xFF00000000000000UL))\n\n#define VSWAP4(x)\t((((x) >> 24) & 0xFFU) | (((x) >> 8) & 0xFF00U) | (((x) << 8) & 0xFF0000U) | (((x) << 24) & 0xFF000000U))\n\n__kernel void Skein(__global ulong *states, __global uint *BranchBuf, __global uint *output, uint Target, ulong Threads)\n{\n\tconst ulong idx = get_global_id(0) - get_global_offset(0);\n\t\n\tif(idx >= Threads) return;\n\t\n\tstates += 25 * BranchBuf[idx];\n\t\n\t// skein\n\tulong8 h = vload8(0, SKEIN512_256_IV);\n\t\n\t// Type field begins with final bit, first bit, then six bits of type; the last 96\n\t// bits are input processed (including in the block to be processed with that tweak)\n\t// The output transform is only one run of UBI, since we need only 256 bits of output\n\t// The tweak for the output transform is Type = Output with the Final bit set\n\t// T[0] for the output is 8, and I don't know why - should be message size...\n\tulong t[3] = { 0x00UL, 0x7000000000000000UL, 0x00UL };\n\tulong8 p, m;\n\t\n\tfor(uint i = 0; i < 4; ++i)\n\t{\n\t\tif(i < 3) t[0] += 0x40UL;\n\t\telse t[0] += 0x08UL;\n\t\t\n\t\tt[2] = t[0] ^ t[1];\n\t\t\n\t\tm = (i < 3) ? vload8(i, states) : (ulong8)(states[24], 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL);\n\t\tconst ulong h8 = h.s0 ^ h.s1 ^ h.s2 ^ h.s3 ^ h.s4 ^ h.s5 ^ h.s6 ^ h.s7 ^ SKEIN_KS_PARITY;\n\t\tp = Skein512Block(m, h, h8, t);\n\t\t\n\t\th = m ^ p;\n\t\t\n\t\tif(i < 2) t[1] = 0x3000000000000000UL;\n\t\telse t[1] = 0xB000000000000000UL;\n\t}\n\t\n\tt[0] = 0x08UL;\n\tt[1] = 0xFF00000000000000UL;\n\tt[2] = t[0] ^ t[1];\n\t\n\tp = (ulong8)(0);\n\tconst ulong h8 = h.s0 ^ h.s1 ^ h.s2 ^ h.s3 ^ h.s4 ^ h.s5 ^ h.s6 ^ h.s7 ^ SKEIN_KS_PARITY;\n\t\n\tp = Skein512Block(p, h, h8, t);\n\t\n\t//vstore8(p, 0, output);\n\t\n\tif(as_uint16(p).s7 <= Target) output[atomic_inc(output + 0xFF)] = BranchBuf[idx] + get_global_offset(0);\n\t\n\tmem_fence(CLK_GLOBAL_MEM_FENCE);\t\n}\n\n#define SWAP8(x)\tas_ulong(as_uchar8(x).s76543210)\n\n__kernel void JH(__global ulong *states, __global uint *BranchBuf, __global uint *output, uint Target, ulong Threads)\n{\n\tconst uint idx = get_global_id(0) - get_global_offset(0);\n\t\n\tif(idx >= Threads) return;\n\t\n\tstates += 25 * BranchBuf[idx];\n\t\n\tsph_u64 h0h = 0xEBD3202C41A398EBUL, h0l = 0xC145B29C7BBECD92UL, h1h = 0xFAC7D4609151931CUL, h1l = 0x038A507ED6820026UL, h2h = 0x45B92677269E23A4UL, h2l = 0x77941AD4481AFBE0UL, h3h = 0x7A176B0226ABB5CDUL, h3l = 0xA82FFF0F4224F056UL;\n\tsph_u64 h4h = 0x754D2E7F8996A371UL, h4l = 0x62E27DF70849141DUL, h5h = 0x948F2476F7957627UL, h5l = 0x6C29804757B6D587UL, h6h = 0x6C0D8EAC2D275E5CUL, h6l = 0x0F7A0557C6508451UL, h7h = 0xEA12247067D3E47BUL, h7l = 0x69D71CD313ABE389UL;\n\tsph_u64 tmp;\n\t\n\tfor(int i = 0; i < 5; ++i)\n\t{\n\t\tulong input[8];\n\t\t\n\t\tif(i < 3)\n\t\t{\n\t\t\tfor(int x = 0; x < 8; ++x) input[x] = (states[(i << 3) + x]);\n\t\t}\n\t\telse if(i == 3)\n\t\t{\n\t\t\tinput[0] = (states[24]);\n\t\t\tinput[1] = 0x80UL;\n\t\t\tfor(int x = 2; x < 8; ++x) input[x] = 0x00UL;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tinput[7] = 0x4006000000000000UL;\n\t\t\t\t\t\t\n\t\t\tfor(int x = 0; x < 7; ++x) input[x] = 0x00UL;\n\t\t}\n\t\t\n\t\th0h ^= input[0];\n\t\th0l ^= input[1];\n\t\th1h ^= input[2];\n\t\th1l ^= input[3];\n\t\th2h ^= input[4];\n\t\th2l ^= input[5];\n\t\th3h ^= input[6];\n\t\th3l ^= input[7];\n\t\t\n\t\tE8;\n\t\t\n\t\th4h ^= input[0];\n\t\th4l ^= input[1];\n\t\th5h ^= input[2];\n\t\th5l ^= input[3];\n\t\th6h ^= input[4];\n\t\th6l ^= input[5];\n\t\th7h ^= input[6];\n\t\th7l ^= input[7];\n\t}\n\t\n\t//output[0] = h6h;\n\t//output[1] = h6l;\n\t//output[2] = h7h;\n\t//output[3] = h7l;\n\t\n\tif(as_uint2(h7l).s1 <= Target) output[atomic_inc(output + 0xFF)] = BranchBuf[idx] + get_global_offset(0);\n}\n\n#define SWAP4(x)\tas_uint(as_uchar4(x).s3210)\n\n__kernel void Blake(__global ulong *states, __global uint *BranchBuf, __global uint *output, uint Target, ulong Threads)\n{\n\tconst uint idx = get_global_id(0) - get_global_offset(0);\n\t\n\tif(idx >= Threads) return;\n\t\n\tstates += 25 * BranchBuf[idx];\n\t\n\tunsigned int m[16];\n\tunsigned int v[16];\n\tuint h[8];\n\t\n\t((uint8 *)h)[0] = vload8(0U, c_IV256);\n\t\n\tfor(uint i = 0, bitlen = 0; i < 4; ++i)\n\t{\n\t\tif(i < 3)\n\t\t{\n\t\t\t((uint16 *)m)[0] = vload16(i, (__global uint *)states);\n\t\t\tfor(int i = 0; i < 16; ++i) m[i] = SWAP4(m[i]);\n\t\t\tbitlen += 512;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tm[0] = SWAP4(((__global uint *)states)[48]);\n\t\t\tm[1] = SWAP4(((__global uint *)states)[49]);\n\t\t\tm[2] = 0x80000000U;\n\t\t\t\n\t\t\tfor(int i = 3; i < 13; ++i) m[i] = 0x00U;\n\t\t\t\n\t\t\tm[13] = 1U;\n\t\t\tm[14] = 0U;\n\t\t\tm[15] = 0x640;\n\t\t\tbitlen += 64;\n\t\t}\n\t\t\n\t\t((uint16 *)v)[0].lo = ((uint8 *)h)[0];\n\t\t((uint16 *)v)[0].hi = vload8(0U, c_u256);\n\t\t\n\t\t//v[12] ^= (i < 3) ? (i + 1) << 9 : 1600U;\n\t\t//v[13] ^= (i < 3) ? (i + 1) << 9 : 1600U;\n\t\t\n\t\tv[12] ^= bitlen;\n\t\tv[13] ^= bitlen;\n\t\t\n\t\tfor(int r = 0; r < 14; r++)\n\t\t{\t\n\t\t\tGS(0, 4, 0x8, 0xC, 0x0);\n\t\t\tGS(1, 5, 0x9, 0xD, 0x2);\n\t\t\tGS(2, 6, 0xA, 0xE, 0x4);\n\t\t\tGS(3, 7, 0xB, 0xF, 0x6);\n\t\t\tGS(0, 5, 0xA, 0xF, 0x8);\n\t\t\tGS(1, 6, 0xB, 0xC, 0xA);\n\t\t\tGS(2, 7, 0x8, 0xD, 0xC);\n\t\t\tGS(3, 4, 0x9, 0xE, 0xE);\n\t\t}\n\t\t\n\t\t((uint8 *)h)[0] ^= ((uint8 *)v)[0] ^ ((uint8 *)v)[1];\n\t}\n\t\n\tfor(int i = 0; i < 8; ++i) h[i] = SWAP4(h[i]);\n\t\n\t//for(int i = 0; i < 4; ++i) output[i] = ((ulong *)h)[i];\n\tif(h[7] <= Target) output[atomic_inc(output + 0xFF)] = BranchBuf[idx] + get_global_offset(0);\n}\n\n__kernel void Groestl(__global ulong *states, __global uint *BranchBuf, __global uint *output, uint Target, ulong Threads)\n{\n\tconst uint idx = get_global_id(0) - get_global_offset(0);\n\t\n\tif(idx >= Threads) return;\n\t\n\tstates += 25 * BranchBuf[idx];\n\t\n\tulong State[8];\n\t\n\tfor(int i = 0; i < 7; ++i) State[i] = 0UL;\n\t\n\tState[7] = 0x0001000000000000UL;\n\t\n\tfor(uint i = 0; i < 4; ++i)\n\t{\n\t\tulong H[8], M[8];\n\t\t\n\t\tif(i < 3)\n\t\t{\n\t\t\t((ulong8 *)M)[0] = vload8(i, states);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tM[0] = states[24];\n\t\t\tM[1] = 0x80UL;\n\t\t\t\t\t\t\n\t\t\tfor(int x = 2; x < 7; ++x) M[x] = 0UL;\n\t\t\t\n\t\t\tM[7] = 0x0400000000000000UL;\n\t\t}\n\t\t\n\t\tfor(int x = 0; x < 8; ++x) H[x] = M[x] ^ State[x];\n\t\t\n\t\tPERM_SMALL_P(H);\n\t\tPERM_SMALL_Q(M);\n\t\t\n\t\tfor(int x = 0; x < 8; ++x) State[x] ^= H[x] ^ M[x];\n\t}\n\t\n\tulong tmp[8];\n\t\n\tfor(int i = 0; i < 8; ++i) tmp[i] = State[i];\n\t\n\tPERM_SMALL_P(State);\n\t\n\tfor(int i = 0; i < 8; ++i) State[i] ^= tmp[i];\n\t\n\t//for(int i = 0; i < 4; ++i) output[i] = State[i + 4];\n\tif(as_uint2(State[7]).s1 <= Target) output[atomic_inc(output + 0xFF)] = BranchBuf[idx] + get_global_offset(0);\n}\n"
  },
  {
    "path": "opencl/groestl256.cl",
    "content": "/* $Id: groestl.c 260 2011-07-21 01:02:38Z tp $ */\n/*\n * Groestl256\n *\n * ==========================(LICENSE BEGIN)============================\n * Copyright (c) 2014 djm34\n * Copyright (c) 2007-2010  Projet RNRT SAPHIR\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n *\n * ===========================(LICENSE END)=============================\n *\n * @author   Thomas Pornin <thomas.pornin@cryptolog.com>\n */\n\n#define SPH_C64(x)\tx\n#define SPH_ROTL64(x, y)\trotate((x), (ulong)(y))\n\n\n#define C64e(x)     ((SPH_C64(x) >> 56) \\\n                    | ((SPH_C64(x) >> 40) & SPH_C64(0x000000000000FF00)) \\\n                    | ((SPH_C64(x) >> 24) & SPH_C64(0x0000000000FF0000)) \\\n                    | ((SPH_C64(x) >>  8) & SPH_C64(0x00000000FF000000)) \\\n                    | ((SPH_C64(x) <<  8) & SPH_C64(0x000000FF00000000)) \\\n                    | ((SPH_C64(x) << 24) & SPH_C64(0x0000FF0000000000)) \\\n                    | ((SPH_C64(x) << 40) & SPH_C64(0x00FF000000000000)) \\\n                    | ((SPH_C64(x) << 56) & SPH_C64(0xFF00000000000000)))\n\n#define B64_0(x)    ((x) & 0xFF)\n#define B64_1(x)    (((x) >> 8) & 0xFF)\n#define B64_2(x)    (((x) >> 16) & 0xFF)\n#define B64_3(x)    (((x) >> 24) & 0xFF)\n#define B64_4(x)    (((x) >> 32) & 0xFF)\n#define B64_5(x)    (((x) >> 40) & 0xFF)\n#define B64_6(x)    (((x) >> 48) & 0xFF)\n#define B64_7(x)    ((x) >> 56)\n#define R64         SPH_ROTL64\n#define PC64(j, r)  ((sph_u64)((j) + (r)))\n#define QC64(j, r)  (((sph_u64)(r) << 56) ^ (~((sph_u64)(j) << 56)))\n\nstatic const __constant ulong T0_G[] =\n{\n\t0xc6a597f4a5f432c6UL, 0xf884eb9784976ff8UL, 0xee99c7b099b05eeeUL, 0xf68df78c8d8c7af6UL, \n\t0xff0de5170d17e8ffUL, 0xd6bdb7dcbddc0ad6UL, 0xdeb1a7c8b1c816deUL, 0x915439fc54fc6d91UL, \n\t0x6050c0f050f09060UL, 0x0203040503050702UL, 0xcea987e0a9e02eceUL, 0x567dac877d87d156UL, \n\t0xe719d52b192bcce7UL, 0xb56271a662a613b5UL, 0x4de69a31e6317c4dUL, 0xec9ac3b59ab559ecUL, \n\t0x8f4505cf45cf408fUL, 0x1f9d3ebc9dbca31fUL, 0x894009c040c04989UL, 0xfa87ef92879268faUL, \n\t0xef15c53f153fd0efUL, 0xb2eb7f26eb2694b2UL, 0x8ec90740c940ce8eUL, 0xfb0bed1d0b1de6fbUL, \n\t0x41ec822fec2f6e41UL, 0xb3677da967a91ab3UL, 0x5ffdbe1cfd1c435fUL, 0x45ea8a25ea256045UL, \n\t0x23bf46dabfdaf923UL, 0x53f7a602f7025153UL, 0xe496d3a196a145e4UL, 0x9b5b2ded5bed769bUL, \n\t0x75c2ea5dc25d2875UL, 0xe11cd9241c24c5e1UL, 0x3dae7ae9aee9d43dUL, 0x4c6a98be6abef24cUL, \n\t0x6c5ad8ee5aee826cUL, 0x7e41fcc341c3bd7eUL, 0xf502f1060206f3f5UL, 0x834f1dd14fd15283UL, \n\t0x685cd0e45ce48c68UL, 0x51f4a207f4075651UL, 0xd134b95c345c8dd1UL, 0xf908e9180818e1f9UL, \n\t0xe293dfae93ae4ce2UL, 0xab734d9573953eabUL, 0x6253c4f553f59762UL, 0x2a3f54413f416b2aUL, \n\t0x080c10140c141c08UL, 0x955231f652f66395UL, 0x46658caf65afe946UL, 0x9d5e21e25ee27f9dUL, \n\t0x3028607828784830UL, 0x37a16ef8a1f8cf37UL, 0x0a0f14110f111b0aUL, 0x2fb55ec4b5c4eb2fUL, \n\t0x0e091c1b091b150eUL, 0x2436485a365a7e24UL, 0x1b9b36b69bb6ad1bUL, 0xdf3da5473d4798dfUL, \n\t0xcd26816a266aa7cdUL, 0x4e699cbb69bbf54eUL, 0x7fcdfe4ccd4c337fUL, 0xea9fcfba9fba50eaUL, \n\t0x121b242d1b2d3f12UL, 0x1d9e3ab99eb9a41dUL, 0x5874b09c749cc458UL, 0x342e68722e724634UL, \n\t0x362d6c772d774136UL, 0xdcb2a3cdb2cd11dcUL, 0xb4ee7329ee299db4UL, 0x5bfbb616fb164d5bUL, \n\t0xa4f65301f601a5a4UL, 0x764decd74dd7a176UL, 0xb76175a361a314b7UL, 0x7dcefa49ce49347dUL, \n\t0x527ba48d7b8ddf52UL, 0xdd3ea1423e429fddUL, 0x5e71bc937193cd5eUL, 0x139726a297a2b113UL, \n\t0xa6f55704f504a2a6UL, 0xb96869b868b801b9UL, 0x0000000000000000UL, 0xc12c99742c74b5c1UL, \n\t0x406080a060a0e040UL, 0xe31fdd211f21c2e3UL, 0x79c8f243c8433a79UL, 0xb6ed772ced2c9ab6UL, \n\t0xd4beb3d9bed90dd4UL, 0x8d4601ca46ca478dUL, 0x67d9ce70d9701767UL, 0x724be4dd4bddaf72UL, \n\t0x94de3379de79ed94UL, 0x98d42b67d467ff98UL, 0xb0e87b23e82393b0UL, 0x854a11de4ade5b85UL, \n\t0xbb6b6dbd6bbd06bbUL, 0xc52a917e2a7ebbc5UL, 0x4fe59e34e5347b4fUL, 0xed16c13a163ad7edUL, \n\t0x86c51754c554d286UL, 0x9ad72f62d762f89aUL, 0x6655ccff55ff9966UL, 0x119422a794a7b611UL, \n\t0x8acf0f4acf4ac08aUL, 0xe910c9301030d9e9UL, 0x0406080a060a0e04UL, 0xfe81e798819866feUL, \n\t0xa0f05b0bf00baba0UL, 0x7844f0cc44ccb478UL, 0x25ba4ad5bad5f025UL, 0x4be3963ee33e754bUL, \n\t0xa2f35f0ef30eaca2UL, 0x5dfeba19fe19445dUL, 0x80c01b5bc05bdb80UL, 0x058a0a858a858005UL, \n\t0x3fad7eecadecd33fUL, 0x21bc42dfbcdffe21UL, 0x7048e0d848d8a870UL, 0xf104f90c040cfdf1UL, \n\t0x63dfc67adf7a1963UL, 0x77c1ee58c1582f77UL, 0xaf75459f759f30afUL, 0x426384a563a5e742UL, \n\t0x2030405030507020UL, 0xe51ad12e1a2ecbe5UL, 0xfd0ee1120e12effdUL, 0xbf6d65b76db708bfUL, \n\t0x814c19d44cd45581UL, 0x1814303c143c2418UL, 0x26354c5f355f7926UL, 0xc32f9d712f71b2c3UL, \n\t0xbee16738e13886beUL, 0x35a26afda2fdc835UL, 0x88cc0b4fcc4fc788UL, 0x2e395c4b394b652eUL, \n\t0x93573df957f96a93UL, 0x55f2aa0df20d5855UL, 0xfc82e39d829d61fcUL, 0x7a47f4c947c9b37aUL, \n\t0xc8ac8befacef27c8UL, 0xbae76f32e73288baUL, 0x322b647d2b7d4f32UL, 0xe695d7a495a442e6UL, \n\t0xc0a09bfba0fb3bc0UL, 0x199832b398b3aa19UL, 0x9ed12768d168f69eUL, 0xa37f5d817f8122a3UL, \n\t0x446688aa66aaee44UL, 0x547ea8827e82d654UL, 0x3bab76e6abe6dd3bUL, 0x0b83169e839e950bUL, \n\t0x8cca0345ca45c98cUL, 0xc729957b297bbcc7UL, 0x6bd3d66ed36e056bUL, 0x283c50443c446c28UL, \n\t0xa779558b798b2ca7UL, 0xbce2633de23d81bcUL, 0x161d2c271d273116UL, 0xad76419a769a37adUL, \n\t0xdb3bad4d3b4d96dbUL, 0x6456c8fa56fa9e64UL, 0x744ee8d24ed2a674UL, 0x141e28221e223614UL, \n\t0x92db3f76db76e492UL, 0x0c0a181e0a1e120cUL, 0x486c90b46cb4fc48UL, 0xb8e46b37e4378fb8UL, \n\t0x9f5d25e75de7789fUL, 0xbd6e61b26eb20fbdUL, 0x43ef862aef2a6943UL, 0xc4a693f1a6f135c4UL, \n\t0x39a872e3a8e3da39UL, 0x31a462f7a4f7c631UL, 0xd337bd5937598ad3UL, 0xf28bff868b8674f2UL, \n\t0xd532b156325683d5UL, 0x8b430dc543c54e8bUL, 0x6e59dceb59eb856eUL, 0xdab7afc2b7c218daUL, \n\t0x018c028f8c8f8e01UL, 0xb16479ac64ac1db1UL, 0x9cd2236dd26df19cUL, 0x49e0923be03b7249UL, \n\t0xd8b4abc7b4c71fd8UL, 0xacfa4315fa15b9acUL, 0xf307fd090709faf3UL, 0xcf25856f256fa0cfUL, \n\t0xcaaf8feaafea20caUL, 0xf48ef3898e897df4UL, 0x47e98e20e9206747UL, 0x1018202818283810UL, \n\t0x6fd5de64d5640b6fUL, 0xf088fb83888373f0UL, 0x4a6f94b16fb1fb4aUL, 0x5c72b8967296ca5cUL, \n\t0x3824706c246c5438UL, 0x57f1ae08f1085f57UL, 0x73c7e652c7522173UL, 0x975135f351f36497UL, \n\t0xcb238d652365aecbUL, 0xa17c59847c8425a1UL, 0xe89ccbbf9cbf57e8UL, 0x3e217c6321635d3eUL, \n\t0x96dd377cdd7cea96UL, 0x61dcc27fdc7f1e61UL, 0x0d861a9186919c0dUL, 0x0f851e9485949b0fUL, \n\t0xe090dbab90ab4be0UL, 0x7c42f8c642c6ba7cUL, 0x71c4e257c4572671UL, 0xccaa83e5aae529ccUL, \n\t0x90d83b73d873e390UL, 0x06050c0f050f0906UL, 0xf701f5030103f4f7UL, 0x1c12383612362a1cUL, \n\t0xc2a39ffea3fe3cc2UL, 0x6a5fd4e15fe18b6aUL, 0xaef94710f910beaeUL, 0x69d0d26bd06b0269UL, \n\t0x17912ea891a8bf17UL, 0x995829e858e87199UL, 0x3a2774692769533aUL, 0x27b94ed0b9d0f727UL, \n\t0xd938a948384891d9UL, 0xeb13cd351335deebUL, 0x2bb356ceb3cee52bUL, 0x2233445533557722UL, \n\t0xd2bbbfd6bbd604d2UL, 0xa9704990709039a9UL, 0x07890e8089808707UL, 0x33a766f2a7f2c133UL, \n\t0x2db65ac1b6c1ec2dUL, 0x3c22786622665a3cUL, 0x15922aad92adb815UL, 0xc92089602060a9c9UL, \n\t0x874915db49db5c87UL, 0xaaff4f1aff1ab0aaUL, 0x5078a0887888d850UL, 0xa57a518e7a8e2ba5UL, \n\t0x038f068a8f8a8903UL, 0x59f8b213f8134a59UL, 0x0980129b809b9209UL, 0x1a1734391739231aUL, \n\t0x65daca75da751065UL, 0xd731b553315384d7UL, 0x84c61351c651d584UL, 0xd0b8bbd3b8d303d0UL, \n\t0x82c31f5ec35edc82UL, 0x29b052cbb0cbe229UL, 0x5a77b4997799c35aUL, 0x1e113c3311332d1eUL, \n\t0x7bcbf646cb463d7bUL, 0xa8fc4b1ffc1fb7a8UL, 0x6dd6da61d6610c6dUL, 0x2c3a584e3a4e622cUL\n};\n\nstatic const __constant ulong T4_G[] =\n{\n\t0xA5F432C6C6A597F4UL, 0x84976FF8F884EB97UL, 0x99B05EEEEE99C7B0UL, 0x8D8C7AF6F68DF78CUL, \n\t0x0D17E8FFFF0DE517UL, 0xBDDC0AD6D6BDB7DCUL, 0xB1C816DEDEB1A7C8UL, 0x54FC6D91915439FCUL, \n\t0x50F090606050C0F0UL, 0x0305070202030405UL, 0xA9E02ECECEA987E0UL, 0x7D87D156567DAC87UL, \n\t0x192BCCE7E719D52BUL, 0x62A613B5B56271A6UL, 0xE6317C4D4DE69A31UL, 0x9AB559ECEC9AC3B5UL, \n\t0x45CF408F8F4505CFUL, 0x9DBCA31F1F9D3EBCUL, 0x40C04989894009C0UL, 0x879268FAFA87EF92UL, \n\t0x153FD0EFEF15C53FUL, 0xEB2694B2B2EB7F26UL, 0xC940CE8E8EC90740UL, 0x0B1DE6FBFB0BED1DUL, \n\t0xEC2F6E4141EC822FUL, 0x67A91AB3B3677DA9UL, 0xFD1C435F5FFDBE1CUL, 0xEA25604545EA8A25UL, \n\t0xBFDAF92323BF46DAUL, 0xF702515353F7A602UL, 0x96A145E4E496D3A1UL, 0x5BED769B9B5B2DEDUL, \n\t0xC25D287575C2EA5DUL, 0x1C24C5E1E11CD924UL, 0xAEE9D43D3DAE7AE9UL, 0x6ABEF24C4C6A98BEUL, \n\t0x5AEE826C6C5AD8EEUL, 0x41C3BD7E7E41FCC3UL, 0x0206F3F5F502F106UL, 0x4FD15283834F1DD1UL, \n\t0x5CE48C68685CD0E4UL, 0xF407565151F4A207UL, 0x345C8DD1D134B95CUL, 0x0818E1F9F908E918UL, \n\t0x93AE4CE2E293DFAEUL, 0x73953EABAB734D95UL, 0x53F597626253C4F5UL, 0x3F416B2A2A3F5441UL, \n\t0x0C141C08080C1014UL, 0x52F66395955231F6UL, 0x65AFE94646658CAFUL, 0x5EE27F9D9D5E21E2UL, \n\t0x2878483030286078UL, 0xA1F8CF3737A16EF8UL, 0x0F111B0A0A0F1411UL, 0xB5C4EB2F2FB55EC4UL, \n\t0x091B150E0E091C1BUL, 0x365A7E242436485AUL, 0x9BB6AD1B1B9B36B6UL, 0x3D4798DFDF3DA547UL, \n\t0x266AA7CDCD26816AUL, 0x69BBF54E4E699CBBUL, 0xCD4C337F7FCDFE4CUL, 0x9FBA50EAEA9FCFBAUL, \n\t0x1B2D3F12121B242DUL, 0x9EB9A41D1D9E3AB9UL, 0x749CC4585874B09CUL, 0x2E724634342E6872UL, \n\t0x2D774136362D6C77UL, 0xB2CD11DCDCB2A3CDUL, 0xEE299DB4B4EE7329UL, 0xFB164D5B5BFBB616UL, \n\t0xF601A5A4A4F65301UL, 0x4DD7A176764DECD7UL, 0x61A314B7B76175A3UL, 0xCE49347D7DCEFA49UL, \n\t0x7B8DDF52527BA48DUL, 0x3E429FDDDD3EA142UL, 0x7193CD5E5E71BC93UL, 0x97A2B113139726A2UL, \n\t0xF504A2A6A6F55704UL, 0x68B801B9B96869B8UL, 0x0000000000000000UL, 0x2C74B5C1C12C9974UL, \n\t0x60A0E040406080A0UL, 0x1F21C2E3E31FDD21UL, 0xC8433A7979C8F243UL, 0xED2C9AB6B6ED772CUL, \n\t0xBED90DD4D4BEB3D9UL, 0x46CA478D8D4601CAUL, 0xD970176767D9CE70UL, 0x4BDDAF72724BE4DDUL, \n\t0xDE79ED9494DE3379UL, 0xD467FF9898D42B67UL, 0xE82393B0B0E87B23UL, 0x4ADE5B85854A11DEUL, \n\t0x6BBD06BBBB6B6DBDUL, 0x2A7EBBC5C52A917EUL, 0xE5347B4F4FE59E34UL, 0x163AD7EDED16C13AUL, \n\t0xC554D28686C51754UL, 0xD762F89A9AD72F62UL, 0x55FF99666655CCFFUL, 0x94A7B611119422A7UL, \n\t0xCF4AC08A8ACF0F4AUL, 0x1030D9E9E910C930UL, 0x060A0E040406080AUL, 0x819866FEFE81E798UL, \n\t0xF00BABA0A0F05B0BUL, 0x44CCB4787844F0CCUL, 0xBAD5F02525BA4AD5UL, 0xE33E754B4BE3963EUL, \n\t0xF30EACA2A2F35F0EUL, 0xFE19445D5DFEBA19UL, 0xC05BDB8080C01B5BUL, 0x8A858005058A0A85UL, \n\t0xADECD33F3FAD7EECUL, 0xBCDFFE2121BC42DFUL, 0x48D8A8707048E0D8UL, 0x040CFDF1F104F90CUL, \n\t0xDF7A196363DFC67AUL, 0xC1582F7777C1EE58UL, 0x759F30AFAF75459FUL, 0x63A5E742426384A5UL, \n\t0x3050702020304050UL, 0x1A2ECBE5E51AD12EUL, 0x0E12EFFDFD0EE112UL, 0x6DB708BFBF6D65B7UL, \n\t0x4CD45581814C19D4UL, 0x143C24181814303CUL, 0x355F792626354C5FUL, 0x2F71B2C3C32F9D71UL, \n\t0xE13886BEBEE16738UL, 0xA2FDC83535A26AFDUL, 0xCC4FC78888CC0B4FUL, 0x394B652E2E395C4BUL, \n\t0x57F96A9393573DF9UL, 0xF20D585555F2AA0DUL, 0x829D61FCFC82E39DUL, 0x47C9B37A7A47F4C9UL, \n\t0xACEF27C8C8AC8BEFUL, 0xE73288BABAE76F32UL, 0x2B7D4F32322B647DUL, 0x95A442E6E695D7A4UL, \n\t0xA0FB3BC0C0A09BFBUL, 0x98B3AA19199832B3UL, 0xD168F69E9ED12768UL, 0x7F8122A3A37F5D81UL, \n\t0x66AAEE44446688AAUL, 0x7E82D654547EA882UL, 0xABE6DD3B3BAB76E6UL, 0x839E950B0B83169EUL, \n\t0xCA45C98C8CCA0345UL, 0x297BBCC7C729957BUL, 0xD36E056B6BD3D66EUL, 0x3C446C28283C5044UL, \n\t0x798B2CA7A779558BUL, 0xE23D81BCBCE2633DUL, 0x1D273116161D2C27UL, 0x769A37ADAD76419AUL, \n\t0x3B4D96DBDB3BAD4DUL, 0x56FA9E646456C8FAUL, 0x4ED2A674744EE8D2UL, 0x1E223614141E2822UL, \n\t0xDB76E49292DB3F76UL, 0x0A1E120C0C0A181EUL, 0x6CB4FC48486C90B4UL, 0xE4378FB8B8E46B37UL, \n\t0x5DE7789F9F5D25E7UL, 0x6EB20FBDBD6E61B2UL, 0xEF2A694343EF862AUL, 0xA6F135C4C4A693F1UL, \n\t0xA8E3DA3939A872E3UL, 0xA4F7C63131A462F7UL, 0x37598AD3D337BD59UL, 0x8B8674F2F28BFF86UL, \n\t0x325683D5D532B156UL, 0x43C54E8B8B430DC5UL, 0x59EB856E6E59DCEBUL, 0xB7C218DADAB7AFC2UL, \n\t0x8C8F8E01018C028FUL, 0x64AC1DB1B16479ACUL, 0xD26DF19C9CD2236DUL, 0xE03B724949E0923BUL, \n\t0xB4C71FD8D8B4ABC7UL, 0xFA15B9ACACFA4315UL, 0x0709FAF3F307FD09UL, 0x256FA0CFCF25856FUL, \n\t0xAFEA20CACAAF8FEAUL, 0x8E897DF4F48EF389UL, 0xE920674747E98E20UL, 0x1828381010182028UL, \n\t0xD5640B6F6FD5DE64UL, 0x888373F0F088FB83UL, 0x6FB1FB4A4A6F94B1UL, 0x7296CA5C5C72B896UL, \n\t0x246C54383824706CUL, 0xF1085F5757F1AE08UL, 0xC752217373C7E652UL, 0x51F36497975135F3UL, \n\t0x2365AECBCB238D65UL, 0x7C8425A1A17C5984UL, 0x9CBF57E8E89CCBBFUL, 0x21635D3E3E217C63UL, \n\t0xDD7CEA9696DD377CUL, 0xDC7F1E6161DCC27FUL, 0x86919C0D0D861A91UL, 0x85949B0F0F851E94UL, \n\t0x90AB4BE0E090DBABUL, 0x42C6BA7C7C42F8C6UL, 0xC457267171C4E257UL, 0xAAE529CCCCAA83E5UL, \n\t0xD873E39090D83B73UL, 0x050F090606050C0FUL, 0x0103F4F7F701F503UL, 0x12362A1C1C123836UL, \n\t0xA3FE3CC2C2A39FFEUL, 0x5FE18B6A6A5FD4E1UL, 0xF910BEAEAEF94710UL, 0xD06B026969D0D26BUL, \n\t0x91A8BF1717912EA8UL, 0x58E87199995829E8UL, 0x2769533A3A277469UL, 0xB9D0F72727B94ED0UL, \n\t0x384891D9D938A948UL, 0x1335DEEBEB13CD35UL, 0xB3CEE52B2BB356CEUL, 0x3355772222334455UL, \n\t0xBBD604D2D2BBBFD6UL, 0x709039A9A9704990UL, 0x8980870707890E80UL, 0xA7F2C13333A766F2UL, \n\t0xB6C1EC2D2DB65AC1UL, 0x22665A3C3C227866UL, 0x92ADB81515922AADUL, 0x2060A9C9C9208960UL, \n\t0x49DB5C87874915DBUL, 0xFF1AB0AAAAFF4F1AUL, 0x7888D8505078A088UL, 0x7A8E2BA5A57A518EUL, \n\t0x8F8A8903038F068AUL, 0xF8134A5959F8B213UL, 0x809B92090980129BUL, 0x1739231A1A173439UL, \n\t0xDA75106565DACA75UL, 0x315384D7D731B553UL, 0xC651D58484C61351UL, 0xB8D303D0D0B8BBD3UL, \n\t0xC35EDC8282C31F5EUL, 0xB0CBE22929B052CBUL, 0x7799C35A5A77B499UL, 0x11332D1E1E113C33UL, \n\t0xCB463D7B7BCBF646UL, 0xFC1FB7A8A8FC4B1FUL, 0xD6610C6D6DD6DA61UL, 0x3A4E622C2C3A584EUL\n};\n\n#define RSTT(d, a, b0, b1, b2, b3, b4, b5, b6, b7)   do { \\\n\t\tt[d] = T0_G[B64_0(a[b0])] \\\n\t\t\t^ R64(T0_G[B64_1(a[b1])],  8) \\\n\t\t\t^ R64(T0_G[B64_2(a[b2])], 16) \\\n\t\t\t^ R64(T0_G[B64_3(a[b3])], 24) \\\n\t\t\t^ T4_G[B64_4(a[b4])] \\\n\t\t\t^ R64(T4_G[B64_5(a[b5])],  8) \\\n\t\t\t^ R64(T4_G[B64_6(a[b6])], 16) \\\n\t\t\t^ R64(T4_G[B64_7(a[b7])], 24); \\\n\t\t} while (0)\n\n#define ROUND_SMALL_P(a, r)   do { \\\n\t\tulong t[8]; \\\n\t\ta[0] ^= PC64(0x00, r); \\\n\t\ta[1] ^= PC64(0x10, r); \\\n\t\ta[2] ^= PC64(0x20, r); \\\n\t\ta[3] ^= PC64(0x30, r); \\\n\t\ta[4] ^= PC64(0x40, r); \\\n\t\ta[5] ^= PC64(0x50, r); \\\n\t\ta[6] ^= PC64(0x60, r); \\\n\t\ta[7] ^= PC64(0x70, r); \\\n\t\tRSTT(0, a, 0, 1, 2, 3, 4, 5, 6, 7); \\\n\t\tRSTT(1, a, 1, 2, 3, 4, 5, 6, 7, 0); \\\n\t\tRSTT(2, a, 2, 3, 4, 5, 6, 7, 0, 1); \\\n\t\tRSTT(3, a, 3, 4, 5, 6, 7, 0, 1, 2); \\\n\t\tRSTT(4, a, 4, 5, 6, 7, 0, 1, 2, 3); \\\n\t\tRSTT(5, a, 5, 6, 7, 0, 1, 2, 3, 4); \\\n\t\tRSTT(6, a, 6, 7, 0, 1, 2, 3, 4, 5); \\\n\t\tRSTT(7, a, 7, 0, 1, 2, 3, 4, 5, 6); \\\n\t\ta[0] = t[0]; \\\n\t\ta[1] = t[1]; \\\n\t\ta[2] = t[2]; \\\n\t\ta[3] = t[3]; \\\n\t\ta[4] = t[4]; \\\n\t\ta[5] = t[5]; \\\n\t\ta[6] = t[6]; \\\n\t\ta[7] = t[7]; \\\n\t\t} while (0)\n\n#define ROUND_SMALL_Pf(a,r)   do { \\\n\t\ta[0] ^= PC64(0x00, r); \\\n\t\ta[1] ^= PC64(0x10, r); \\\n\t\ta[2] ^= PC64(0x20, r); \\\n\t\ta[3] ^= PC64(0x30, r); \\\n\t\ta[4] ^= PC64(0x40, r); \\\n\t\ta[5] ^= PC64(0x50, r); \\\n\t\ta[6] ^= PC64(0x60, r); \\\n\t\ta[7] ^= PC64(0x70, r); \\\n\t\tRSTT(7, a, 7, 0, 1, 2, 3, 4, 5, 6); \\\n\t\ta[7] = t[7]; \\\n\t\t\t} while (0)\n\n#define ROUND_SMALL_Q(a, r)   do { \\\n\t\tulong t[8]; \\\n\t\ta[0] ^= QC64(0x00, r); \\\n\t\ta[1] ^= QC64(0x10, r); \\\n\t\ta[2] ^= QC64(0x20, r); \\\n\t\ta[3] ^= QC64(0x30, r); \\\n\t\ta[4] ^= QC64(0x40, r); \\\n\t\ta[5] ^= QC64(0x50, r); \\\n\t\ta[6] ^= QC64(0x60, r); \\\n\t\ta[7] ^= QC64(0x70, r); \\\n\t\tRSTT(0, a, 1, 3, 5, 7, 0, 2, 4, 6); \\\n\t\tRSTT(1, a, 2, 4, 6, 0, 1, 3, 5, 7); \\\n\t\tRSTT(2, a, 3, 5, 7, 1, 2, 4, 6, 0); \\\n\t\tRSTT(3, a, 4, 6, 0, 2, 3, 5, 7, 1); \\\n\t\tRSTT(4, a, 5, 7, 1, 3, 4, 6, 0, 2); \\\n\t\tRSTT(5, a, 6, 0, 2, 4, 5, 7, 1, 3); \\\n\t\tRSTT(6, a, 7, 1, 3, 5, 6, 0, 2, 4); \\\n\t\tRSTT(7, a, 0, 2, 4, 6, 7, 1, 3, 5); \\\n\t\ta[0] = t[0]; \\\n\t\ta[1] = t[1]; \\\n\t\ta[2] = t[2]; \\\n\t\ta[3] = t[3]; \\\n\t\ta[4] = t[4]; \\\n\t\ta[5] = t[5]; \\\n\t\ta[6] = t[6]; \\\n\t\ta[7] = t[7]; \\\n\t\t} while (0)\n\n#define PERM_SMALL_P(a)   do { \\\n\t\tfor (int r = 0; r < 10; r ++) \\\n\t\t\tROUND_SMALL_P(a, r); \\\n\t\t} while (0)\n\n#define PERM_SMALL_Pf(a)   do { \\\n\t\tfor (int r = 0; r < 9; r ++) { \\\n\t\t\tROUND_SMALL_P(a, r);} \\\n            ROUND_SMALL_Pf(a,9); \\\n\t\t\t} while (0)\n\n#define PERM_SMALL_Q(a)   do { \\\n\t\tfor (int r = 0; r < 10; r ++) \\\n\t\t\tROUND_SMALL_Q(a, r); \\\n\t\t} while (0)\n\n"
  },
  {
    "path": "opencl/jh.cl",
    "content": "/* $Id: jh.c 255 2011-06-07 19:50:20Z tp $ */\n/*\n * JH implementation.\n *\n * ==========================(LICENSE BEGIN)============================\n *\n * Copyright (c) 2007-2010  Projet RNRT SAPHIR\n * \n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n * \n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n *\n * ===========================(LICENSE END)=============================\n *\n * @author   Thomas Pornin <thomas.pornin@cryptolog.com>\n */\n\n#define SPH_JH_64   1\n#define SPH_LITTLE_ENDIAN 1\n\n#define SPH_C32(x)\tx\n#define SPH_C64(x)\tx\ntypedef uint sph_u32;\ntypedef ulong sph_u64;\n\n/*\n * The internal bitslice representation may use either big-endian or\n * little-endian (true bitslice operations do not care about the bit\n * ordering, and the bit-swapping linear operations in JH happen to\n * be invariant through endianness-swapping). The constants must be\n * defined according to the chosen endianness; we use some\n * byte-swapping macros for that.\n */\n\n#if SPH_LITTLE_ENDIAN\n\n#define C32e(x)     ((SPH_C32(x) >> 24) \\\n          | ((SPH_C32(x) >>  8) & SPH_C32(0x0000FF00)) \\\n          | ((SPH_C32(x) <<  8) & SPH_C32(0x00FF0000)) \\\n          | ((SPH_C32(x) << 24) & SPH_C32(0xFF000000)))\n#define dec32e_aligned   sph_dec32le_aligned\n#define enc32e           sph_enc32le\n\n#define C64e(x)     ((SPH_C64(x) >> 56) \\\n          | ((SPH_C64(x) >> 40) & SPH_C64(0x000000000000FF00)) \\\n          | ((SPH_C64(x) >> 24) & SPH_C64(0x0000000000FF0000)) \\\n          | ((SPH_C64(x) >>  8) & SPH_C64(0x00000000FF000000)) \\\n          | ((SPH_C64(x) <<  8) & SPH_C64(0x000000FF00000000)) \\\n          | ((SPH_C64(x) << 24) & SPH_C64(0x0000FF0000000000)) \\\n          | ((SPH_C64(x) << 40) & SPH_C64(0x00FF000000000000)) \\\n          | ((SPH_C64(x) << 56) & SPH_C64(0xFF00000000000000)))\n#define dec64e_aligned   sph_dec64le_aligned\n#define enc64e           sph_enc64le\n\n#else\n\n#define C32e(x)     SPH_C32(x)\n#define dec32e_aligned   sph_dec32be_aligned\n#define enc32e           sph_enc32be\n#define C64e(x)     SPH_C64(x)\n#define dec64e_aligned   sph_dec64be_aligned\n#define enc64e           sph_enc64be\n\n#endif\n\n#define Sb(x0, x1, x2, x3, c)   do { \\\n    x3 = ~x3; \\\n    x0 ^= (c) & ~x2; \\\n    tmp = (c) ^ (x0 & x1); \\\n    x0 ^= x2 & x3; \\\n    x3 ^= ~x1 & x2; \\\n    x1 ^= x0 & x2; \\\n    x2 ^= x0 & ~x3; \\\n    x0 ^= x1 | x3; \\\n    x3 ^= x1 & x2; \\\n    x1 ^= tmp & x0; \\\n    x2 ^= tmp; \\\n  } while (0)\n\n#define Lb(x0, x1, x2, x3, x4, x5, x6, x7)   do { \\\n    x4 ^= x1; \\\n    x5 ^= x2; \\\n    x6 ^= x3 ^ x0; \\\n    x7 ^= x0; \\\n    x0 ^= x5; \\\n    x1 ^= x6; \\\n    x2 ^= x7 ^ x4; \\\n    x3 ^= x4; \\\n  } while (0)\n\nstatic const __constant ulong C[] =\n{\n\t0x67F815DFA2DED572UL, 0x571523B70A15847BUL, 0xF6875A4D90D6AB81UL, 0x402BD1C3C54F9F4EUL, \n\t0x9CFA455CE03A98EAUL, 0x9A99B26699D2C503UL, 0x8A53BBF2B4960266UL, 0x31A2DB881A1456B5UL, \n\t0xDB0E199A5C5AA303UL, 0x1044C1870AB23F40UL, 0x1D959E848019051CUL, 0xDCCDE75EADEB336FUL, \n\t0x416BBF029213BA10UL, 0xD027BBF7156578DCUL, 0x5078AA3739812C0AUL, 0xD3910041D2BF1A3FUL, \n\t0x907ECCF60D5A2D42UL, 0xCE97C0929C9F62DDUL, 0xAC442BC70BA75C18UL, 0x23FCC663D665DFD1UL, \n\t0x1AB8E09E036C6E97UL, 0xA8EC6C447E450521UL, 0xFA618E5DBB03F1EEUL, 0x97818394B29796FDUL, \n\t0x2F3003DB37858E4AUL, 0x956A9FFB2D8D672AUL, 0x6C69B8F88173FE8AUL, 0x14427FC04672C78AUL, \n\t0xC45EC7BD8F15F4C5UL, 0x80BB118FA76F4475UL, 0xBC88E4AEB775DE52UL, 0xF4A3A6981E00B882UL, \n\t0x1563A3A9338FF48EUL, 0x89F9B7D524565FAAUL, 0xFDE05A7C20EDF1B6UL, 0x362C42065AE9CA36UL, \n\t0x3D98FE4E433529CEUL, 0xA74B9A7374F93A53UL, 0x86814E6F591FF5D0UL, 0x9F5AD8AF81AD9D0EUL, \n\t0x6A6234EE670605A7UL, 0x2717B96EBE280B8BUL, 0x3F1080C626077447UL, 0x7B487EC66F7EA0E0UL, \n\t0xC0A4F84AA50A550DUL, 0x9EF18E979FE7E391UL, 0xD48D605081727686UL, 0x62B0E5F3415A9E7EUL, \n\t0x7A205440EC1F9FFCUL, 0x84C9F4CE001AE4E3UL, 0xD895FA9DF594D74FUL, 0xA554C324117E2E55UL, \n\t0x286EFEBD2872DF5BUL, 0xB2C4A50FE27FF578UL, 0x2ED349EEEF7C8905UL, 0x7F5928EB85937E44UL, \n\t0x4A3124B337695F70UL, 0x65E4D61DF128865EUL, 0xE720B95104771BC7UL, 0x8A87D423E843FE74UL, \n\t0xF2947692A3E8297DUL, 0xC1D9309B097ACBDDUL, 0xE01BDC5BFB301B1DUL, 0xBF829CF24F4924DAUL, \n\t0xFFBF70B431BAE7A4UL, 0x48BCF8DE0544320DUL, 0x39D3BB5332FCAE3BUL, 0xA08B29E0C1C39F45UL, \n\t0x0F09AEF7FD05C9E5UL, 0x34F1904212347094UL, 0x95ED44E301B771A2UL, 0x4A982F4F368E3BE9UL, \n\t0x15F66CA0631D4088UL, 0xFFAF52874B44C147UL, 0x30C60AE2F14ABB7EUL, 0xE68C6ECCC5B67046UL, \n\t0x00CA4FBD56A4D5A4UL, 0xAE183EC84B849DDAUL, 0xADD1643045CE5773UL, 0x67255C1468CEA6E8UL, \n\t0x16E10ECBF28CDAA3UL, 0x9A99949A5806E933UL, 0x7B846FC220B2601FUL, 0x1885D1A07FACCED1UL, \n\t0xD319DD8DA15B5932UL, 0x46B4A5AAC01C9A50UL, 0xBA6B04E467633D9FUL, 0x7EEE560BAB19CAF6UL, \n\t0x742128A9EA79B11FUL, 0xEE51363B35F7BDE9UL, 0x76D350755AAC571DUL, 0x01707DA3FEC2463AUL, \n\t0x42D8A498AFC135F7UL, 0x79676B9E20ECED78UL, 0xA8DB3AEA15638341UL, 0x832C83324D3BC3FAUL, \n\t0xF347271C1F3B40A7UL, 0x9A762DB734F04059UL, 0xFD4F21D26C4E3EE7UL, 0xEF5957DC398DFDB8UL, \n\t0xDAEB492B490C9B8DUL, 0x0D70F36849D7A25BUL, 0x84558D7AD0AE3B7DUL, 0x658EF8E4F0E9A5F5UL, \n\t0x533B1036F4A2B8A0UL, 0x5AEC3E759E07A80CUL, 0x4F88E85692946891UL, 0x4CBCBAF8555CB05BUL, \n\t0x7B9487F3993BBBE3UL, 0x5D1C6B72D6F4DA75UL, 0x6DB334DC28ACAE64UL, 0x71DB28B850A5346CUL, \n\t0x2A518D10F2E261F8UL, 0xFC75DD593364DBE3UL, 0xA23FCE43F1BCAC1CUL, 0xB043E8023CD1BB67UL, \n\t0x75A12988CA5B0A33UL, 0x5C5316B44D19347FUL, 0x1E4D790EC3943B92UL, 0x3FAFEEB6D7757479UL, \n\t0x21391ABEF7D4A8EAUL, 0x5127234C097EF45CUL, 0xD23C32BA5324A326UL, 0xADD5A66D4A17A344UL, \n\t0x08C9F2AFA63E1DB5UL, 0x563C6B91983D5983UL, 0x4D608672A17CF84CUL, 0xF6C76E08CC3EE246UL, \n\t0x5E76BCB1B333982FUL, 0x2AE6C4EFA566D62BUL, 0x36D4C1BEE8B6F406UL, 0x6321EFBC1582EE74UL, \n\t0x69C953F40D4EC1FDUL, 0x26585806C45A7DA7UL, 0x16FAE0061614C17EUL, 0x3F9D63283DAF907EUL, \n\t0x0CD29B00E3F2C9D2UL, 0x300CD4B730CEAA5FUL, 0x9832E0F216512A74UL, 0x9AF8CEE3D830EB0DUL, \n\t0x9279F1B57B9EC54BUL, 0xD36886046EE651FFUL, 0x316796E6574D239BUL, 0x05750A17F3A6E6CCUL, \n\t0xCE6C3213D98176B1UL, 0x62A205F88452173CUL, 0x47154778B3CB2BF4UL, 0x486A9323825446FFUL, \n\t0x65655E4E0758DF38UL, 0x8E5086FC897CFCF2UL, 0x86CA0BD0442E7031UL, 0x4E477830A20940F0UL, \n\t0x8338F7D139EEA065UL, 0xBD3A2CE437E95EF7UL, 0x6FF8130126B29721UL, 0xE7DE9FEFD1ED44A3UL, \n\t0xD992257615DFA08BUL, 0xBE42DC12F6F7853CUL, 0x7EB027AB7CECA7D8UL, 0xDEA83EAADA7D8D53UL, \n\t0xD86902BD93CE25AAUL, 0xF908731AFD43F65AUL, 0xA5194A17DAEF5FC0UL, 0x6A21FD4C33664D97UL, \n\t0x701541DB3198B435UL, 0x9B54CDEDBB0F1EEAUL, 0x72409751A163D09AUL, 0xE26F4791BF9D75F6UL\n};\n\n#define Ceven_hi(r)   (C[((r) << 2) + 0])\n#define Ceven_lo(r)   (C[((r) << 2) + 1])\n#define Codd_hi(r)    (C[((r) << 2) + 2])\n#define Codd_lo(r)    (C[((r) << 2) + 3])\n\n#define S(x0, x1, x2, x3, cb, r)   do { \\\n    Sb(x0 ## h, x1 ## h, x2 ## h, x3 ## h, cb ## hi(r)); \\\n    Sb(x0 ## l, x1 ## l, x2 ## l, x3 ## l, cb ## lo(r)); \\\n  } while (0)\n\n#define L(x0, x1, x2, x3, x4, x5, x6, x7)   do { \\\n    Lb(x0 ## h, x1 ## h, x2 ## h, x3 ## h, \\\n      x4 ## h, x5 ## h, x6 ## h, x7 ## h); \\\n    Lb(x0 ## l, x1 ## l, x2 ## l, x3 ## l, \\\n      x4 ## l, x5 ## l, x6 ## l, x7 ## l); \\\n  } while (0)\n\n#define Wz(x, c, n)   do { \\\n    sph_u64 t = (x ## h & (c)) << (n); \\\n    x ## h = ((x ## h >> (n)) & (c)) | t; \\\n    t = (x ## l & (c)) << (n); \\\n    x ## l = ((x ## l >> (n)) & (c)) | t; \\\n  } while (0)\n\n#define W0(x)   Wz(x, SPH_C64(0x5555555555555555),  1)\n#define W1(x)   Wz(x, SPH_C64(0x3333333333333333),  2)\n#define W2(x)   Wz(x, SPH_C64(0x0F0F0F0F0F0F0F0F),  4)\n#define W3(x)   Wz(x, SPH_C64(0x00FF00FF00FF00FF),  8)\n#define W4(x)   Wz(x, SPH_C64(0x0000FFFF0000FFFF), 16)\n#define W5(x)   Wz(x, SPH_C64(0x00000000FFFFFFFF), 32)\n#define W6(x)   do { \\\n    sph_u64 t = x ## h; \\\n    x ## h = x ## l; \\\n    x ## l = t; \\\n  } while (0)\n\n#define SL(ro)   SLu(r + ro, ro)\n\n#define SLu(r, ro)   do { \\\n    S(h0, h2, h4, h6, Ceven_, r); \\\n    S(h1, h3, h5, h7, Codd_, r); \\\n    L(h0, h2, h4, h6, h1, h3, h5, h7); \\\n    W ## ro(h1); \\\n    W ## ro(h3); \\\n    W ## ro(h5); \\\n    W ## ro(h7); \\\n  } while (0)\n\n#if SPH_SMALL_FOOTPRINT_JH\n\n/*\n * The \"small footprint\" 64-bit version just uses a partially unrolled\n * loop.\n */\n\n#define E8   do { \\\n    unsigned r; \\\n    for (r = 0; r < 42; r += 7) { \\\n      SL(0); \\\n      SL(1); \\\n      SL(2); \\\n      SL(3); \\\n      SL(4); \\\n      SL(5); \\\n      SL(6); \\\n    } \\\n  } while (0)\n\n#else\n\n/*\n * On a \"true 64-bit\" architecture, we can unroll at will.\n */\n\n#define E8   do { \\\n    SLu( 0, 0); \\\n    SLu( 1, 1); \\\n    SLu( 2, 2); \\\n    SLu( 3, 3); \\\n    SLu( 4, 4); \\\n    SLu( 5, 5); \\\n    SLu( 6, 6); \\\n    SLu( 7, 0); \\\n    SLu( 8, 1); \\\n    SLu( 9, 2); \\\n    SLu(10, 3); \\\n    SLu(11, 4); \\\n    SLu(12, 5); \\\n    SLu(13, 6); \\\n    SLu(14, 0); \\\n    SLu(15, 1); \\\n    SLu(16, 2); \\\n    SLu(17, 3); \\\n    SLu(18, 4); \\\n    SLu(19, 5); \\\n    SLu(20, 6); \\\n    SLu(21, 0); \\\n    SLu(22, 1); \\\n    SLu(23, 2); \\\n    SLu(24, 3); \\\n    SLu(25, 4); \\\n    SLu(26, 5); \\\n    SLu(27, 6); \\\n    SLu(28, 0); \\\n    SLu(29, 1); \\\n    SLu(30, 2); \\\n    SLu(31, 3); \\\n    SLu(32, 4); \\\n    SLu(33, 5); \\\n    SLu(34, 6); \\\n    SLu(35, 0); \\\n    SLu(36, 1); \\\n    SLu(37, 2); \\\n    SLu(38, 3); \\\n    SLu(39, 4); \\\n    SLu(40, 5); \\\n    SLu(41, 6); \\\n  } while (0)\n\n#endif\n\n"
  },
  {
    "path": "opencl/wolf-aes.cl",
    "content": "#ifndef WOLF_AES_CL\n#define WOLF_AES_CL\n\n// AES table - the other three are generated on the fly\n\nstatic const __constant uint AES0_C[256] =\n{\n\t0xA56363C6U, 0x847C7CF8U, 0x997777EEU, 0x8D7B7BF6U,\n\t0x0DF2F2FFU, 0xBD6B6BD6U, 0xB16F6FDEU, 0x54C5C591U,\n\t0x50303060U, 0x03010102U, 0xA96767CEU, 0x7D2B2B56U,\n\t0x19FEFEE7U, 0x62D7D7B5U, 0xE6ABAB4DU, 0x9A7676ECU,\n\t0x45CACA8FU, 0x9D82821FU, 0x40C9C989U, 0x877D7DFAU,\n\t0x15FAFAEFU, 0xEB5959B2U, 0xC947478EU, 0x0BF0F0FBU,\n\t0xECADAD41U, 0x67D4D4B3U, 0xFDA2A25FU, 0xEAAFAF45U,\n\t0xBF9C9C23U, 0xF7A4A453U, 0x967272E4U, 0x5BC0C09BU,\n\t0xC2B7B775U, 0x1CFDFDE1U, 0xAE93933DU, 0x6A26264CU,\n\t0x5A36366CU, 0x413F3F7EU, 0x02F7F7F5U, 0x4FCCCC83U,\n\t0x5C343468U, 0xF4A5A551U, 0x34E5E5D1U, 0x08F1F1F9U,\n\t0x937171E2U, 0x73D8D8ABU, 0x53313162U, 0x3F15152AU,\n\t0x0C040408U, 0x52C7C795U, 0x65232346U, 0x5EC3C39DU,\n\t0x28181830U, 0xA1969637U, 0x0F05050AU, 0xB59A9A2FU,\n\t0x0907070EU, 0x36121224U, 0x9B80801BU, 0x3DE2E2DFU,\n\t0x26EBEBCDU, 0x6927274EU, 0xCDB2B27FU, 0x9F7575EAU,\n\t0x1B090912U, 0x9E83831DU, 0x742C2C58U, 0x2E1A1A34U,\n\t0x2D1B1B36U, 0xB26E6EDCU, 0xEE5A5AB4U, 0xFBA0A05BU,\n\t0xF65252A4U, 0x4D3B3B76U, 0x61D6D6B7U, 0xCEB3B37DU,\n\t0x7B292952U, 0x3EE3E3DDU, 0x712F2F5EU, 0x97848413U,\n\t0xF55353A6U, 0x68D1D1B9U, 0x00000000U, 0x2CEDEDC1U,\n\t0x60202040U, 0x1FFCFCE3U, 0xC8B1B179U, 0xED5B5BB6U,\n\t0xBE6A6AD4U, 0x46CBCB8DU, 0xD9BEBE67U, 0x4B393972U,\n\t0xDE4A4A94U, 0xD44C4C98U, 0xE85858B0U, 0x4ACFCF85U,\n\t0x6BD0D0BBU, 0x2AEFEFC5U, 0xE5AAAA4FU, 0x16FBFBEDU,\n\t0xC5434386U, 0xD74D4D9AU, 0x55333366U, 0x94858511U,\n\t0xCF45458AU, 0x10F9F9E9U, 0x06020204U, 0x817F7FFEU,\n\t0xF05050A0U, 0x443C3C78U, 0xBA9F9F25U, 0xE3A8A84BU,\n\t0xF35151A2U, 0xFEA3A35DU, 0xC0404080U, 0x8A8F8F05U,\n\t0xAD92923FU, 0xBC9D9D21U, 0x48383870U, 0x04F5F5F1U,\n\t0xDFBCBC63U, 0xC1B6B677U, 0x75DADAAFU, 0x63212142U,\n\t0x30101020U, 0x1AFFFFE5U, 0x0EF3F3FDU, 0x6DD2D2BFU,\n\t0x4CCDCD81U, 0x140C0C18U, 0x35131326U, 0x2FECECC3U,\n\t0xE15F5FBEU, 0xA2979735U, 0xCC444488U, 0x3917172EU,\n\t0x57C4C493U, 0xF2A7A755U, 0x827E7EFCU, 0x473D3D7AU,\n\t0xAC6464C8U, 0xE75D5DBAU, 0x2B191932U, 0x957373E6U,\n\t0xA06060C0U, 0x98818119U, 0xD14F4F9EU, 0x7FDCDCA3U,\n\t0x66222244U, 0x7E2A2A54U, 0xAB90903BU, 0x8388880BU,\n\t0xCA46468CU, 0x29EEEEC7U, 0xD3B8B86BU, 0x3C141428U,\n\t0x79DEDEA7U, 0xE25E5EBCU, 0x1D0B0B16U, 0x76DBDBADU,\n\t0x3BE0E0DBU, 0x56323264U, 0x4E3A3A74U, 0x1E0A0A14U,\n\t0xDB494992U, 0x0A06060CU, 0x6C242448U, 0xE45C5CB8U,\n\t0x5DC2C29FU, 0x6ED3D3BDU, 0xEFACAC43U, 0xA66262C4U,\n\t0xA8919139U, 0xA4959531U, 0x37E4E4D3U, 0x8B7979F2U,\n\t0x32E7E7D5U, 0x43C8C88BU, 0x5937376EU, 0xB76D6DDAU,\n\t0x8C8D8D01U, 0x64D5D5B1U, 0xD24E4E9CU, 0xE0A9A949U,\n\t0xB46C6CD8U, 0xFA5656ACU, 0x07F4F4F3U, 0x25EAEACFU,\n\t0xAF6565CAU, 0x8E7A7AF4U, 0xE9AEAE47U, 0x18080810U,\n\t0xD5BABA6FU, 0x887878F0U, 0x6F25254AU, 0x722E2E5CU,\n\t0x241C1C38U, 0xF1A6A657U, 0xC7B4B473U, 0x51C6C697U,\n\t0x23E8E8CBU, 0x7CDDDDA1U, 0x9C7474E8U, 0x211F1F3EU,\n\t0xDD4B4B96U, 0xDCBDBD61U, 0x868B8B0DU, 0x858A8A0FU,\n\t0x907070E0U, 0x423E3E7CU, 0xC4B5B571U, 0xAA6666CCU,\n\t0xD8484890U, 0x05030306U, 0x01F6F6F7U, 0x120E0E1CU,\n\t0xA36161C2U, 0x5F35356AU, 0xF95757AEU, 0xD0B9B969U,\n\t0x91868617U, 0x58C1C199U, 0x271D1D3AU, 0xB99E9E27U,\n\t0x38E1E1D9U, 0x13F8F8EBU, 0xB398982BU, 0x33111122U,\n\t0xBB6969D2U, 0x70D9D9A9U, 0x898E8E07U, 0xA7949433U,\n\t0xB69B9B2DU, 0x221E1E3CU, 0x92878715U, 0x20E9E9C9U,\n\t0x49CECE87U, 0xFF5555AAU, 0x78282850U, 0x7ADFDFA5U,\n\t0x8F8C8C03U, 0xF8A1A159U, 0x80898909U, 0x170D0D1AU,\n\t0xDABFBF65U, 0x31E6E6D7U, 0xC6424284U, 0xB86868D0U,\n\t0xC3414182U, 0xB0999929U, 0x772D2D5AU, 0x110F0F1EU,\n\t0xCBB0B07BU, 0xFC5454A8U, 0xD6BBBB6DU, 0x3A16162CU\n};\n\n#define BYTE(x, y)\t(amd_bfe((x), (y) << 3U, 8U))\n\nuint4 AES_Round(const __local uint *AES0, const __local uint *AES1, const __local uint *AES2, const __local uint *AES3, const uint4 X, const uint4 key)\n{\n\tuint4 Y;\n\tY.s0 = AES0[BYTE(X.s0, 0)] ^ AES1[BYTE(X.s1, 1)] ^ AES2[BYTE(X.s2, 2)] ^ AES3[BYTE(X.s3, 3)];\n    Y.s1 = AES0[BYTE(X.s1, 0)] ^ AES1[BYTE(X.s2, 1)] ^ AES2[BYTE(X.s3, 2)] ^ AES3[BYTE(X.s0, 3)];\n    Y.s2 = AES0[BYTE(X.s2, 0)] ^ AES1[BYTE(X.s3, 1)] ^ AES2[BYTE(X.s0, 2)] ^ AES3[BYTE(X.s1, 3)];\n    Y.s3 = AES0[BYTE(X.s3, 0)] ^ AES1[BYTE(X.s0, 1)] ^ AES2[BYTE(X.s1, 2)] ^ AES3[BYTE(X.s2, 3)];\n    Y ^= key;\n    return(Y);\n}\n\n#endif\n"
  },
  {
    "path": "opencl/wolf-skein.cl",
    "content": "#ifndef WOLF_SKEIN_CL\n#define WOLF_SKEIN_CL\n\n// Vectorized Skein implementation macros and functions by Wolf\n\n#define SKEIN_KS_PARITY\t0x1BD11BDAA9FC1A22\n\nstatic const __constant ulong SKEIN256_IV[8] =\n{\n\t0xCCD044A12FDB3E13UL, 0xE83590301A79A9EBUL,\n\t0x55AEA0614F816E6FUL, 0x2A2767A4AE9B94DBUL,\n\t0xEC06025E74DD7683UL, 0xE7A436CDC4746251UL,\n\t0xC36FBAF9393AD185UL, 0x3EEDBA1833EDFC13UL\n};\n\nstatic const __constant ulong SKEIN512_256_IV[8] =\n{\n\t0xCCD044A12FDB3E13UL, 0xE83590301A79A9EBUL,\n\t0x55AEA0614F816E6FUL, 0x2A2767A4AE9B94DBUL,\n\t0xEC06025E74DD7683UL, 0xE7A436CDC4746251UL,\n\t0xC36FBAF9393AD185UL, 0x3EEDBA1833EDFC13UL\n};\n\n#define SKEIN_INJECT_KEY(p, s)\tdo { \\\n\tp += h; \\\n\tp.s5 += t[s % 3]; \\\n\tp.s6 += t[(s + 1) % 3]; \\\n\tp.s7 += s; \\\n} while(0)\n\nulong SKEIN_ROT(const uint2 x, const uint y)\n{\n\tif(y < 32) return(as_ulong(amd_bitalign(x, x.s10, 32 - y)));\n\telse return(as_ulong(amd_bitalign(x.s10, x, 32 - (y - 32))));\n}\n\nvoid SkeinMix8(ulong4 *pv0, ulong4 *pv1, const uint rc0, const uint rc1, const uint rc2, const uint rc3)\n{\n\t*pv0 += *pv1;\n\t(*pv1).s0 = SKEIN_ROT(as_uint2((*pv1).s0), rc0);\n\t(*pv1).s1 = SKEIN_ROT(as_uint2((*pv1).s1), rc1);\n\t(*pv1).s2 = SKEIN_ROT(as_uint2((*pv1).s2), rc2);\n\t(*pv1).s3 = SKEIN_ROT(as_uint2((*pv1).s3), rc3);\n\t*pv1 ^= *pv0;\n}\n\nulong8 SkeinEvenRound(ulong8 p, const ulong8 h, const ulong *t, const uint s)\n{\n\tSKEIN_INJECT_KEY(p, s);\n\tulong4 pv0 = p.even, pv1 = p.odd;\n\t\n\tSkeinMix8(&pv0, &pv1, 46, 36, 19, 37);\n\tpv0 = shuffle(pv0, (ulong4)(1, 2, 3, 0));\n\tpv1 = shuffle(pv1, (ulong4)(0, 3, 2, 1));\n\t\n\tSkeinMix8(&pv0, &pv1, 33, 27, 14, 42);\n\tpv0 = shuffle(pv0, (ulong4)(1, 2, 3, 0));\n\tpv1 = shuffle(pv1, (ulong4)(0, 3, 2, 1));\n\t\n\tSkeinMix8(&pv0, &pv1, 17, 49, 36, 39);\n\tpv0 = shuffle(pv0, (ulong4)(1, 2, 3, 0));\n\tpv1 = shuffle(pv1, (ulong4)(0, 3, 2, 1));\n\t\n\tSkeinMix8(&pv0, &pv1, 44, 9, 54, 56);\n\treturn(shuffle2(pv0, pv1, (ulong8)(1, 4, 2, 7, 3, 6, 0, 5)));\n}\n\nulong8 SkeinOddRound(ulong8 p, const ulong8 h, const ulong *t, const uint s)\n{\n\tSKEIN_INJECT_KEY(p, s);\n    ulong4 pv0 = p.even, pv1 = p.odd;\n    \n\tSkeinMix8(&pv0, &pv1, 39, 30, 34, 24);\n\tpv0 = shuffle(pv0, (ulong4)(1, 2, 3, 0));\n\tpv1 = shuffle(pv1, (ulong4)(0, 3, 2, 1));\n\t\n\tSkeinMix8(&pv0, &pv1, 13, 50, 10, 17);\n\tpv0 = shuffle(pv0, (ulong4)(1, 2, 3, 0));\n\tpv1 = shuffle(pv1, (ulong4)(0, 3, 2, 1));\n\t\n\tSkeinMix8(&pv0, &pv1, 25, 29, 39, 43);\n\tpv0 = shuffle(pv0, (ulong4)(1, 2, 3, 0));\n\tpv1 = shuffle(pv1, (ulong4)(0, 3, 2, 1));\n\t\n\tSkeinMix8(&pv0, &pv1, 8, 35, 56, 22);\n\treturn(shuffle2(pv0, pv1, (ulong8)(1, 4, 2, 7, 3, 6, 0, 5)));\n}\n\nulong8 Skein512Block(ulong8 p, ulong8 h, ulong h8, const ulong *t)\n{\n\t#pragma unroll\n\tfor(int i = 0; i < 18; ++i)\n\t{\n\t\tp = SkeinEvenRound(p, h, t, i);\n\t\t++i;\n\t\tulong tmp = h.s0;\n\t\th = shuffle(h, (ulong8)(1, 2, 3, 4, 5, 6, 7, 0));\n\t\th.s7 = h8;\n\t\th8 = tmp;\n\t\tp = SkeinOddRound(p, h, t, i);\n\t\ttmp = h.s0;\n\t\th = shuffle(h, (ulong8)(1, 2, 3, 4, 5, 6, 7, 0));\n\t\th.s7 = h8;\n\t\th8 = tmp;\n\t}\n\t\n\tSKEIN_INJECT_KEY(p, 18);\n\treturn(p);\n}\n\n#endif\n"
  },
  {
    "path": "rapidjson/allocators.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_ALLOCATORS_H_\n#define RAPIDJSON_ALLOCATORS_H_\n\n#include \"rapidjson.h\"\n\nRAPIDJSON_NAMESPACE_BEGIN\n\n///////////////////////////////////////////////////////////////////////////////\n// Allocator\n\n/*! \\class rapidjson::Allocator\n    \\brief Concept for allocating, resizing and freeing memory block.\n    \n    Note that Malloc() and Realloc() are non-static but Free() is static.\n    \n    So if an allocator need to support Free(), it needs to put its pointer in \n    the header of memory block.\n\n\\code\nconcept Allocator {\n    static const bool kNeedFree;    //!< Whether this allocator needs to call Free().\n\n    // Allocate a memory block.\n    // \\param size of the memory block in bytes.\n    // \\returns pointer to the memory block.\n    void* Malloc(size_t size);\n\n    // Resize a memory block.\n    // \\param originalPtr The pointer to current memory block. Null pointer is permitted.\n    // \\param originalSize The current size in bytes. (Design issue: since some allocator may not book-keep this, explicitly pass to it can save memory.)\n    // \\param newSize the new size in bytes.\n    void* Realloc(void* originalPtr, size_t originalSize, size_t newSize);\n\n    // Free a memory block.\n    // \\param pointer to the memory block. Null pointer is permitted.\n    static void Free(void *ptr);\n};\n\\endcode\n*/\n\n///////////////////////////////////////////////////////////////////////////////\n// CrtAllocator\n\n//! C-runtime library allocator.\n/*! This class is just wrapper for standard C library memory routines.\n    \\note implements Allocator concept\n*/\nclass CrtAllocator {\npublic:\n    static const bool kNeedFree = true;\n    void* Malloc(size_t size) { \n        if (size) //  behavior of malloc(0) is implementation defined.\n            return std::malloc(size);\n        else\n            return NULL; // standardize to returning NULL.\n    }\n    void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {\n        (void)originalSize;\n        if (newSize == 0) {\n            std::free(originalPtr);\n            return NULL;\n        }\n        return std::realloc(originalPtr, newSize);\n    }\n    static void Free(void *ptr) { std::free(ptr); }\n};\n\n///////////////////////////////////////////////////////////////////////////////\n// MemoryPoolAllocator\n\n//! Default memory allocator used by the parser and DOM.\n/*! This allocator allocate memory blocks from pre-allocated memory chunks. \n\n    It does not free memory blocks. And Realloc() only allocate new memory.\n\n    The memory chunks are allocated by BaseAllocator, which is CrtAllocator by default.\n\n    User may also supply a buffer as the first chunk.\n\n    If the user-buffer is full then additional chunks are allocated by BaseAllocator.\n\n    The user-buffer is not deallocated by this allocator.\n\n    \\tparam BaseAllocator the allocator type for allocating memory chunks. Default is CrtAllocator.\n    \\note implements Allocator concept\n*/\ntemplate <typename BaseAllocator = CrtAllocator>\nclass MemoryPoolAllocator {\npublic:\n    static const bool kNeedFree = false;    //!< Tell users that no need to call Free() with this allocator. (concept Allocator)\n\n    //! Constructor with chunkSize.\n    /*! \\param chunkSize The size of memory chunk. The default is kDefaultChunkSize.\n        \\param baseAllocator The allocator for allocating memory chunks.\n    */\n    MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) : \n        chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(0), baseAllocator_(baseAllocator), ownBaseAllocator_(0)\n    {\n    }\n\n    //! Constructor with user-supplied buffer.\n    /*! The user buffer will be used firstly. When it is full, memory pool allocates new chunk with chunk size.\n\n        The user buffer will not be deallocated when this allocator is destructed.\n\n        \\param buffer User supplied buffer.\n        \\param size Size of the buffer in bytes. It must at least larger than sizeof(ChunkHeader).\n        \\param chunkSize The size of memory chunk. The default is kDefaultChunkSize.\n        \\param baseAllocator The allocator for allocating memory chunks.\n    */\n    MemoryPoolAllocator(void *buffer, size_t size, size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :\n        chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(buffer), baseAllocator_(baseAllocator), ownBaseAllocator_(0)\n    {\n        RAPIDJSON_ASSERT(buffer != 0);\n        RAPIDJSON_ASSERT(size > sizeof(ChunkHeader));\n        chunkHead_ = reinterpret_cast<ChunkHeader*>(buffer);\n        chunkHead_->capacity = size - sizeof(ChunkHeader);\n        chunkHead_->size = 0;\n        chunkHead_->next = 0;\n    }\n\n    //! Destructor.\n    /*! This deallocates all memory chunks, excluding the user-supplied buffer.\n    */\n    ~MemoryPoolAllocator() {\n        Clear();\n        RAPIDJSON_DELETE(ownBaseAllocator_);\n    }\n\n    //! Deallocates all memory chunks, excluding the user-supplied buffer.\n    void Clear() {\n        while (chunkHead_ && chunkHead_ != userBuffer_) {\n            ChunkHeader* next = chunkHead_->next;\n            baseAllocator_->Free(chunkHead_);\n            chunkHead_ = next;\n        }\n        if (chunkHead_ && chunkHead_ == userBuffer_)\n            chunkHead_->size = 0; // Clear user buffer\n    }\n\n    //! Computes the total capacity of allocated memory chunks.\n    /*! \\return total capacity in bytes.\n    */\n    size_t Capacity() const {\n        size_t capacity = 0;\n        for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)\n            capacity += c->capacity;\n        return capacity;\n    }\n\n    //! Computes the memory blocks allocated.\n    /*! \\return total used bytes.\n    */\n    size_t Size() const {\n        size_t size = 0;\n        for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)\n            size += c->size;\n        return size;\n    }\n\n    //! Allocates a memory block. (concept Allocator)\n    void* Malloc(size_t size) {\n        if (!size)\n            return NULL;\n\n        size = RAPIDJSON_ALIGN(size);\n        if (chunkHead_ == 0 || chunkHead_->size + size > chunkHead_->capacity)\n            if (!AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size))\n                return NULL;\n\n        void *buffer = reinterpret_cast<char *>(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size;\n        chunkHead_->size += size;\n        return buffer;\n    }\n\n    //! Resizes a memory block (concept Allocator)\n    void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {\n        if (originalPtr == 0)\n            return Malloc(newSize);\n\n        if (newSize == 0)\n            return NULL;\n\n        originalSize = RAPIDJSON_ALIGN(originalSize);\n        newSize = RAPIDJSON_ALIGN(newSize);\n\n        // Do not shrink if new size is smaller than original\n        if (originalSize >= newSize)\n            return originalPtr;\n\n        // Simply expand it if it is the last allocation and there is sufficient space\n        if (originalPtr == reinterpret_cast<char *>(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size - originalSize) {\n            size_t increment = static_cast<size_t>(newSize - originalSize);\n            if (chunkHead_->size + increment <= chunkHead_->capacity) {\n                chunkHead_->size += increment;\n                return originalPtr;\n            }\n        }\n\n        // Realloc process: allocate and copy memory, do not free original buffer.\n        if (void* newBuffer = Malloc(newSize)) {\n            if (originalSize)\n                std::memcpy(newBuffer, originalPtr, originalSize);\n            return newBuffer;\n        }\n        else\n            return NULL;\n    }\n\n    //! Frees a memory block (concept Allocator)\n    static void Free(void *ptr) { (void)ptr; } // Do nothing\n\nprivate:\n    //! Copy constructor is not permitted.\n    MemoryPoolAllocator(const MemoryPoolAllocator& rhs) /* = delete */;\n    //! Copy assignment operator is not permitted.\n    MemoryPoolAllocator& operator=(const MemoryPoolAllocator& rhs) /* = delete */;\n\n    //! Creates a new chunk.\n    /*! \\param capacity Capacity of the chunk in bytes.\n        \\return true if success.\n    */\n    bool AddChunk(size_t capacity) {\n        if (!baseAllocator_)\n            ownBaseAllocator_ = baseAllocator_ = RAPIDJSON_NEW(BaseAllocator());\n        if (ChunkHeader* chunk = reinterpret_cast<ChunkHeader*>(baseAllocator_->Malloc(RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + capacity))) {\n            chunk->capacity = capacity;\n            chunk->size = 0;\n            chunk->next = chunkHead_;\n            chunkHead_ =  chunk;\n            return true;\n        }\n        else\n            return false;\n    }\n\n    static const int kDefaultChunkCapacity = 64 * 1024; //!< Default chunk capacity.\n\n    //! Chunk header for perpending to each chunk.\n    /*! Chunks are stored as a singly linked list.\n    */\n    struct ChunkHeader {\n        size_t capacity;    //!< Capacity of the chunk in bytes (excluding the header itself).\n        size_t size;        //!< Current size of allocated memory in bytes.\n        ChunkHeader *next;  //!< Next chunk in the linked list.\n    };\n\n    ChunkHeader *chunkHead_;    //!< Head of the chunk linked-list. Only the head chunk serves allocation.\n    size_t chunk_capacity_;     //!< The minimum capacity of chunk when they are allocated.\n    void *userBuffer_;          //!< User supplied buffer.\n    BaseAllocator* baseAllocator_;  //!< base allocator for allocating memory chunks.\n    BaseAllocator* ownBaseAllocator_;   //!< base allocator created by this object.\n};\n\nRAPIDJSON_NAMESPACE_END\n\n#endif // RAPIDJSON_ENCODINGS_H_\n"
  },
  {
    "path": "rapidjson/document.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_DOCUMENT_H_\n#define RAPIDJSON_DOCUMENT_H_\n\n/*! \\file document.h */\n\n#include \"reader.h\"\n#include \"internal/meta.h\"\n#include \"internal/strfunc.h\"\n#include \"memorystream.h\"\n#include \"encodedstream.h\"\n#include <new>      // placement new\n#include <limits>\n\nRAPIDJSON_DIAG_PUSH\n#ifdef _MSC_VER\nRAPIDJSON_DIAG_OFF(4127) // conditional expression is constant\nRAPIDJSON_DIAG_OFF(4244) // conversion from kXxxFlags to 'uint16_t', possible loss of data\n#ifdef _MINWINDEF_       // see: http://stackoverflow.com/questions/22744262/cant-call-stdmax-because-minwindef-h-defines-max\n#ifndef NOMINMAX\n#pragma push_macro(\"min\")\n#pragma push_macro(\"max\")\n#undef min\n#undef max\n#endif\n#endif\n#endif\n\n#ifdef __clang__\nRAPIDJSON_DIAG_OFF(padded)\nRAPIDJSON_DIAG_OFF(switch-enum)\nRAPIDJSON_DIAG_OFF(c++98-compat)\n#endif\n\n#ifdef __GNUC__\nRAPIDJSON_DIAG_OFF(effc++)\n#if __GNUC__ >= 6\nRAPIDJSON_DIAG_OFF(terminate) // ignore throwing RAPIDJSON_ASSERT in RAPIDJSON_NOEXCEPT functions\n#endif\n#endif // __GNUC__\n\n#ifndef RAPIDJSON_NOMEMBERITERATORCLASS\n#include <iterator> // std::iterator, std::random_access_iterator_tag\n#endif\n\n#if RAPIDJSON_HAS_CXX11_RVALUE_REFS\n#include <utility> // std::move\n#endif\n\nRAPIDJSON_NAMESPACE_BEGIN\n\n// Forward declaration.\ntemplate <typename Encoding, typename Allocator>\nclass GenericValue;\n\ntemplate <typename Encoding, typename Allocator, typename StackAllocator>\nclass GenericDocument;\n\n//! Name-value pair in a JSON object value.\n/*!\n    This class was internal to GenericValue. It used to be a inner struct.\n    But a compiler (IBM XL C/C++ for AIX) have reported to have problem with that so it moved as a namespace scope struct.\n    https://code.google.com/p/rapidjson/issues/detail?id=64\n*/\ntemplate <typename Encoding, typename Allocator> \nstruct GenericMember { \n    GenericValue<Encoding, Allocator> name;     //!< name of member (must be a string)\n    GenericValue<Encoding, Allocator> value;    //!< value of member.\n};\n\n///////////////////////////////////////////////////////////////////////////////\n// GenericMemberIterator\n\n#ifndef RAPIDJSON_NOMEMBERITERATORCLASS\n\n//! (Constant) member iterator for a JSON object value\n/*!\n    \\tparam Const Is this a constant iterator?\n    \\tparam Encoding    Encoding of the value. (Even non-string values need to have the same encoding in a document)\n    \\tparam Allocator   Allocator type for allocating memory of object, array and string.\n\n    This class implements a Random Access Iterator for GenericMember elements\n    of a GenericValue, see ISO/IEC 14882:2003(E) C++ standard, 24.1 [lib.iterator.requirements].\n\n    \\note This iterator implementation is mainly intended to avoid implicit\n        conversions from iterator values to \\c NULL,\n        e.g. from GenericValue::FindMember.\n\n    \\note Define \\c RAPIDJSON_NOMEMBERITERATORCLASS to fall back to a\n        pointer-based implementation, if your platform doesn't provide\n        the C++ <iterator> header.\n\n    \\see GenericMember, GenericValue::MemberIterator, GenericValue::ConstMemberIterator\n */\ntemplate <bool Const, typename Encoding, typename Allocator>\nclass GenericMemberIterator\n    : public std::iterator<std::random_access_iterator_tag\n        , typename internal::MaybeAddConst<Const,GenericMember<Encoding,Allocator> >::Type> {\n\n    friend class GenericValue<Encoding,Allocator>;\n    template <bool, typename, typename> friend class GenericMemberIterator;\n\n    typedef GenericMember<Encoding,Allocator> PlainType;\n    typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;\n    typedef std::iterator<std::random_access_iterator_tag,ValueType> BaseType;\n\npublic:\n    //! Iterator type itself\n    typedef GenericMemberIterator Iterator;\n    //! Constant iterator type\n    typedef GenericMemberIterator<true,Encoding,Allocator>  ConstIterator;\n    //! Non-constant iterator type\n    typedef GenericMemberIterator<false,Encoding,Allocator> NonConstIterator;\n\n    //! Pointer to (const) GenericMember\n    typedef typename BaseType::pointer         Pointer;\n    //! Reference to (const) GenericMember\n    typedef typename BaseType::reference       Reference;\n    //! Signed integer type (e.g. \\c ptrdiff_t)\n    typedef typename BaseType::difference_type DifferenceType;\n\n    //! Default constructor (singular value)\n    /*! Creates an iterator pointing to no element.\n        \\note All operations, except for comparisons, are undefined on such values.\n     */\n    GenericMemberIterator() : ptr_() {}\n\n    //! Iterator conversions to more const\n    /*!\n        \\param it (Non-const) iterator to copy from\n\n        Allows the creation of an iterator from another GenericMemberIterator\n        that is \"less const\".  Especially, creating a non-constant iterator\n        from a constant iterator are disabled:\n        \\li const -> non-const (not ok)\n        \\li const -> const (ok)\n        \\li non-const -> const (ok)\n        \\li non-const -> non-const (ok)\n\n        \\note If the \\c Const template parameter is already \\c false, this\n            constructor effectively defines a regular copy-constructor.\n            Otherwise, the copy constructor is implicitly defined.\n    */\n    GenericMemberIterator(const NonConstIterator & it) : ptr_(it.ptr_) {}\n    Iterator& operator=(const NonConstIterator & it) { ptr_ = it.ptr_; return *this; }\n\n    //! @name stepping\n    //@{\n    Iterator& operator++(){ ++ptr_; return *this; }\n    Iterator& operator--(){ --ptr_; return *this; }\n    Iterator  operator++(int){ Iterator old(*this); ++ptr_; return old; }\n    Iterator  operator--(int){ Iterator old(*this); --ptr_; return old; }\n    //@}\n\n    //! @name increment/decrement\n    //@{\n    Iterator operator+(DifferenceType n) const { return Iterator(ptr_+n); }\n    Iterator operator-(DifferenceType n) const { return Iterator(ptr_-n); }\n\n    Iterator& operator+=(DifferenceType n) { ptr_+=n; return *this; }\n    Iterator& operator-=(DifferenceType n) { ptr_-=n; return *this; }\n    //@}\n\n    //! @name relations\n    //@{\n    bool operator==(ConstIterator that) const { return ptr_ == that.ptr_; }\n    bool operator!=(ConstIterator that) const { return ptr_ != that.ptr_; }\n    bool operator<=(ConstIterator that) const { return ptr_ <= that.ptr_; }\n    bool operator>=(ConstIterator that) const { return ptr_ >= that.ptr_; }\n    bool operator< (ConstIterator that) const { return ptr_ < that.ptr_; }\n    bool operator> (ConstIterator that) const { return ptr_ > that.ptr_; }\n    //@}\n\n    //! @name dereference\n    //@{\n    Reference operator*() const { return *ptr_; }\n    Pointer   operator->() const { return ptr_; }\n    Reference operator[](DifferenceType n) const { return ptr_[n]; }\n    //@}\n\n    //! Distance\n    DifferenceType operator-(ConstIterator that) const { return ptr_-that.ptr_; }\n\nprivate:\n    //! Internal constructor from plain pointer\n    explicit GenericMemberIterator(Pointer p) : ptr_(p) {}\n\n    Pointer ptr_; //!< raw pointer\n};\n\n#else // RAPIDJSON_NOMEMBERITERATORCLASS\n\n// class-based member iterator implementation disabled, use plain pointers\n\ntemplate <bool Const, typename Encoding, typename Allocator>\nstruct GenericMemberIterator;\n\n//! non-const GenericMemberIterator\ntemplate <typename Encoding, typename Allocator>\nstruct GenericMemberIterator<false,Encoding,Allocator> {\n    //! use plain pointer as iterator type\n    typedef GenericMember<Encoding,Allocator>* Iterator;\n};\n//! const GenericMemberIterator\ntemplate <typename Encoding, typename Allocator>\nstruct GenericMemberIterator<true,Encoding,Allocator> {\n    //! use plain const pointer as iterator type\n    typedef const GenericMember<Encoding,Allocator>* Iterator;\n};\n\n#endif // RAPIDJSON_NOMEMBERITERATORCLASS\n\n///////////////////////////////////////////////////////////////////////////////\n// GenericStringRef\n\n//! Reference to a constant string (not taking a copy)\n/*!\n    \\tparam CharType character type of the string\n\n    This helper class is used to automatically infer constant string\n    references for string literals, especially from \\c const \\b (!)\n    character arrays.\n\n    The main use is for creating JSON string values without copying the\n    source string via an \\ref Allocator.  This requires that the referenced\n    string pointers have a sufficient lifetime, which exceeds the lifetime\n    of the associated GenericValue.\n\n    \\b Example\n    \\code\n    Value v(\"foo\");   // ok, no need to copy & calculate length\n    const char foo[] = \"foo\";\n    v.SetString(foo); // ok\n\n    const char* bar = foo;\n    // Value x(bar); // not ok, can't rely on bar's lifetime\n    Value x(StringRef(bar)); // lifetime explicitly guaranteed by user\n    Value y(StringRef(bar, 3));  // ok, explicitly pass length\n    \\endcode\n\n    \\see StringRef, GenericValue::SetString\n*/\ntemplate<typename CharType>\nstruct GenericStringRef {\n    typedef CharType Ch; //!< character type of the string\n\n    //! Create string reference from \\c const character array\n#ifndef __clang__ // -Wdocumentation\n    /*!\n        This constructor implicitly creates a constant string reference from\n        a \\c const character array.  It has better performance than\n        \\ref StringRef(const CharType*) by inferring the string \\ref length\n        from the array length, and also supports strings containing null\n        characters.\n\n        \\tparam N length of the string, automatically inferred\n\n        \\param str Constant character array, lifetime assumed to be longer\n            than the use of the string in e.g. a GenericValue\n\n        \\post \\ref s == str\n\n        \\note Constant complexity.\n        \\note There is a hidden, private overload to disallow references to\n            non-const character arrays to be created via this constructor.\n            By this, e.g. function-scope arrays used to be filled via\n            \\c snprintf are excluded from consideration.\n            In such cases, the referenced string should be \\b copied to the\n            GenericValue instead.\n     */\n#endif\n    template<SizeType N>\n    GenericStringRef(const CharType (&str)[N]) RAPIDJSON_NOEXCEPT\n        : s(str), length(N-1) {}\n\n    //! Explicitly create string reference from \\c const character pointer\n#ifndef __clang__ // -Wdocumentation\n    /*!\n        This constructor can be used to \\b explicitly  create a reference to\n        a constant string pointer.\n\n        \\see StringRef(const CharType*)\n\n        \\param str Constant character pointer, lifetime assumed to be longer\n            than the use of the string in e.g. a GenericValue\n\n        \\post \\ref s == str\n\n        \\note There is a hidden, private overload to disallow references to\n            non-const character arrays to be created via this constructor.\n            By this, e.g. function-scope arrays used to be filled via\n            \\c snprintf are excluded from consideration.\n            In such cases, the referenced string should be \\b copied to the\n            GenericValue instead.\n     */\n#endif\n    explicit GenericStringRef(const CharType* str)\n        : s(str), length(internal::StrLen(str)){ RAPIDJSON_ASSERT(s != 0); }\n\n    //! Create constant string reference from pointer and length\n#ifndef __clang__ // -Wdocumentation\n    /*! \\param str constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue\n        \\param len length of the string, excluding the trailing NULL terminator\n\n        \\post \\ref s == str && \\ref length == len\n        \\note Constant complexity.\n     */\n#endif\n    GenericStringRef(const CharType* str, SizeType len)\n        : s(str), length(len) { RAPIDJSON_ASSERT(s != 0); }\n\n    GenericStringRef(const GenericStringRef& rhs) : s(rhs.s), length(rhs.length) {}\n\n    //! implicit conversion to plain CharType pointer\n    operator const Ch *() const { return s; }\n\n    const Ch* const s; //!< plain CharType pointer\n    const SizeType length; //!< length of the string (excluding the trailing NULL terminator)\n\nprivate:\n    //! Disallow construction from non-const array\n    template<SizeType N>\n    GenericStringRef(CharType (&str)[N]) /* = delete */;\n    //! Copy assignment operator not permitted - immutable type\n    GenericStringRef& operator=(const GenericStringRef& rhs) /* = delete */;\n};\n\n//! Mark a character pointer as constant string\n/*! Mark a plain character pointer as a \"string literal\".  This function\n    can be used to avoid copying a character string to be referenced as a\n    value in a JSON GenericValue object, if the string's lifetime is known\n    to be valid long enough.\n    \\tparam CharType Character type of the string\n    \\param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue\n    \\return GenericStringRef string reference object\n    \\relatesalso GenericStringRef\n\n    \\see GenericValue::GenericValue(StringRefType), GenericValue::operator=(StringRefType), GenericValue::SetString(StringRefType), GenericValue::PushBack(StringRefType, Allocator&), GenericValue::AddMember\n*/\ntemplate<typename CharType>\ninline GenericStringRef<CharType> StringRef(const CharType* str) {\n    return GenericStringRef<CharType>(str, internal::StrLen(str));\n}\n\n//! Mark a character pointer as constant string\n/*! Mark a plain character pointer as a \"string literal\".  This function\n    can be used to avoid copying a character string to be referenced as a\n    value in a JSON GenericValue object, if the string's lifetime is known\n    to be valid long enough.\n\n    This version has better performance with supplied length, and also\n    supports string containing null characters.\n\n    \\tparam CharType character type of the string\n    \\param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue\n    \\param length The length of source string.\n    \\return GenericStringRef string reference object\n    \\relatesalso GenericStringRef\n*/\ntemplate<typename CharType>\ninline GenericStringRef<CharType> StringRef(const CharType* str, size_t length) {\n    return GenericStringRef<CharType>(str, SizeType(length));\n}\n\n#if RAPIDJSON_HAS_STDSTRING\n//! Mark a string object as constant string\n/*! Mark a string object (e.g. \\c std::string) as a \"string literal\".\n    This function can be used to avoid copying a string to be referenced as a\n    value in a JSON GenericValue object, if the string's lifetime is known\n    to be valid long enough.\n\n    \\tparam CharType character type of the string\n    \\param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue\n    \\return GenericStringRef string reference object\n    \\relatesalso GenericStringRef\n    \\note Requires the definition of the preprocessor symbol \\ref RAPIDJSON_HAS_STDSTRING.\n*/\ntemplate<typename CharType>\ninline GenericStringRef<CharType> StringRef(const std::basic_string<CharType>& str) {\n    return GenericStringRef<CharType>(str.data(), SizeType(str.size()));\n}\n#endif\n\n///////////////////////////////////////////////////////////////////////////////\n// GenericValue type traits\nnamespace internal {\n\ntemplate <typename T, typename Encoding = void, typename Allocator = void>\nstruct IsGenericValueImpl : FalseType {};\n\n// select candidates according to nested encoding and allocator types\ntemplate <typename T> struct IsGenericValueImpl<T, typename Void<typename T::EncodingType>::Type, typename Void<typename T::AllocatorType>::Type>\n    : IsBaseOf<GenericValue<typename T::EncodingType, typename T::AllocatorType>, T>::Type {};\n\n// helper to match arbitrary GenericValue instantiations, including derived classes\ntemplate <typename T> struct IsGenericValue : IsGenericValueImpl<T>::Type {};\n\n} // namespace internal\n\n///////////////////////////////////////////////////////////////////////////////\n// TypeHelper\n\nnamespace internal {\n\ntemplate <typename ValueType, typename T>\nstruct TypeHelper {};\n\ntemplate<typename ValueType> \nstruct TypeHelper<ValueType, bool> {\n    static bool Is(const ValueType& v) { return v.IsBool(); }\n    static bool Get(const ValueType& v) { return v.GetBool(); }\n    static ValueType& Set(ValueType& v, bool data) { return v.SetBool(data); }\n    static ValueType& Set(ValueType& v, bool data, typename ValueType::AllocatorType&) { return v.SetBool(data); }\n};\n\ntemplate<typename ValueType> \nstruct TypeHelper<ValueType, int> {\n    static bool Is(const ValueType& v) { return v.IsInt(); }\n    static int Get(const ValueType& v) { return v.GetInt(); }\n    static ValueType& Set(ValueType& v, int data) { return v.SetInt(data); }\n    static ValueType& Set(ValueType& v, int data, typename ValueType::AllocatorType&) { return v.SetInt(data); }\n};\n\ntemplate<typename ValueType> \nstruct TypeHelper<ValueType, unsigned> {\n    static bool Is(const ValueType& v) { return v.IsUint(); }\n    static unsigned Get(const ValueType& v) { return v.GetUint(); }\n    static ValueType& Set(ValueType& v, unsigned data) { return v.SetUint(data); }\n    static ValueType& Set(ValueType& v, unsigned data, typename ValueType::AllocatorType&) { return v.SetUint(data); }\n};\n\ntemplate<typename ValueType> \nstruct TypeHelper<ValueType, int64_t> {\n    static bool Is(const ValueType& v) { return v.IsInt64(); }\n    static int64_t Get(const ValueType& v) { return v.GetInt64(); }\n    static ValueType& Set(ValueType& v, int64_t data) { return v.SetInt64(data); }\n    static ValueType& Set(ValueType& v, int64_t data, typename ValueType::AllocatorType&) { return v.SetInt64(data); }\n};\n\ntemplate<typename ValueType> \nstruct TypeHelper<ValueType, uint64_t> {\n    static bool Is(const ValueType& v) { return v.IsUint64(); }\n    static uint64_t Get(const ValueType& v) { return v.GetUint64(); }\n    static ValueType& Set(ValueType& v, uint64_t data) { return v.SetUint64(data); }\n    static ValueType& Set(ValueType& v, uint64_t data, typename ValueType::AllocatorType&) { return v.SetUint64(data); }\n};\n\ntemplate<typename ValueType> \nstruct TypeHelper<ValueType, double> {\n    static bool Is(const ValueType& v) { return v.IsDouble(); }\n    static double Get(const ValueType& v) { return v.GetDouble(); }\n    static ValueType& Set(ValueType& v, double data) { return v.SetDouble(data); }\n    static ValueType& Set(ValueType& v, double data, typename ValueType::AllocatorType&) { return v.SetDouble(data); }\n};\n\ntemplate<typename ValueType> \nstruct TypeHelper<ValueType, float> {\n    static bool Is(const ValueType& v) { return v.IsFloat(); }\n    static float Get(const ValueType& v) { return v.GetFloat(); }\n    static ValueType& Set(ValueType& v, float data) { return v.SetFloat(data); }\n    static ValueType& Set(ValueType& v, float data, typename ValueType::AllocatorType&) { return v.SetFloat(data); }\n};\n\ntemplate<typename ValueType> \nstruct TypeHelper<ValueType, const typename ValueType::Ch*> {\n    typedef const typename ValueType::Ch* StringType;\n    static bool Is(const ValueType& v) { return v.IsString(); }\n    static StringType Get(const ValueType& v) { return v.GetString(); }\n    static ValueType& Set(ValueType& v, const StringType data) { return v.SetString(typename ValueType::StringRefType(data)); }\n    static ValueType& Set(ValueType& v, const StringType data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); }\n};\n\n#if RAPIDJSON_HAS_STDSTRING\ntemplate<typename ValueType> \nstruct TypeHelper<ValueType, std::basic_string<typename ValueType::Ch> > {\n    typedef std::basic_string<typename ValueType::Ch> StringType;\n    static bool Is(const ValueType& v) { return v.IsString(); }\n    static StringType Get(const ValueType& v) { return StringType(v.GetString(), v.GetStringLength()); }\n    static ValueType& Set(ValueType& v, const StringType& data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); }\n};\n#endif\n\ntemplate<typename ValueType> \nstruct TypeHelper<ValueType, typename ValueType::Array> {\n    typedef typename ValueType::Array ArrayType;\n    static bool Is(const ValueType& v) { return v.IsArray(); }\n    static ArrayType Get(ValueType& v) { return v.GetArray(); }\n    static ValueType& Set(ValueType& v, ArrayType data) { return v = data; }\n    static ValueType& Set(ValueType& v, ArrayType data, typename ValueType::AllocatorType&) { return v = data; }\n};\n\ntemplate<typename ValueType> \nstruct TypeHelper<ValueType, typename ValueType::ConstArray> {\n    typedef typename ValueType::ConstArray ArrayType;\n    static bool Is(const ValueType& v) { return v.IsArray(); }\n    static ArrayType Get(const ValueType& v) { return v.GetArray(); }\n};\n\ntemplate<typename ValueType> \nstruct TypeHelper<ValueType, typename ValueType::Object> {\n    typedef typename ValueType::Object ObjectType;\n    static bool Is(const ValueType& v) { return v.IsObject(); }\n    static ObjectType Get(ValueType& v) { return v.GetObject(); }\n    static ValueType& Set(ValueType& v, ObjectType data) { return v = data; }\n    static ValueType& Set(ValueType& v, ObjectType data, typename ValueType::AllocatorType&) { v = data; }\n};\n\ntemplate<typename ValueType> \nstruct TypeHelper<ValueType, typename ValueType::ConstObject> {\n    typedef typename ValueType::ConstObject ObjectType;\n    static bool Is(const ValueType& v) { return v.IsObject(); }\n    static ObjectType Get(const ValueType& v) { return v.GetObject(); }\n};\n\n} // namespace internal\n\n// Forward declarations\ntemplate <bool, typename> class GenericArray;\ntemplate <bool, typename> class GenericObject;\n\n///////////////////////////////////////////////////////////////////////////////\n// GenericValue\n\n//! Represents a JSON value. Use Value for UTF8 encoding and default allocator.\n/*!\n    A JSON value can be one of 7 types. This class is a variant type supporting\n    these types.\n\n    Use the Value if UTF8 and default allocator\n\n    \\tparam Encoding    Encoding of the value. (Even non-string values need to have the same encoding in a document)\n    \\tparam Allocator   Allocator type for allocating memory of object, array and string.\n*/\ntemplate <typename Encoding, typename Allocator = MemoryPoolAllocator<> > \nclass GenericValue {\npublic:\n    //! Name-value pair in an object.\n    typedef GenericMember<Encoding, Allocator> Member;\n    typedef Encoding EncodingType;                  //!< Encoding type from template parameter.\n    typedef Allocator AllocatorType;                //!< Allocator type from template parameter.\n    typedef typename Encoding::Ch Ch;               //!< Character type derived from Encoding.\n    typedef GenericStringRef<Ch> StringRefType;     //!< Reference to a constant string\n    typedef typename GenericMemberIterator<false,Encoding,Allocator>::Iterator MemberIterator;  //!< Member iterator for iterating in object.\n    typedef typename GenericMemberIterator<true,Encoding,Allocator>::Iterator ConstMemberIterator;  //!< Constant member iterator for iterating in object.\n    typedef GenericValue* ValueIterator;            //!< Value iterator for iterating in array.\n    typedef const GenericValue* ConstValueIterator; //!< Constant value iterator for iterating in array.\n    typedef GenericValue<Encoding, Allocator> ValueType;    //!< Value type of itself.\n    typedef GenericArray<false, ValueType> Array;\n    typedef GenericArray<true, ValueType> ConstArray;\n    typedef GenericObject<false, ValueType> Object;\n    typedef GenericObject<true, ValueType> ConstObject;\n\n    //!@name Constructors and destructor.\n    //@{\n\n    //! Default constructor creates a null value.\n    GenericValue() RAPIDJSON_NOEXCEPT : data_() { data_.f.flags = kNullFlag; }\n\n#if RAPIDJSON_HAS_CXX11_RVALUE_REFS\n    //! Move constructor in C++11\n    GenericValue(GenericValue&& rhs) RAPIDJSON_NOEXCEPT : data_(rhs.data_) {\n        rhs.data_.f.flags = kNullFlag; // give up contents\n    }\n#endif\n\nprivate:\n    //! Copy constructor is not permitted.\n    GenericValue(const GenericValue& rhs);\n\n#if RAPIDJSON_HAS_CXX11_RVALUE_REFS\n    //! Moving from a GenericDocument is not permitted.\n    template <typename StackAllocator>\n    GenericValue(GenericDocument<Encoding,Allocator,StackAllocator>&& rhs);\n\n    //! Move assignment from a GenericDocument is not permitted.\n    template <typename StackAllocator>\n    GenericValue& operator=(GenericDocument<Encoding,Allocator,StackAllocator>&& rhs);\n#endif\n\npublic:\n\n    //! Constructor with JSON value type.\n    /*! This creates a Value of specified type with default content.\n        \\param type Type of the value.\n        \\note Default content for number is zero.\n    */\n    explicit GenericValue(Type type) RAPIDJSON_NOEXCEPT : data_() {\n        static const uint16_t defaultFlags[7] = {\n            kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kShortStringFlag,\n            kNumberAnyFlag\n        };\n        RAPIDJSON_ASSERT(type <= kNumberType);\n        data_.f.flags = defaultFlags[type];\n\n        // Use ShortString to store empty string.\n        if (type == kStringType)\n            data_.ss.SetLength(0);\n    }\n\n    //! Explicit copy constructor (with allocator)\n    /*! Creates a copy of a Value by using the given Allocator\n        \\tparam SourceAllocator allocator of \\c rhs\n        \\param rhs Value to copy from (read-only)\n        \\param allocator Allocator for allocating copied elements and buffers. Commonly use GenericDocument::GetAllocator().\n        \\see CopyFrom()\n    */\n    template <typename SourceAllocator>\n    GenericValue(const GenericValue<Encoding,SourceAllocator>& rhs, Allocator& allocator) {\n        switch (rhs.GetType()) {\n        case kObjectType: {\n                SizeType count = rhs.data_.o.size;\n                Member* lm = reinterpret_cast<Member*>(allocator.Malloc(count * sizeof(Member)));\n                const typename GenericValue<Encoding,SourceAllocator>::Member* rm = rhs.GetMembersPointer();\n                for (SizeType i = 0; i < count; i++) {\n                    new (&lm[i].name) GenericValue(rm[i].name, allocator);\n                    new (&lm[i].value) GenericValue(rm[i].value, allocator);\n                }\n                data_.f.flags = kObjectFlag;\n                data_.o.size = data_.o.capacity = count;\n                SetMembersPointer(lm);\n            }\n            break;\n        case kArrayType: {\n                SizeType count = rhs.data_.a.size;\n                GenericValue* le = reinterpret_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));\n                const GenericValue<Encoding,SourceAllocator>* re = rhs.GetElementsPointer();\n                for (SizeType i = 0; i < count; i++)\n                    new (&le[i]) GenericValue(re[i], allocator);\n                data_.f.flags = kArrayFlag;\n                data_.a.size = data_.a.capacity = count;\n                SetElementsPointer(le);\n            }\n            break;\n        case kStringType:\n            if (rhs.data_.f.flags == kConstStringFlag) {\n                data_.f.flags = rhs.data_.f.flags;\n                data_  = *reinterpret_cast<const Data*>(&rhs.data_);\n            }\n            else\n                SetStringRaw(StringRef(rhs.GetString(), rhs.GetStringLength()), allocator);\n            break;\n        default:\n            data_.f.flags = rhs.data_.f.flags;\n            data_  = *reinterpret_cast<const Data*>(&rhs.data_);\n            break;\n        }\n    }\n\n    //! Constructor for boolean value.\n    /*! \\param b Boolean value\n        \\note This constructor is limited to \\em real boolean values and rejects\n            implicitly converted types like arbitrary pointers.  Use an explicit cast\n            to \\c bool, if you want to construct a boolean JSON value in such cases.\n     */\n#ifndef RAPIDJSON_DOXYGEN_RUNNING // hide SFINAE from Doxygen\n    template <typename T>\n    explicit GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame<bool, T>))) RAPIDJSON_NOEXCEPT  // See #472\n#else\n    explicit GenericValue(bool b) RAPIDJSON_NOEXCEPT\n#endif\n        : data_() {\n            // safe-guard against failing SFINAE\n            RAPIDJSON_STATIC_ASSERT((internal::IsSame<bool,T>::Value));\n            data_.f.flags = b ? kTrueFlag : kFalseFlag;\n    }\n\n    //! Constructor for int value.\n    explicit GenericValue(int i) RAPIDJSON_NOEXCEPT : data_() {\n        data_.n.i64 = i;\n        data_.f.flags = (i >= 0) ? (kNumberIntFlag | kUintFlag | kUint64Flag) : kNumberIntFlag;\n    }\n\n    //! Constructor for unsigned value.\n    explicit GenericValue(unsigned u) RAPIDJSON_NOEXCEPT : data_() {\n        data_.n.u64 = u; \n        data_.f.flags = (u & 0x80000000) ? kNumberUintFlag : (kNumberUintFlag | kIntFlag | kInt64Flag);\n    }\n\n    //! Constructor for int64_t value.\n    explicit GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT : data_() {\n        data_.n.i64 = i64;\n        data_.f.flags = kNumberInt64Flag;\n        if (i64 >= 0) {\n            data_.f.flags |= kNumberUint64Flag;\n            if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))\n                data_.f.flags |= kUintFlag;\n            if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))\n                data_.f.flags |= kIntFlag;\n        }\n        else if (i64 >= static_cast<int64_t>(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))\n            data_.f.flags |= kIntFlag;\n    }\n\n    //! Constructor for uint64_t value.\n    explicit GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT : data_() {\n        data_.n.u64 = u64;\n        data_.f.flags = kNumberUint64Flag;\n        if (!(u64 & RAPIDJSON_UINT64_C2(0x80000000, 0x00000000)))\n            data_.f.flags |= kInt64Flag;\n        if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))\n            data_.f.flags |= kUintFlag;\n        if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))\n            data_.f.flags |= kIntFlag;\n    }\n\n    //! Constructor for double value.\n    explicit GenericValue(double d) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = d; data_.f.flags = kNumberDoubleFlag; }\n\n    //! Constructor for float value.\n    explicit GenericValue(float f) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = static_cast<double>(f); data_.f.flags = kNumberDoubleFlag; }\n\n    //! Constructor for constant string (i.e. do not make a copy of string)\n    GenericValue(const Ch* s, SizeType length) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(StringRef(s, length)); }\n\n    //! Constructor for constant string (i.e. do not make a copy of string)\n    explicit GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(s); }\n\n    //! Constructor for copy-string (i.e. do make a copy of string)\n    GenericValue(const Ch* s, SizeType length, Allocator& allocator) : data_() { SetStringRaw(StringRef(s, length), allocator); }\n\n    //! Constructor for copy-string (i.e. do make a copy of string)\n    GenericValue(const Ch*s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); }\n\n#if RAPIDJSON_HAS_STDSTRING\n    //! Constructor for copy-string from a string object (i.e. do make a copy of string)\n    /*! \\note Requires the definition of the preprocessor symbol \\ref RAPIDJSON_HAS_STDSTRING.\n     */\n    GenericValue(const std::basic_string<Ch>& s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); }\n#endif\n\n    //! Constructor for Array.\n    /*!\n        \\param a An array obtained by \\c GetArray().\n        \\note \\c Array is always pass-by-value.\n        \\note the source array is moved into this value and the sourec array becomes empty.\n    */\n    GenericValue(Array a) RAPIDJSON_NOEXCEPT : data_(a.value_.data_) {\n        a.value_.data_ = Data();\n        a.value_.data_.f.flags = kArrayFlag;\n    }\n\n    //! Constructor for Object.\n    /*!\n        \\param o An object obtained by \\c GetObject().\n        \\note \\c Object is always pass-by-value.\n        \\note the source object is moved into this value and the sourec object becomes empty.\n    */\n    GenericValue(Object o) RAPIDJSON_NOEXCEPT : data_(o.value_.data_) {\n        o.value_.data_ = Data();\n        o.value_.data_.f.flags = kObjectFlag;\n    }\n\n    //! Destructor.\n    /*! Need to destruct elements of array, members of object, or copy-string.\n    */\n    ~GenericValue() {\n        if (Allocator::kNeedFree) { // Shortcut by Allocator's trait\n            switch(data_.f.flags) {\n            case kArrayFlag:\n                {\n                    GenericValue* e = GetElementsPointer();\n                    for (GenericValue* v = e; v != e + data_.a.size; ++v)\n                        v->~GenericValue();\n                    Allocator::Free(e);\n                }\n                break;\n\n            case kObjectFlag:\n                for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)\n                    m->~Member();\n                Allocator::Free(GetMembersPointer());\n                break;\n\n            case kCopyStringFlag:\n                Allocator::Free(const_cast<Ch*>(GetStringPointer()));\n                break;\n\n            default:\n                break;  // Do nothing for other types.\n            }\n        }\n    }\n\n    //@}\n\n    //!@name Assignment operators\n    //@{\n\n    //! Assignment with move semantics.\n    /*! \\param rhs Source of the assignment. It will become a null value after assignment.\n    */\n    GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT {\n        RAPIDJSON_ASSERT(this != &rhs);\n        this->~GenericValue();\n        RawAssign(rhs);\n        return *this;\n    }\n\n#if RAPIDJSON_HAS_CXX11_RVALUE_REFS\n    //! Move assignment in C++11\n    GenericValue& operator=(GenericValue&& rhs) RAPIDJSON_NOEXCEPT {\n        return *this = rhs.Move();\n    }\n#endif\n\n    //! Assignment of constant string reference (no copy)\n    /*! \\param str Constant string reference to be assigned\n        \\note This overload is needed to avoid clashes with the generic primitive type assignment overload below.\n        \\see GenericStringRef, operator=(T)\n    */\n    GenericValue& operator=(StringRefType str) RAPIDJSON_NOEXCEPT {\n        GenericValue s(str);\n        return *this = s;\n    }\n\n    //! Assignment with primitive types.\n    /*! \\tparam T Either \\ref Type, \\c int, \\c unsigned, \\c int64_t, \\c uint64_t\n        \\param value The value to be assigned.\n\n        \\note The source type \\c T explicitly disallows all pointer types,\n            especially (\\c const) \\ref Ch*.  This helps avoiding implicitly\n            referencing character strings with insufficient lifetime, use\n            \\ref SetString(const Ch*, Allocator&) (for copying) or\n            \\ref StringRef() (to explicitly mark the pointer as constant) instead.\n            All other pointer types would implicitly convert to \\c bool,\n            use \\ref SetBool() instead.\n    */\n    template <typename T>\n    RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer<T>), (GenericValue&))\n    operator=(T value) {\n        GenericValue v(value);\n        return *this = v;\n    }\n\n    //! Deep-copy assignment from Value\n    /*! Assigns a \\b copy of the Value to the current Value object\n        \\tparam SourceAllocator Allocator type of \\c rhs\n        \\param rhs Value to copy from (read-only)\n        \\param allocator Allocator to use for copying\n     */\n    template <typename SourceAllocator>\n    GenericValue& CopyFrom(const GenericValue<Encoding, SourceAllocator>& rhs, Allocator& allocator) {\n        RAPIDJSON_ASSERT(static_cast<void*>(this) != static_cast<void const*>(&rhs));\n        this->~GenericValue();\n        new (this) GenericValue(rhs, allocator);\n        return *this;\n    }\n\n    //! Exchange the contents of this value with those of other.\n    /*!\n        \\param other Another value.\n        \\note Constant complexity.\n    */\n    GenericValue& Swap(GenericValue& other) RAPIDJSON_NOEXCEPT {\n        GenericValue temp;\n        temp.RawAssign(*this);\n        RawAssign(other);\n        other.RawAssign(temp);\n        return *this;\n    }\n\n    //! free-standing swap function helper\n    /*!\n        Helper function to enable support for common swap implementation pattern based on \\c std::swap:\n        \\code\n        void swap(MyClass& a, MyClass& b) {\n            using std::swap;\n            swap(a.value, b.value);\n            // ...\n        }\n        \\endcode\n        \\see Swap()\n     */\n    friend inline void swap(GenericValue& a, GenericValue& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }\n\n    //! Prepare Value for move semantics\n    /*! \\return *this */\n    GenericValue& Move() RAPIDJSON_NOEXCEPT { return *this; }\n    //@}\n\n    //!@name Equal-to and not-equal-to operators\n    //@{\n    //! Equal-to operator\n    /*!\n        \\note If an object contains duplicated named member, comparing equality with any object is always \\c false.\n        \\note Linear time complexity (number of all values in the subtree and total lengths of all strings).\n    */\n    template <typename SourceAllocator>\n    bool operator==(const GenericValue<Encoding, SourceAllocator>& rhs) const {\n        typedef GenericValue<Encoding, SourceAllocator> RhsType;\n        if (GetType() != rhs.GetType())\n            return false;\n\n        switch (GetType()) {\n        case kObjectType: // Warning: O(n^2) inner-loop\n            if (data_.o.size != rhs.data_.o.size)\n                return false;           \n            for (ConstMemberIterator lhsMemberItr = MemberBegin(); lhsMemberItr != MemberEnd(); ++lhsMemberItr) {\n                typename RhsType::ConstMemberIterator rhsMemberItr = rhs.FindMember(lhsMemberItr->name);\n                if (rhsMemberItr == rhs.MemberEnd() || lhsMemberItr->value != rhsMemberItr->value)\n                    return false;\n            }\n            return true;\n            \n        case kArrayType:\n            if (data_.a.size != rhs.data_.a.size)\n                return false;\n            for (SizeType i = 0; i < data_.a.size; i++)\n                if ((*this)[i] != rhs[i])\n                    return false;\n            return true;\n\n        case kStringType:\n            return StringEqual(rhs);\n\n        case kNumberType:\n            if (IsDouble() || rhs.IsDouble()) {\n                double a = GetDouble();     // May convert from integer to double.\n                double b = rhs.GetDouble(); // Ditto\n                return a >= b && a <= b;    // Prevent -Wfloat-equal\n            }\n            else\n                return data_.n.u64 == rhs.data_.n.u64;\n\n        default:\n            return true;\n        }\n    }\n\n    //! Equal-to operator with const C-string pointer\n    bool operator==(const Ch* rhs) const { return *this == GenericValue(StringRef(rhs)); }\n\n#if RAPIDJSON_HAS_STDSTRING\n    //! Equal-to operator with string object\n    /*! \\note Requires the definition of the preprocessor symbol \\ref RAPIDJSON_HAS_STDSTRING.\n     */\n    bool operator==(const std::basic_string<Ch>& rhs) const { return *this == GenericValue(StringRef(rhs)); }\n#endif\n\n    //! Equal-to operator with primitive types\n    /*! \\tparam T Either \\ref Type, \\c int, \\c unsigned, \\c int64_t, \\c uint64_t, \\c double, \\c true, \\c false\n    */\n    template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>,internal::IsGenericValue<T> >), (bool)) operator==(const T& rhs) const { return *this == GenericValue(rhs); }\n\n    //! Not-equal-to operator\n    /*! \\return !(*this == rhs)\n     */\n    template <typename SourceAllocator>\n    bool operator!=(const GenericValue<Encoding, SourceAllocator>& rhs) const { return !(*this == rhs); }\n\n    //! Not-equal-to operator with const C-string pointer\n    bool operator!=(const Ch* rhs) const { return !(*this == rhs); }\n\n    //! Not-equal-to operator with arbitrary types\n    /*! \\return !(*this == rhs)\n     */\n    template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); }\n\n    //! Equal-to operator with arbitrary types (symmetric version)\n    /*! \\return (rhs == lhs)\n     */\n    template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator==(const T& lhs, const GenericValue& rhs) { return rhs == lhs; }\n\n    //! Not-Equal-to operator with arbitrary types (symmetric version)\n    /*! \\return !(rhs == lhs)\n     */\n    template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& lhs, const GenericValue& rhs) { return !(rhs == lhs); }\n    //@}\n\n    //!@name Type\n    //@{\n\n    Type GetType()  const { return static_cast<Type>(data_.f.flags & kTypeMask); }\n    bool IsNull()   const { return data_.f.flags == kNullFlag; }\n    bool IsFalse()  const { return data_.f.flags == kFalseFlag; }\n    bool IsTrue()   const { return data_.f.flags == kTrueFlag; }\n    bool IsBool()   const { return (data_.f.flags & kBoolFlag) != 0; }\n    bool IsObject() const { return data_.f.flags == kObjectFlag; }\n    bool IsArray()  const { return data_.f.flags == kArrayFlag; }\n    bool IsNumber() const { return (data_.f.flags & kNumberFlag) != 0; }\n    bool IsInt()    const { return (data_.f.flags & kIntFlag) != 0; }\n    bool IsUint()   const { return (data_.f.flags & kUintFlag) != 0; }\n    bool IsInt64()  const { return (data_.f.flags & kInt64Flag) != 0; }\n    bool IsUint64() const { return (data_.f.flags & kUint64Flag) != 0; }\n    bool IsDouble() const { return (data_.f.flags & kDoubleFlag) != 0; }\n    bool IsString() const { return (data_.f.flags & kStringFlag) != 0; }\n\n    // Checks whether a number can be losslessly converted to a double.\n    bool IsLosslessDouble() const {\n        if (!IsNumber()) return false;\n        if (IsUint64()) {\n            uint64_t u = GetUint64();\n            volatile double d = static_cast<double>(u);\n            return (d >= 0.0)\n                && (d < static_cast<double>(std::numeric_limits<uint64_t>::max()))\n                && (u == static_cast<uint64_t>(d));\n        }\n        if (IsInt64()) {\n            int64_t i = GetInt64();\n            volatile double d = static_cast<double>(i);\n            return (d >= static_cast<double>(std::numeric_limits<int64_t>::min()))\n                && (d < static_cast<double>(std::numeric_limits<int64_t>::max()))\n                && (i == static_cast<int64_t>(d));\n        }\n        return true; // double, int, uint are always lossless\n    }\n\n    // Checks whether a number is a float (possible lossy).\n    bool IsFloat() const  {\n        if ((data_.f.flags & kDoubleFlag) == 0)\n            return false;\n        double d = GetDouble();\n        return d >= -3.4028234e38 && d <= 3.4028234e38;\n    }\n    // Checks whether a number can be losslessly converted to a float.\n    bool IsLosslessFloat() const {\n        if (!IsNumber()) return false;\n        double a = GetDouble();\n        if (a < static_cast<double>(-std::numeric_limits<float>::max())\n                || a > static_cast<double>(std::numeric_limits<float>::max()))\n            return false;\n        double b = static_cast<double>(static_cast<float>(a));\n        return a >= b && a <= b;    // Prevent -Wfloat-equal\n    }\n\n    //@}\n\n    //!@name Null\n    //@{\n\n    GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; }\n\n    //@}\n\n    //!@name Bool\n    //@{\n\n    bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return data_.f.flags == kTrueFlag; }\n    //!< Set boolean value\n    /*! \\post IsBool() == true */\n    GenericValue& SetBool(bool b) { this->~GenericValue(); new (this) GenericValue(b); return *this; }\n\n    //@}\n\n    //!@name Object\n    //@{\n\n    //! Set this value as an empty object.\n    /*! \\post IsObject() == true */\n    GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; }\n\n    //! Get the number of members in the object.\n    SizeType MemberCount() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size; }\n\n    //! Check whether the object is empty.\n    bool ObjectEmpty() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size == 0; }\n\n    //! Get a value from an object associated with the name.\n    /*! \\pre IsObject() == true\n        \\tparam T Either \\c Ch or \\c const \\c Ch (template used for disambiguation with \\ref operator[](SizeType))\n        \\note In version 0.1x, if the member is not found, this function returns a null value. This makes issue 7.\n        Since 0.2, if the name is not correct, it will assert.\n        If user is unsure whether a member exists, user should use HasMember() first.\n        A better approach is to use FindMember().\n        \\note Linear time complexity.\n    */\n    template <typename T>\n    RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >),(GenericValue&)) operator[](T* name) {\n        GenericValue n(StringRef(name));\n        return (*this)[n];\n    }\n    template <typename T>\n    RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >),(const GenericValue&)) operator[](T* name) const { return const_cast<GenericValue&>(*this)[name]; }\n\n    //! Get a value from an object associated with the name.\n    /*! \\pre IsObject() == true\n        \\tparam SourceAllocator Allocator of the \\c name value\n\n        \\note Compared to \\ref operator[](T*), this version is faster because it does not need a StrLen().\n        And it can also handle strings with embedded null characters.\n\n        \\note Linear time complexity.\n    */\n    template <typename SourceAllocator>\n    GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) {\n        MemberIterator member = FindMember(name);\n        if (member != MemberEnd())\n            return member->value;\n        else {\n            RAPIDJSON_ASSERT(false);    // see above note\n\n            // This will generate -Wexit-time-destructors in clang\n            // static GenericValue NullValue;\n            // return NullValue;\n\n            // Use static buffer and placement-new to prevent destruction\n            static char buffer[sizeof(GenericValue)];\n            return *new (buffer) GenericValue();\n        }\n    }\n    template <typename SourceAllocator>\n    const GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this)[name]; }\n\n#if RAPIDJSON_HAS_STDSTRING\n    //! Get a value from an object associated with name (string object).\n    GenericValue& operator[](const std::basic_string<Ch>& name) { return (*this)[GenericValue(StringRef(name))]; }\n    const GenericValue& operator[](const std::basic_string<Ch>& name) const { return (*this)[GenericValue(StringRef(name))]; }\n#endif\n\n    //! Const member iterator\n    /*! \\pre IsObject() == true */\n    ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer()); }\n    //! Const \\em past-the-end member iterator\n    /*! \\pre IsObject() == true */\n    ConstMemberIterator MemberEnd() const   { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer() + data_.o.size); }\n    //! Member iterator\n    /*! \\pre IsObject() == true */\n    MemberIterator MemberBegin()            { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer()); }\n    //! \\em Past-the-end member iterator\n    /*! \\pre IsObject() == true */\n    MemberIterator MemberEnd()              { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer() + data_.o.size); }\n\n    //! Check whether a member exists in the object.\n    /*!\n        \\param name Member name to be searched.\n        \\pre IsObject() == true\n        \\return Whether a member with that name exists.\n        \\note It is better to use FindMember() directly if you need the obtain the value as well.\n        \\note Linear time complexity.\n    */\n    bool HasMember(const Ch* name) const { return FindMember(name) != MemberEnd(); }\n\n#if RAPIDJSON_HAS_STDSTRING\n    //! Check whether a member exists in the object with string object.\n    /*!\n        \\param name Member name to be searched.\n        \\pre IsObject() == true\n        \\return Whether a member with that name exists.\n        \\note It is better to use FindMember() directly if you need the obtain the value as well.\n        \\note Linear time complexity.\n    */\n    bool HasMember(const std::basic_string<Ch>& name) const { return FindMember(name) != MemberEnd(); }\n#endif\n\n    //! Check whether a member exists in the object with GenericValue name.\n    /*!\n        This version is faster because it does not need a StrLen(). It can also handle string with null character.\n        \\param name Member name to be searched.\n        \\pre IsObject() == true\n        \\return Whether a member with that name exists.\n        \\note It is better to use FindMember() directly if you need the obtain the value as well.\n        \\note Linear time complexity.\n    */\n    template <typename SourceAllocator>\n    bool HasMember(const GenericValue<Encoding, SourceAllocator>& name) const { return FindMember(name) != MemberEnd(); }\n\n    //! Find member by name.\n    /*!\n        \\param name Member name to be searched.\n        \\pre IsObject() == true\n        \\return Iterator to member, if it exists.\n            Otherwise returns \\ref MemberEnd().\n\n        \\note Earlier versions of Rapidjson returned a \\c NULL pointer, in case\n            the requested member doesn't exist. For consistency with e.g.\n            \\c std::map, this has been changed to MemberEnd() now.\n        \\note Linear time complexity.\n    */\n    MemberIterator FindMember(const Ch* name) {\n        GenericValue n(StringRef(name));\n        return FindMember(n);\n    }\n\n    ConstMemberIterator FindMember(const Ch* name) const { return const_cast<GenericValue&>(*this).FindMember(name); }\n\n    //! Find member by name.\n    /*!\n        This version is faster because it does not need a StrLen(). It can also handle string with null character.\n        \\param name Member name to be searched.\n        \\pre IsObject() == true\n        \\return Iterator to member, if it exists.\n            Otherwise returns \\ref MemberEnd().\n\n        \\note Earlier versions of Rapidjson returned a \\c NULL pointer, in case\n            the requested member doesn't exist. For consistency with e.g.\n            \\c std::map, this has been changed to MemberEnd() now.\n        \\note Linear time complexity.\n    */\n    template <typename SourceAllocator>\n    MemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) {\n        RAPIDJSON_ASSERT(IsObject());\n        RAPIDJSON_ASSERT(name.IsString());\n        MemberIterator member = MemberBegin();\n        for ( ; member != MemberEnd(); ++member)\n            if (name.StringEqual(member->name))\n                break;\n        return member;\n    }\n    template <typename SourceAllocator> ConstMemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this).FindMember(name); }\n\n#if RAPIDJSON_HAS_STDSTRING\n    //! Find member by string object name.\n    /*!\n        \\param name Member name to be searched.\n        \\pre IsObject() == true\n        \\return Iterator to member, if it exists.\n            Otherwise returns \\ref MemberEnd().\n    */\n    MemberIterator FindMember(const std::basic_string<Ch>& name) { return FindMember(GenericValue(StringRef(name))); }\n    ConstMemberIterator FindMember(const std::basic_string<Ch>& name) const { return FindMember(GenericValue(StringRef(name))); }\n#endif\n\n    //! Add a member (name-value pair) to the object.\n    /*! \\param name A string value as name of member.\n        \\param value Value of any type.\n        \\param allocator    Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().\n        \\return The value itself for fluent API.\n        \\note The ownership of \\c name and \\c value will be transferred to this object on success.\n        \\pre  IsObject() && name.IsString()\n        \\post name.IsNull() && value.IsNull()\n        \\note Amortized Constant time complexity.\n    */\n    GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) {\n        RAPIDJSON_ASSERT(IsObject());\n        RAPIDJSON_ASSERT(name.IsString());\n\n        ObjectData& o = data_.o;\n        if (o.size >= o.capacity) {\n            if (o.capacity == 0) {\n                o.capacity = kDefaultObjectCapacity;\n                SetMembersPointer(reinterpret_cast<Member*>(allocator.Malloc(o.capacity * sizeof(Member))));\n            }\n            else {\n                SizeType oldCapacity = o.capacity;\n                o.capacity += (oldCapacity + 1) / 2; // grow by factor 1.5\n                SetMembersPointer(reinterpret_cast<Member*>(allocator.Realloc(GetMembersPointer(), oldCapacity * sizeof(Member), o.capacity * sizeof(Member))));\n            }\n        }\n        Member* members = GetMembersPointer();\n        members[o.size].name.RawAssign(name);\n        members[o.size].value.RawAssign(value);\n        o.size++;\n        return *this;\n    }\n\n    //! Add a constant string value as member (name-value pair) to the object.\n    /*! \\param name A string value as name of member.\n        \\param value constant string reference as value of member.\n        \\param allocator    Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().\n        \\return The value itself for fluent API.\n        \\pre  IsObject()\n        \\note This overload is needed to avoid clashes with the generic primitive type AddMember(GenericValue&,T,Allocator&) overload below.\n        \\note Amortized Constant time complexity.\n    */\n    GenericValue& AddMember(GenericValue& name, StringRefType value, Allocator& allocator) {\n        GenericValue v(value);\n        return AddMember(name, v, allocator);\n    }\n\n#if RAPIDJSON_HAS_STDSTRING\n    //! Add a string object as member (name-value pair) to the object.\n    /*! \\param name A string value as name of member.\n        \\param value constant string reference as value of member.\n        \\param allocator    Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().\n        \\return The value itself for fluent API.\n        \\pre  IsObject()\n        \\note This overload is needed to avoid clashes with the generic primitive type AddMember(GenericValue&,T,Allocator&) overload below.\n        \\note Amortized Constant time complexity.\n    */\n    GenericValue& AddMember(GenericValue& name, std::basic_string<Ch>& value, Allocator& allocator) {\n        GenericValue v(value, allocator);\n        return AddMember(name, v, allocator);\n    }\n#endif\n\n    //! Add any primitive value as member (name-value pair) to the object.\n    /*! \\tparam T Either \\ref Type, \\c int, \\c unsigned, \\c int64_t, \\c uint64_t\n        \\param name A string value as name of member.\n        \\param value Value of primitive type \\c T as value of member\n        \\param allocator Allocator for reallocating memory. Commonly use GenericDocument::GetAllocator().\n        \\return The value itself for fluent API.\n        \\pre  IsObject()\n\n        \\note The source type \\c T explicitly disallows all pointer types,\n            especially (\\c const) \\ref Ch*.  This helps avoiding implicitly\n            referencing character strings with insufficient lifetime, use\n            \\ref AddMember(StringRefType, GenericValue&, Allocator&) or \\ref\n            AddMember(StringRefType, StringRefType, Allocator&).\n            All other pointer types would implicitly convert to \\c bool,\n            use an explicit cast instead, if needed.\n        \\note Amortized Constant time complexity.\n    */\n    template <typename T>\n    RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))\n    AddMember(GenericValue& name, T value, Allocator& allocator) {\n        GenericValue v(value);\n        return AddMember(name, v, allocator);\n    }\n\n#if RAPIDJSON_HAS_CXX11_RVALUE_REFS\n    GenericValue& AddMember(GenericValue&& name, GenericValue&& value, Allocator& allocator) {\n        return AddMember(name, value, allocator);\n    }\n    GenericValue& AddMember(GenericValue&& name, GenericValue& value, Allocator& allocator) {\n        return AddMember(name, value, allocator);\n    }\n    GenericValue& AddMember(GenericValue& name, GenericValue&& value, Allocator& allocator) {\n        return AddMember(name, value, allocator);\n    }\n    GenericValue& AddMember(StringRefType name, GenericValue&& value, Allocator& allocator) {\n        GenericValue n(name);\n        return AddMember(n, value, allocator);\n    }\n#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS\n\n\n    //! Add a member (name-value pair) to the object.\n    /*! \\param name A constant string reference as name of member.\n        \\param value Value of any type.\n        \\param allocator    Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().\n        \\return The value itself for fluent API.\n        \\note The ownership of \\c value will be transferred to this object on success.\n        \\pre  IsObject()\n        \\post value.IsNull()\n        \\note Amortized Constant time complexity.\n    */\n    GenericValue& AddMember(StringRefType name, GenericValue& value, Allocator& allocator) {\n        GenericValue n(name);\n        return AddMember(n, value, allocator);\n    }\n\n    //! Add a constant string value as member (name-value pair) to the object.\n    /*! \\param name A constant string reference as name of member.\n        \\param value constant string reference as value of member.\n        \\param allocator    Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().\n        \\return The value itself for fluent API.\n        \\pre  IsObject()\n        \\note This overload is needed to avoid clashes with the generic primitive type AddMember(StringRefType,T,Allocator&) overload below.\n        \\note Amortized Constant time complexity.\n    */\n    GenericValue& AddMember(StringRefType name, StringRefType value, Allocator& allocator) {\n        GenericValue v(value);\n        return AddMember(name, v, allocator);\n    }\n\n    //! Add any primitive value as member (name-value pair) to the object.\n    /*! \\tparam T Either \\ref Type, \\c int, \\c unsigned, \\c int64_t, \\c uint64_t\n        \\param name A constant string reference as name of member.\n        \\param value Value of primitive type \\c T as value of member\n        \\param allocator Allocator for reallocating memory. Commonly use GenericDocument::GetAllocator().\n        \\return The value itself for fluent API.\n        \\pre  IsObject()\n\n        \\note The source type \\c T explicitly disallows all pointer types,\n            especially (\\c const) \\ref Ch*.  This helps avoiding implicitly\n            referencing character strings with insufficient lifetime, use\n            \\ref AddMember(StringRefType, GenericValue&, Allocator&) or \\ref\n            AddMember(StringRefType, StringRefType, Allocator&).\n            All other pointer types would implicitly convert to \\c bool,\n            use an explicit cast instead, if needed.\n        \\note Amortized Constant time complexity.\n    */\n    template <typename T>\n    RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))\n    AddMember(StringRefType name, T value, Allocator& allocator) {\n        GenericValue n(name);\n        return AddMember(n, value, allocator);\n    }\n\n    //! Remove all members in the object.\n    /*! This function do not deallocate memory in the object, i.e. the capacity is unchanged.\n        \\note Linear time complexity.\n    */\n    void RemoveAllMembers() {\n        RAPIDJSON_ASSERT(IsObject()); \n        for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)\n            m->~Member();\n        data_.o.size = 0;\n    }\n\n    //! Remove a member in object by its name.\n    /*! \\param name Name of member to be removed.\n        \\return Whether the member existed.\n        \\note This function may reorder the object members. Use \\ref\n            EraseMember(ConstMemberIterator) if you need to preserve the\n            relative order of the remaining members.\n        \\note Linear time complexity.\n    */\n    bool RemoveMember(const Ch* name) {\n        GenericValue n(StringRef(name));\n        return RemoveMember(n);\n    }\n\n#if RAPIDJSON_HAS_STDSTRING\n    bool RemoveMember(const std::basic_string<Ch>& name) { return RemoveMember(GenericValue(StringRef(name))); }\n#endif\n\n    template <typename SourceAllocator>\n    bool RemoveMember(const GenericValue<Encoding, SourceAllocator>& name) {\n        MemberIterator m = FindMember(name);\n        if (m != MemberEnd()) {\n            RemoveMember(m);\n            return true;\n        }\n        else\n            return false;\n    }\n\n    //! Remove a member in object by iterator.\n    /*! \\param m member iterator (obtained by FindMember() or MemberBegin()).\n        \\return the new iterator after removal.\n        \\note This function may reorder the object members. Use \\ref\n            EraseMember(ConstMemberIterator) if you need to preserve the\n            relative order of the remaining members.\n        \\note Constant time complexity.\n    */\n    MemberIterator RemoveMember(MemberIterator m) {\n        RAPIDJSON_ASSERT(IsObject());\n        RAPIDJSON_ASSERT(data_.o.size > 0);\n        RAPIDJSON_ASSERT(GetMembersPointer() != 0);\n        RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd());\n\n        MemberIterator last(GetMembersPointer() + (data_.o.size - 1));\n        if (data_.o.size > 1 && m != last)\n            *m = *last; // Move the last one to this place\n        else\n            m->~Member(); // Only one left, just destroy\n        --data_.o.size;\n        return m;\n    }\n\n    //! Remove a member from an object by iterator.\n    /*! \\param pos iterator to the member to remove\n        \\pre IsObject() == true && \\ref MemberBegin() <= \\c pos < \\ref MemberEnd()\n        \\return Iterator following the removed element.\n            If the iterator \\c pos refers to the last element, the \\ref MemberEnd() iterator is returned.\n        \\note This function preserves the relative order of the remaining object\n            members. If you do not need this, use the more efficient \\ref RemoveMember(MemberIterator).\n        \\note Linear time complexity.\n    */\n    MemberIterator EraseMember(ConstMemberIterator pos) {\n        return EraseMember(pos, pos +1);\n    }\n\n    //! Remove members in the range [first, last) from an object.\n    /*! \\param first iterator to the first member to remove\n        \\param last  iterator following the last member to remove\n        \\pre IsObject() == true && \\ref MemberBegin() <= \\c first <= \\c last <= \\ref MemberEnd()\n        \\return Iterator following the last removed element.\n        \\note This function preserves the relative order of the remaining object\n            members.\n        \\note Linear time complexity.\n    */\n    MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) {\n        RAPIDJSON_ASSERT(IsObject());\n        RAPIDJSON_ASSERT(data_.o.size > 0);\n        RAPIDJSON_ASSERT(GetMembersPointer() != 0);\n        RAPIDJSON_ASSERT(first >= MemberBegin());\n        RAPIDJSON_ASSERT(first <= last);\n        RAPIDJSON_ASSERT(last <= MemberEnd());\n\n        MemberIterator pos = MemberBegin() + (first - MemberBegin());\n        for (MemberIterator itr = pos; itr != last; ++itr)\n            itr->~Member();\n        std::memmove(&*pos, &*last, static_cast<size_t>(MemberEnd() - last) * sizeof(Member));\n        data_.o.size -= static_cast<SizeType>(last - first);\n        return pos;\n    }\n\n    //! Erase a member in object by its name.\n    /*! \\param name Name of member to be removed.\n        \\return Whether the member existed.\n        \\note Linear time complexity.\n    */\n    bool EraseMember(const Ch* name) {\n        GenericValue n(StringRef(name));\n        return EraseMember(n);\n    }\n\n#if RAPIDJSON_HAS_STDSTRING\n    bool EraseMember(const std::basic_string<Ch>& name) { return EraseMember(GenericValue(StringRef(name))); }\n#endif\n\n    template <typename SourceAllocator>\n    bool EraseMember(const GenericValue<Encoding, SourceAllocator>& name) {\n        MemberIterator m = FindMember(name);\n        if (m != MemberEnd()) {\n            EraseMember(m);\n            return true;\n        }\n        else\n            return false;\n    }\n\n    Object GetObject() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); }\n    ConstObject GetObject() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); }\n\n    //@}\n\n    //!@name Array\n    //@{\n\n    //! Set this value as an empty array.\n    /*! \\post IsArray == true */\n    GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; }\n\n    //! Get the number of elements in array.\n    SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; }\n\n    //! Get the capacity of array.\n    SizeType Capacity() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.capacity; }\n\n    //! Check whether the array is empty.\n    bool Empty() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; }\n\n    //! Remove all elements in the array.\n    /*! This function do not deallocate memory in the array, i.e. the capacity is unchanged.\n        \\note Linear time complexity.\n    */\n    void Clear() {\n        RAPIDJSON_ASSERT(IsArray()); \n        GenericValue* e = GetElementsPointer();\n        for (GenericValue* v = e; v != e + data_.a.size; ++v)\n            v->~GenericValue();\n        data_.a.size = 0;\n    }\n\n    //! Get an element from array by index.\n    /*! \\pre IsArray() == true\n        \\param index Zero-based index of element.\n        \\see operator[](T*)\n    */\n    GenericValue& operator[](SizeType index) {\n        RAPIDJSON_ASSERT(IsArray());\n        RAPIDJSON_ASSERT(index < data_.a.size);\n        return GetElementsPointer()[index];\n    }\n    const GenericValue& operator[](SizeType index) const { return const_cast<GenericValue&>(*this)[index]; }\n\n    //! Element iterator\n    /*! \\pre IsArray() == true */\n    ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer(); }\n    //! \\em Past-the-end element iterator\n    /*! \\pre IsArray() == true */\n    ValueIterator End() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer() + data_.a.size; }\n    //! Constant element iterator\n    /*! \\pre IsArray() == true */\n    ConstValueIterator Begin() const { return const_cast<GenericValue&>(*this).Begin(); }\n    //! Constant \\em past-the-end element iterator\n    /*! \\pre IsArray() == true */\n    ConstValueIterator End() const { return const_cast<GenericValue&>(*this).End(); }\n\n    //! Request the array to have enough capacity to store elements.\n    /*! \\param newCapacity  The capacity that the array at least need to have.\n        \\param allocator    Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().\n        \\return The value itself for fluent API.\n        \\note Linear time complexity.\n    */\n    GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) {\n        RAPIDJSON_ASSERT(IsArray());\n        if (newCapacity > data_.a.capacity) {\n            SetElementsPointer(reinterpret_cast<GenericValue*>(allocator.Realloc(GetElementsPointer(), data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue))));\n            data_.a.capacity = newCapacity;\n        }\n        return *this;\n    }\n\n    //! Append a GenericValue at the end of the array.\n    /*! \\param value        Value to be appended.\n        \\param allocator    Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().\n        \\pre IsArray() == true\n        \\post value.IsNull() == true\n        \\return The value itself for fluent API.\n        \\note The ownership of \\c value will be transferred to this array on success.\n        \\note If the number of elements to be appended is known, calls Reserve() once first may be more efficient.\n        \\note Amortized constant time complexity.\n    */\n    GenericValue& PushBack(GenericValue& value, Allocator& allocator) {\n        RAPIDJSON_ASSERT(IsArray());\n        if (data_.a.size >= data_.a.capacity)\n            Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : (data_.a.capacity + (data_.a.capacity + 1) / 2), allocator);\n        GetElementsPointer()[data_.a.size++].RawAssign(value);\n        return *this;\n    }\n\n#if RAPIDJSON_HAS_CXX11_RVALUE_REFS\n    GenericValue& PushBack(GenericValue&& value, Allocator& allocator) {\n        return PushBack(value, allocator);\n    }\n#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS\n\n    //! Append a constant string reference at the end of the array.\n    /*! \\param value        Constant string reference to be appended.\n        \\param allocator    Allocator for reallocating memory. It must be the same one used previously. Commonly use GenericDocument::GetAllocator().\n        \\pre IsArray() == true\n        \\return The value itself for fluent API.\n        \\note If the number of elements to be appended is known, calls Reserve() once first may be more efficient.\n        \\note Amortized constant time complexity.\n        \\see GenericStringRef\n    */\n    GenericValue& PushBack(StringRefType value, Allocator& allocator) {\n        return (*this).template PushBack<StringRefType>(value, allocator);\n    }\n\n    //! Append a primitive value at the end of the array.\n    /*! \\tparam T Either \\ref Type, \\c int, \\c unsigned, \\c int64_t, \\c uint64_t\n        \\param value Value of primitive type T to be appended.\n        \\param allocator    Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().\n        \\pre IsArray() == true\n        \\return The value itself for fluent API.\n        \\note If the number of elements to be appended is known, calls Reserve() once first may be more efficient.\n\n        \\note The source type \\c T explicitly disallows all pointer types,\n            especially (\\c const) \\ref Ch*.  This helps avoiding implicitly\n            referencing character strings with insufficient lifetime, use\n            \\ref PushBack(GenericValue&, Allocator&) or \\ref\n            PushBack(StringRefType, Allocator&).\n            All other pointer types would implicitly convert to \\c bool,\n            use an explicit cast instead, if needed.\n        \\note Amortized constant time complexity.\n    */\n    template <typename T>\n    RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))\n    PushBack(T value, Allocator& allocator) {\n        GenericValue v(value);\n        return PushBack(v, allocator);\n    }\n\n    //! Remove the last element in the array.\n    /*!\n        \\note Constant time complexity.\n    */\n    GenericValue& PopBack() {\n        RAPIDJSON_ASSERT(IsArray());\n        RAPIDJSON_ASSERT(!Empty());\n        GetElementsPointer()[--data_.a.size].~GenericValue();\n        return *this;\n    }\n\n    //! Remove an element of array by iterator.\n    /*!\n        \\param pos iterator to the element to remove\n        \\pre IsArray() == true && \\ref Begin() <= \\c pos < \\ref End()\n        \\return Iterator following the removed element. If the iterator pos refers to the last element, the End() iterator is returned.\n        \\note Linear time complexity.\n    */\n    ValueIterator Erase(ConstValueIterator pos) {\n        return Erase(pos, pos + 1);\n    }\n\n    //! Remove elements in the range [first, last) of the array.\n    /*!\n        \\param first iterator to the first element to remove\n        \\param last  iterator following the last element to remove\n        \\pre IsArray() == true && \\ref Begin() <= \\c first <= \\c last <= \\ref End()\n        \\return Iterator following the last removed element.\n        \\note Linear time complexity.\n    */\n    ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) {\n        RAPIDJSON_ASSERT(IsArray());\n        RAPIDJSON_ASSERT(data_.a.size > 0);\n        RAPIDJSON_ASSERT(GetElementsPointer() != 0);\n        RAPIDJSON_ASSERT(first >= Begin());\n        RAPIDJSON_ASSERT(first <= last);\n        RAPIDJSON_ASSERT(last <= End());\n        ValueIterator pos = Begin() + (first - Begin());\n        for (ValueIterator itr = pos; itr != last; ++itr)\n            itr->~GenericValue();       \n        std::memmove(pos, last, static_cast<size_t>(End() - last) * sizeof(GenericValue));\n        data_.a.size -= static_cast<SizeType>(last - first);\n        return pos;\n    }\n\n    Array GetArray() { RAPIDJSON_ASSERT(IsArray()); return Array(*this); }\n    ConstArray GetArray() const { RAPIDJSON_ASSERT(IsArray()); return ConstArray(*this); }\n\n    //@}\n\n    //!@name Number\n    //@{\n\n    int GetInt() const          { RAPIDJSON_ASSERT(data_.f.flags & kIntFlag);   return data_.n.i.i;   }\n    unsigned GetUint() const    { RAPIDJSON_ASSERT(data_.f.flags & kUintFlag);  return data_.n.u.u;   }\n    int64_t GetInt64() const    { RAPIDJSON_ASSERT(data_.f.flags & kInt64Flag); return data_.n.i64; }\n    uint64_t GetUint64() const  { RAPIDJSON_ASSERT(data_.f.flags & kUint64Flag); return data_.n.u64; }\n\n    //! Get the value as double type.\n    /*! \\note If the value is 64-bit integer type, it may lose precision. Use \\c IsLosslessDouble() to check whether the converison is lossless.\n    */\n    double GetDouble() const {\n        RAPIDJSON_ASSERT(IsNumber());\n        if ((data_.f.flags & kDoubleFlag) != 0)                return data_.n.d;   // exact type, no conversion.\n        if ((data_.f.flags & kIntFlag) != 0)                   return data_.n.i.i; // int -> double\n        if ((data_.f.flags & kUintFlag) != 0)                  return data_.n.u.u; // unsigned -> double\n        if ((data_.f.flags & kInt64Flag) != 0)                 return static_cast<double>(data_.n.i64); // int64_t -> double (may lose precision)\n        RAPIDJSON_ASSERT((data_.f.flags & kUint64Flag) != 0);  return static_cast<double>(data_.n.u64); // uint64_t -> double (may lose precision)\n    }\n\n    //! Get the value as float type.\n    /*! \\note If the value is 64-bit integer type, it may lose precision. Use \\c IsLosslessFloat() to check whether the converison is lossless.\n    */\n    float GetFloat() const {\n        return static_cast<float>(GetDouble());\n    }\n\n    GenericValue& SetInt(int i)             { this->~GenericValue(); new (this) GenericValue(i);    return *this; }\n    GenericValue& SetUint(unsigned u)       { this->~GenericValue(); new (this) GenericValue(u);    return *this; }\n    GenericValue& SetInt64(int64_t i64)     { this->~GenericValue(); new (this) GenericValue(i64);  return *this; }\n    GenericValue& SetUint64(uint64_t u64)   { this->~GenericValue(); new (this) GenericValue(u64);  return *this; }\n    GenericValue& SetDouble(double d)       { this->~GenericValue(); new (this) GenericValue(d);    return *this; }\n    GenericValue& SetFloat(float f)         { this->~GenericValue(); new (this) GenericValue(static_cast<double>(f)); return *this; }\n\n    //@}\n\n    //!@name String\n    //@{\n\n    const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return (data_.f.flags & kInlineStrFlag) ? data_.ss.str : GetStringPointer(); }\n\n    //! Get the length of string.\n    /*! Since rapidjson permits \"\\\\u0000\" in the json string, strlen(v.GetString()) may not equal to v.GetStringLength().\n    */\n    SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return ((data_.f.flags & kInlineStrFlag) ? (data_.ss.GetLength()) : data_.s.length); }\n\n    //! Set this value as a string without copying source string.\n    /*! This version has better performance with supplied length, and also support string containing null character.\n        \\param s source string pointer. \n        \\param length The length of source string, excluding the trailing null terminator.\n        \\return The value itself for fluent API.\n        \\post IsString() == true && GetString() == s && GetStringLength() == length\n        \\see SetString(StringRefType)\n    */\n    GenericValue& SetString(const Ch* s, SizeType length) { return SetString(StringRef(s, length)); }\n\n    //! Set this value as a string without copying source string.\n    /*! \\param s source string reference\n        \\return The value itself for fluent API.\n        \\post IsString() == true && GetString() == s && GetStringLength() == s.length\n    */\n    GenericValue& SetString(StringRefType s) { this->~GenericValue(); SetStringRaw(s); return *this; }\n\n    //! Set this value as a string by copying from source string.\n    /*! This version has better performance with supplied length, and also support string containing null character.\n        \\param s source string. \n        \\param length The length of source string, excluding the trailing null terminator.\n        \\param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator().\n        \\return The value itself for fluent API.\n        \\post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length\n    */\n    GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { this->~GenericValue(); SetStringRaw(StringRef(s, length), allocator); return *this; }\n\n    //! Set this value as a string by copying from source string.\n    /*! \\param s source string. \n        \\param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator().\n        \\return The value itself for fluent API.\n        \\post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length\n    */\n    GenericValue& SetString(const Ch* s, Allocator& allocator) { return SetString(s, internal::StrLen(s), allocator); }\n\n#if RAPIDJSON_HAS_STDSTRING\n    //! Set this value as a string by copying from source string.\n    /*! \\param s source string.\n        \\param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator().\n        \\return The value itself for fluent API.\n        \\post IsString() == true && GetString() != s.data() && strcmp(GetString(),s.data() == 0 && GetStringLength() == s.size()\n        \\note Requires the definition of the preprocessor symbol \\ref RAPIDJSON_HAS_STDSTRING.\n    */\n    GenericValue& SetString(const std::basic_string<Ch>& s, Allocator& allocator) { return SetString(s.data(), SizeType(s.size()), allocator); }\n#endif\n\n    //@}\n\n    //!@name Array\n    //@{\n\n    //! Templated version for checking whether this value is type T.\n    /*!\n        \\tparam T Either \\c bool, \\c int, \\c unsigned, \\c int64_t, \\c uint64_t, \\c double, \\c float, \\c const \\c char*, \\c std::basic_string<Ch>\n    */\n    template <typename T>\n    bool Is() const { return internal::TypeHelper<ValueType, T>::Is(*this); }\n\n    template <typename T>\n    T Get() const { return internal::TypeHelper<ValueType, T>::Get(*this); }\n\n    template <typename T>\n    T Get() { return internal::TypeHelper<ValueType, T>::Get(*this); }\n\n    template<typename T>\n    ValueType& Set(const T& data) { return internal::TypeHelper<ValueType, T>::Set(*this, data); }\n\n    template<typename T>\n    ValueType& Set(const T& data, AllocatorType& allocator) { return internal::TypeHelper<ValueType, T>::Set(*this, data, allocator); }\n\n    //@}\n\n    //! Generate events of this value to a Handler.\n    /*! This function adopts the GoF visitor pattern.\n        Typical usage is to output this JSON value as JSON text via Writer, which is a Handler.\n        It can also be used to deep clone this value via GenericDocument, which is also a Handler.\n        \\tparam Handler type of handler.\n        \\param handler An object implementing concept Handler.\n    */\n    template <typename Handler>\n    bool Accept(Handler& handler) const {\n        switch(GetType()) {\n        case kNullType:     return handler.Null();\n        case kFalseType:    return handler.Bool(false);\n        case kTrueType:     return handler.Bool(true);\n\n        case kObjectType:\n            if (RAPIDJSON_UNLIKELY(!handler.StartObject()))\n                return false;\n            for (ConstMemberIterator m = MemberBegin(); m != MemberEnd(); ++m) {\n                RAPIDJSON_ASSERT(m->name.IsString()); // User may change the type of name by MemberIterator.\n                if (RAPIDJSON_UNLIKELY(!handler.Key(m->name.GetString(), m->name.GetStringLength(), (m->name.data_.f.flags & kCopyFlag) != 0)))\n                    return false;\n                if (RAPIDJSON_UNLIKELY(!m->value.Accept(handler)))\n                    return false;\n            }\n            return handler.EndObject(data_.o.size);\n\n        case kArrayType:\n            if (RAPIDJSON_UNLIKELY(!handler.StartArray()))\n                return false;\n            for (const GenericValue* v = Begin(); v != End(); ++v)\n                if (RAPIDJSON_UNLIKELY(!v->Accept(handler)))\n                    return false;\n            return handler.EndArray(data_.a.size);\n    \n        case kStringType:\n            return handler.String(GetString(), GetStringLength(), (data_.f.flags & kCopyFlag) != 0);\n    \n        default:\n            RAPIDJSON_ASSERT(GetType() == kNumberType);\n            if (IsDouble())         return handler.Double(data_.n.d);\n            else if (IsInt())       return handler.Int(data_.n.i.i);\n            else if (IsUint())      return handler.Uint(data_.n.u.u);\n            else if (IsInt64())     return handler.Int64(data_.n.i64);\n            else                    return handler.Uint64(data_.n.u64);\n        }\n    }\n\nprivate:\n    template <typename, typename> friend class GenericValue;\n    template <typename, typename, typename> friend class GenericDocument;\n\n    enum {\n        kBoolFlag       = 0x0008,\n        kNumberFlag     = 0x0010,\n        kIntFlag        = 0x0020,\n        kUintFlag       = 0x0040,\n        kInt64Flag      = 0x0080,\n        kUint64Flag     = 0x0100,\n        kDoubleFlag     = 0x0200,\n        kStringFlag     = 0x0400,\n        kCopyFlag       = 0x0800,\n        kInlineStrFlag  = 0x1000,\n\n        // Initial flags of different types.\n        kNullFlag = kNullType,\n        kTrueFlag = kTrueType | kBoolFlag,\n        kFalseFlag = kFalseType | kBoolFlag,\n        kNumberIntFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag,\n        kNumberUintFlag = kNumberType | kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag,\n        kNumberInt64Flag = kNumberType | kNumberFlag | kInt64Flag,\n        kNumberUint64Flag = kNumberType | kNumberFlag | kUint64Flag,\n        kNumberDoubleFlag = kNumberType | kNumberFlag | kDoubleFlag,\n        kNumberAnyFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag | kUintFlag | kUint64Flag | kDoubleFlag,\n        kConstStringFlag = kStringType | kStringFlag,\n        kCopyStringFlag = kStringType | kStringFlag | kCopyFlag,\n        kShortStringFlag = kStringType | kStringFlag | kCopyFlag | kInlineStrFlag,\n        kObjectFlag = kObjectType,\n        kArrayFlag = kArrayType,\n\n        kTypeMask = 0x07\n    };\n\n    static const SizeType kDefaultArrayCapacity = 16;\n    static const SizeType kDefaultObjectCapacity = 16;\n\n    struct Flag {\n#if RAPIDJSON_48BITPOINTER_OPTIMIZATION\n        char payload[sizeof(SizeType) * 2 + 6];     // 2 x SizeType + lower 48-bit pointer\n#elif RAPIDJSON_64BIT\n        char payload[sizeof(SizeType) * 2 + sizeof(void*) + 6]; // 6 padding bytes\n#else\n        char payload[sizeof(SizeType) * 2 + sizeof(void*) + 2]; // 2 padding bytes\n#endif\n        uint16_t flags;\n    };\n\n    struct String {\n        SizeType length;\n        SizeType hashcode;  //!< reserved\n        const Ch* str;\n    };  // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode\n\n    // implementation detail: ShortString can represent zero-terminated strings up to MaxSize chars\n    // (excluding the terminating zero) and store a value to determine the length of the contained\n    // string in the last character str[LenPos] by storing \"MaxSize - length\" there. If the string\n    // to store has the maximal length of MaxSize then str[LenPos] will be 0 and therefore act as\n    // the string terminator as well. For getting the string length back from that value just use\n    // \"MaxSize - str[LenPos]\".\n    // This allows to store 13-chars strings in 32-bit mode, 21-chars strings in 64-bit mode,\n    // 13-chars strings for RAPIDJSON_48BITPOINTER_OPTIMIZATION=1 inline (for `UTF8`-encoded strings).\n    struct ShortString {\n        enum { MaxChars = sizeof(static_cast<Flag*>(0)->payload) / sizeof(Ch), MaxSize = MaxChars - 1, LenPos = MaxSize };\n        Ch str[MaxChars];\n\n        inline static bool Usable(SizeType len) { return                       (MaxSize >= len); }\n        inline void     SetLength(SizeType len) { str[LenPos] = static_cast<Ch>(MaxSize -  len); }\n        inline SizeType GetLength() const       { return  static_cast<SizeType>(MaxSize -  str[LenPos]); }\n    };  // at most as many bytes as \"String\" above => 12 bytes in 32-bit mode, 16 bytes in 64-bit mode\n\n    // By using proper binary layout, retrieval of different integer types do not need conversions.\n    union Number {\n#if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN\n        struct I {\n            int i;\n            char padding[4];\n        }i;\n        struct U {\n            unsigned u;\n            char padding2[4];\n        }u;\n#else\n        struct I {\n            char padding[4];\n            int i;\n        }i;\n        struct U {\n            char padding2[4];\n            unsigned u;\n        }u;\n#endif\n        int64_t i64;\n        uint64_t u64;\n        double d;\n    };  // 8 bytes\n\n    struct ObjectData {\n        SizeType size;\n        SizeType capacity;\n        Member* members;\n    };  // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode\n\n    struct ArrayData {\n        SizeType size;\n        SizeType capacity;\n        GenericValue* elements;\n    };  // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode\n\n    union Data {\n        String s;\n        ShortString ss;\n        Number n;\n        ObjectData o;\n        ArrayData a;\n        Flag f;\n    };  // 16 bytes in 32-bit mode, 24 bytes in 64-bit mode, 16 bytes in 64-bit with RAPIDJSON_48BITPOINTER_OPTIMIZATION\n\n    RAPIDJSON_FORCEINLINE const Ch* GetStringPointer() const { return RAPIDJSON_GETPOINTER(Ch, data_.s.str); }\n    RAPIDJSON_FORCEINLINE const Ch* SetStringPointer(const Ch* str) { return RAPIDJSON_SETPOINTER(Ch, data_.s.str, str); }\n    RAPIDJSON_FORCEINLINE GenericValue* GetElementsPointer() const { return RAPIDJSON_GETPOINTER(GenericValue, data_.a.elements); }\n    RAPIDJSON_FORCEINLINE GenericValue* SetElementsPointer(GenericValue* elements) { return RAPIDJSON_SETPOINTER(GenericValue, data_.a.elements, elements); }\n    RAPIDJSON_FORCEINLINE Member* GetMembersPointer() const { return RAPIDJSON_GETPOINTER(Member, data_.o.members); }\n    RAPIDJSON_FORCEINLINE Member* SetMembersPointer(Member* members) { return RAPIDJSON_SETPOINTER(Member, data_.o.members, members); }\n\n    // Initialize this value as array with initial data, without calling destructor.\n    void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) {\n        data_.f.flags = kArrayFlag;\n        if (count) {\n            GenericValue* e = static_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));\n            SetElementsPointer(e);\n            std::memcpy(e, values, count * sizeof(GenericValue));\n        }\n        else\n            SetElementsPointer(0);\n        data_.a.size = data_.a.capacity = count;\n    }\n\n    //! Initialize this value as object with initial data, without calling destructor.\n    void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) {\n        data_.f.flags = kObjectFlag;\n        if (count) {\n            Member* m = static_cast<Member*>(allocator.Malloc(count * sizeof(Member)));\n            SetMembersPointer(m);\n            std::memcpy(m, members, count * sizeof(Member));\n        }\n        else\n            SetMembersPointer(0);\n        data_.o.size = data_.o.capacity = count;\n    }\n\n    //! Initialize this value as constant string, without calling destructor.\n    void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT {\n        data_.f.flags = kConstStringFlag;\n        SetStringPointer(s);\n        data_.s.length = s.length;\n    }\n\n    //! Initialize this value as copy string with initial data, without calling destructor.\n    void SetStringRaw(StringRefType s, Allocator& allocator) {\n        Ch* str = 0;\n        if (ShortString::Usable(s.length)) {\n            data_.f.flags = kShortStringFlag;\n            data_.ss.SetLength(s.length);\n            str = data_.ss.str;\n        } else {\n            data_.f.flags = kCopyStringFlag;\n            data_.s.length = s.length;\n            str = static_cast<Ch *>(allocator.Malloc((s.length + 1) * sizeof(Ch)));\n            SetStringPointer(str);\n        }\n        std::memcpy(str, s, s.length * sizeof(Ch));\n        str[s.length] = '\\0';\n    }\n\n    //! Assignment without calling destructor\n    void RawAssign(GenericValue& rhs) RAPIDJSON_NOEXCEPT {\n        data_ = rhs.data_;\n        // data_.f.flags = rhs.data_.f.flags;\n        rhs.data_.f.flags = kNullFlag;\n    }\n\n    template <typename SourceAllocator>\n    bool StringEqual(const GenericValue<Encoding, SourceAllocator>& rhs) const {\n        RAPIDJSON_ASSERT(IsString());\n        RAPIDJSON_ASSERT(rhs.IsString());\n\n        const SizeType len1 = GetStringLength();\n        const SizeType len2 = rhs.GetStringLength();\n        if(len1 != len2) { return false; }\n\n        const Ch* const str1 = GetString();\n        const Ch* const str2 = rhs.GetString();\n        if(str1 == str2) { return true; } // fast path for constant string\n\n        return (std::memcmp(str1, str2, sizeof(Ch) * len1) == 0);\n    }\n\n    Data data_;\n};\n\n//! GenericValue with UTF8 encoding\ntypedef GenericValue<UTF8<> > Value;\n\n///////////////////////////////////////////////////////////////////////////////\n// GenericDocument \n\n//! A document for parsing JSON text as DOM.\n/*!\n    \\note implements Handler concept\n    \\tparam Encoding Encoding for both parsing and string storage.\n    \\tparam Allocator Allocator for allocating memory for the DOM\n    \\tparam StackAllocator Allocator for allocating memory for stack during parsing.\n    \\warning Although GenericDocument inherits from GenericValue, the API does \\b not provide any virtual functions, especially no virtual destructor.  To avoid memory leaks, do not \\c delete a GenericDocument object via a pointer to a GenericValue.\n*/\ntemplate <typename Encoding, typename Allocator = MemoryPoolAllocator<>, typename StackAllocator = CrtAllocator>\nclass GenericDocument : public GenericValue<Encoding, Allocator> {\npublic:\n    typedef typename Encoding::Ch Ch;                       //!< Character type derived from Encoding.\n    typedef GenericValue<Encoding, Allocator> ValueType;    //!< Value type of the document.\n    typedef Allocator AllocatorType;                        //!< Allocator type from template parameter.\n\n    //! Constructor\n    /*! Creates an empty document of specified type.\n        \\param type             Mandatory type of object to create.\n        \\param allocator        Optional allocator for allocating memory.\n        \\param stackCapacity    Optional initial capacity of stack in bytes.\n        \\param stackAllocator   Optional allocator for allocating memory for stack.\n    */\n    explicit GenericDocument(Type type, Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :\n        GenericValue<Encoding, Allocator>(type),  allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()\n    {\n        if (!allocator_)\n            ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator());\n    }\n\n    //! Constructor\n    /*! Creates an empty document which type is Null. \n        \\param allocator        Optional allocator for allocating memory.\n        \\param stackCapacity    Optional initial capacity of stack in bytes.\n        \\param stackAllocator   Optional allocator for allocating memory for stack.\n    */\n    GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) : \n        allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()\n    {\n        if (!allocator_)\n            ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator());\n    }\n\n#if RAPIDJSON_HAS_CXX11_RVALUE_REFS\n    //! Move constructor in C++11\n    GenericDocument(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT\n        : ValueType(std::forward<ValueType>(rhs)), // explicit cast to avoid prohibited move from Document\n          allocator_(rhs.allocator_),\n          ownAllocator_(rhs.ownAllocator_),\n          stack_(std::move(rhs.stack_)),\n          parseResult_(rhs.parseResult_)\n    {\n        rhs.allocator_ = 0;\n        rhs.ownAllocator_ = 0;\n        rhs.parseResult_ = ParseResult();\n    }\n#endif\n\n    ~GenericDocument() {\n        Destroy();\n    }\n\n#if RAPIDJSON_HAS_CXX11_RVALUE_REFS\n    //! Move assignment in C++11\n    GenericDocument& operator=(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT\n    {\n        // The cast to ValueType is necessary here, because otherwise it would\n        // attempt to call GenericValue's templated assignment operator.\n        ValueType::operator=(std::forward<ValueType>(rhs));\n\n        // Calling the destructor here would prematurely call stack_'s destructor\n        Destroy();\n\n        allocator_ = rhs.allocator_;\n        ownAllocator_ = rhs.ownAllocator_;\n        stack_ = std::move(rhs.stack_);\n        parseResult_ = rhs.parseResult_;\n\n        rhs.allocator_ = 0;\n        rhs.ownAllocator_ = 0;\n        rhs.parseResult_ = ParseResult();\n\n        return *this;\n    }\n#endif\n\n    //! Exchange the contents of this document with those of another.\n    /*!\n        \\param rhs Another document.\n        \\note Constant complexity.\n        \\see GenericValue::Swap\n    */\n    GenericDocument& Swap(GenericDocument& rhs) RAPIDJSON_NOEXCEPT {\n        ValueType::Swap(rhs);\n        stack_.Swap(rhs.stack_);\n        internal::Swap(allocator_, rhs.allocator_);\n        internal::Swap(ownAllocator_, rhs.ownAllocator_);\n        internal::Swap(parseResult_, rhs.parseResult_);\n        return *this;\n    }\n\n    //! free-standing swap function helper\n    /*!\n        Helper function to enable support for common swap implementation pattern based on \\c std::swap:\n        \\code\n        void swap(MyClass& a, MyClass& b) {\n            using std::swap;\n            swap(a.doc, b.doc);\n            // ...\n        }\n        \\endcode\n        \\see Swap()\n     */\n    friend inline void swap(GenericDocument& a, GenericDocument& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }\n\n    //! Populate this document by a generator which produces SAX events.\n    /*! \\tparam Generator A functor with <tt>bool f(Handler)</tt> prototype.\n        \\param g Generator functor which sends SAX events to the parameter.\n        \\return The document itself for fluent API.\n    */\n    template <typename Generator>\n    GenericDocument& Populate(Generator& g) {\n        ClearStackOnExit scope(*this);\n        if (g(*this)) {\n            RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object\n            ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document\n        }\n        return *this;\n    }\n\n    //!@name Parse from stream\n    //!@{\n\n    //! Parse JSON text from an input stream (with Encoding conversion)\n    /*! \\tparam parseFlags Combination of \\ref ParseFlag.\n        \\tparam SourceEncoding Encoding of input stream\n        \\tparam InputStream Type of input stream, implementing Stream concept\n        \\param is Input stream to be parsed.\n        \\return The document itself for fluent API.\n    */\n    template <unsigned parseFlags, typename SourceEncoding, typename InputStream>\n    GenericDocument& ParseStream(InputStream& is) {\n        GenericReader<SourceEncoding, Encoding, StackAllocator> reader(\n            stack_.HasAllocator() ? &stack_.GetAllocator() : 0);\n        ClearStackOnExit scope(*this);\n        parseResult_ = reader.template Parse<parseFlags>(is, *this);\n        if (parseResult_) {\n            RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object\n            ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document\n        }\n        return *this;\n    }\n\n    //! Parse JSON text from an input stream\n    /*! \\tparam parseFlags Combination of \\ref ParseFlag.\n        \\tparam InputStream Type of input stream, implementing Stream concept\n        \\param is Input stream to be parsed.\n        \\return The document itself for fluent API.\n    */\n    template <unsigned parseFlags, typename InputStream>\n    GenericDocument& ParseStream(InputStream& is) {\n        return ParseStream<parseFlags, Encoding, InputStream>(is);\n    }\n\n    //! Parse JSON text from an input stream (with \\ref kParseDefaultFlags)\n    /*! \\tparam InputStream Type of input stream, implementing Stream concept\n        \\param is Input stream to be parsed.\n        \\return The document itself for fluent API.\n    */\n    template <typename InputStream>\n    GenericDocument& ParseStream(InputStream& is) {\n        return ParseStream<kParseDefaultFlags, Encoding, InputStream>(is);\n    }\n    //!@}\n\n    //!@name Parse in-place from mutable string\n    //!@{\n\n    //! Parse JSON text from a mutable string\n    /*! \\tparam parseFlags Combination of \\ref ParseFlag.\n        \\param str Mutable zero-terminated string to be parsed.\n        \\return The document itself for fluent API.\n    */\n    template <unsigned parseFlags>\n    GenericDocument& ParseInsitu(Ch* str) {\n        GenericInsituStringStream<Encoding> s(str);\n        return ParseStream<parseFlags | kParseInsituFlag>(s);\n    }\n\n    //! Parse JSON text from a mutable string (with \\ref kParseDefaultFlags)\n    /*! \\param str Mutable zero-terminated string to be parsed.\n        \\return The document itself for fluent API.\n    */\n    GenericDocument& ParseInsitu(Ch* str) {\n        return ParseInsitu<kParseDefaultFlags>(str);\n    }\n    //!@}\n\n    //!@name Parse from read-only string\n    //!@{\n\n    //! Parse JSON text from a read-only string (with Encoding conversion)\n    /*! \\tparam parseFlags Combination of \\ref ParseFlag (must not contain \\ref kParseInsituFlag).\n        \\tparam SourceEncoding Transcoding from input Encoding\n        \\param str Read-only zero-terminated string to be parsed.\n    */\n    template <unsigned parseFlags, typename SourceEncoding>\n    GenericDocument& Parse(const typename SourceEncoding::Ch* str) {\n        RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));\n        GenericStringStream<SourceEncoding> s(str);\n        return ParseStream<parseFlags, SourceEncoding>(s);\n    }\n\n    //! Parse JSON text from a read-only string\n    /*! \\tparam parseFlags Combination of \\ref ParseFlag (must not contain \\ref kParseInsituFlag).\n        \\param str Read-only zero-terminated string to be parsed.\n    */\n    template <unsigned parseFlags>\n    GenericDocument& Parse(const Ch* str) {\n        return Parse<parseFlags, Encoding>(str);\n    }\n\n    //! Parse JSON text from a read-only string (with \\ref kParseDefaultFlags)\n    /*! \\param str Read-only zero-terminated string to be parsed.\n    */\n    GenericDocument& Parse(const Ch* str) {\n        return Parse<kParseDefaultFlags>(str);\n    }\n\n    template <unsigned parseFlags, typename SourceEncoding>\n    GenericDocument& Parse(const typename SourceEncoding::Ch* str, size_t length) {\n        RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));\n        MemoryStream ms(static_cast<const char*>(str), length * sizeof(typename SourceEncoding::Ch));\n        EncodedInputStream<SourceEncoding, MemoryStream> is(ms);\n        ParseStream<parseFlags, SourceEncoding>(is);\n        return *this;\n    }\n\n    template <unsigned parseFlags>\n    GenericDocument& Parse(const Ch* str, size_t length) {\n        return Parse<parseFlags, Encoding>(str, length);\n    }\n    \n    GenericDocument& Parse(const Ch* str, size_t length) {\n        return Parse<kParseDefaultFlags>(str, length);\n    }\n\n#if RAPIDJSON_HAS_STDSTRING\n    template <unsigned parseFlags, typename SourceEncoding>\n    GenericDocument& Parse(const std::basic_string<typename SourceEncoding::Ch>& str) {\n        // c_str() is constant complexity according to standard. Should be faster than Parse(const char*, size_t)\n        return Parse<parseFlags, SourceEncoding>(str.c_str());\n    }\n\n    template <unsigned parseFlags>\n    GenericDocument& Parse(const std::basic_string<Ch>& str) {\n        return Parse<parseFlags, Encoding>(str.c_str());\n    }\n\n    GenericDocument& Parse(const std::basic_string<Ch>& str) {\n        return Parse<kParseDefaultFlags>(str);\n    }\n#endif // RAPIDJSON_HAS_STDSTRING    \n\n    //!@}\n\n    //!@name Handling parse errors\n    //!@{\n\n    //! Whether a parse error has occured in the last parsing.\n    bool HasParseError() const { return parseResult_.IsError(); }\n\n    //! Get the \\ref ParseErrorCode of last parsing.\n    ParseErrorCode GetParseError() const { return parseResult_.Code(); }\n\n    //! Get the position of last parsing error in input, 0 otherwise.\n    size_t GetErrorOffset() const { return parseResult_.Offset(); }\n\n    //! Implicit conversion to get the last parse result\n#ifndef __clang // -Wdocumentation\n    /*! \\return \\ref ParseResult of the last parse operation\n\n        \\code\n          Document doc;\n          ParseResult ok = doc.Parse(json);\n          if (!ok)\n            printf( \"JSON parse error: %s (%u)\\n\", GetParseError_En(ok.Code()), ok.Offset());\n        \\endcode\n     */\n#endif\n    operator ParseResult() const { return parseResult_; }\n    //!@}\n\n    //! Get the allocator of this document.\n    Allocator& GetAllocator() {\n        RAPIDJSON_ASSERT(allocator_);\n        return *allocator_;\n    }\n\n    //! Get the capacity of stack in bytes.\n    size_t GetStackCapacity() const { return stack_.GetCapacity(); }\n\nprivate:\n    // clear stack on any exit from ParseStream, e.g. due to exception\n    struct ClearStackOnExit {\n        explicit ClearStackOnExit(GenericDocument& d) : d_(d) {}\n        ~ClearStackOnExit() { d_.ClearStack(); }\n    private:\n        ClearStackOnExit(const ClearStackOnExit&);\n        ClearStackOnExit& operator=(const ClearStackOnExit&);\n        GenericDocument& d_;\n    };\n\n    // callers of the following private Handler functions\n    // template <typename,typename,typename> friend class GenericReader; // for parsing\n    template <typename, typename> friend class GenericValue; // for deep copying\n\npublic:\n    // Implementation of Handler\n    bool Null() { new (stack_.template Push<ValueType>()) ValueType(); return true; }\n    bool Bool(bool b) { new (stack_.template Push<ValueType>()) ValueType(b); return true; }\n    bool Int(int i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }\n    bool Uint(unsigned i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }\n    bool Int64(int64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }\n    bool Uint64(uint64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }\n    bool Double(double d) { new (stack_.template Push<ValueType>()) ValueType(d); return true; }\n\n    bool RawNumber(const Ch* str, SizeType length, bool copy) { \n        if (copy) \n            new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());\n        else\n            new (stack_.template Push<ValueType>()) ValueType(str, length);\n        return true;\n    }\n\n    bool String(const Ch* str, SizeType length, bool copy) { \n        if (copy) \n            new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());\n        else\n            new (stack_.template Push<ValueType>()) ValueType(str, length);\n        return true;\n    }\n\n    bool StartObject() { new (stack_.template Push<ValueType>()) ValueType(kObjectType); return true; }\n    \n    bool Key(const Ch* str, SizeType length, bool copy) { return String(str, length, copy); }\n\n    bool EndObject(SizeType memberCount) {\n        typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount);\n        stack_.template Top<ValueType>()->SetObjectRaw(members, memberCount, GetAllocator());\n        return true;\n    }\n\n    bool StartArray() { new (stack_.template Push<ValueType>()) ValueType(kArrayType); return true; }\n    \n    bool EndArray(SizeType elementCount) {\n        ValueType* elements = stack_.template Pop<ValueType>(elementCount);\n        stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount, GetAllocator());\n        return true;\n    }\n\nprivate:\n    //! Prohibit copying\n    GenericDocument(const GenericDocument&);\n    //! Prohibit assignment\n    GenericDocument& operator=(const GenericDocument&);\n\n    void ClearStack() {\n        if (Allocator::kNeedFree)\n            while (stack_.GetSize() > 0)    // Here assumes all elements in stack array are GenericValue (Member is actually 2 GenericValue objects)\n                (stack_.template Pop<ValueType>(1))->~ValueType();\n        else\n            stack_.Clear();\n        stack_.ShrinkToFit();\n    }\n\n    void Destroy() {\n        RAPIDJSON_DELETE(ownAllocator_);\n    }\n\n    static const size_t kDefaultStackCapacity = 1024;\n    Allocator* allocator_;\n    Allocator* ownAllocator_;\n    internal::Stack<StackAllocator> stack_;\n    ParseResult parseResult_;\n};\n\n//! GenericDocument with UTF8 encoding\ntypedef GenericDocument<UTF8<> > Document;\n\n//! Helper class for accessing Value of array type.\n/*!\n    Instance of this helper class is obtained by \\c GenericValue::GetArray().\n    In addition to all APIs for array type, it provides range-based for loop if \\c RAPIDJSON_HAS_CXX11_RANGE_FOR=1.\n*/\ntemplate <bool Const, typename ValueT>\nclass GenericArray {\npublic:\n    typedef GenericArray<true, ValueT> ConstArray;\n    typedef GenericArray<false, ValueT> Array;\n    typedef ValueT PlainType;\n    typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;\n    typedef ValueType* ValueIterator;  // This may be const or non-const iterator\n    typedef const ValueT* ConstValueIterator;\n    typedef typename ValueType::AllocatorType AllocatorType;\n    typedef typename ValueType::StringRefType StringRefType;\n\n    template <typename, typename>\n    friend class GenericValue;\n\n    GenericArray(const GenericArray& rhs) : value_(rhs.value_) {}\n    GenericArray& operator=(const GenericArray& rhs) { value_ = rhs.value_; return *this; }\n    ~GenericArray() {}\n\n    SizeType Size() const { return value_.Size(); }\n    SizeType Capacity() const { return value_.Capacity(); }\n    bool Empty() const { return value_.Empty(); }\n    void Clear() const { value_.Clear(); }\n    ValueType& operator[](SizeType index) const {  return value_[index]; }\n    ValueIterator Begin() const { return value_.Begin(); }\n    ValueIterator End() const { return value_.End(); }\n    GenericArray Reserve(SizeType newCapacity, AllocatorType &allocator) const { value_.Reserve(newCapacity, allocator); return *this; }\n    GenericArray PushBack(ValueType& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }\n#if RAPIDJSON_HAS_CXX11_RVALUE_REFS\n    GenericArray PushBack(ValueType&& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }\n#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS\n    GenericArray PushBack(StringRefType value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }\n    template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (const GenericArray&)) PushBack(T value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }\n    GenericArray PopBack() const { value_.PopBack(); return *this; }\n    ValueIterator Erase(ConstValueIterator pos) const { return value_.Erase(pos); }\n    ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) const { return value_.Erase(first, last); }\n\n#if RAPIDJSON_HAS_CXX11_RANGE_FOR\n    ValueIterator begin() const { return value_.Begin(); }\n    ValueIterator end() const { return value_.End(); }\n#endif\n\nprivate:\n    GenericArray();\n    GenericArray(ValueType& value) : value_(value) {}\n    ValueType& value_;\n};\n\n//! Helper class for accessing Value of object type.\n/*!\n    Instance of this helper class is obtained by \\c GenericValue::GetObject().\n    In addition to all APIs for array type, it provides range-based for loop if \\c RAPIDJSON_HAS_CXX11_RANGE_FOR=1.\n*/\ntemplate <bool Const, typename ValueT>\nclass GenericObject {\npublic:\n    typedef GenericObject<true, ValueT> ConstObject;\n    typedef GenericObject<false, ValueT> Object;\n    typedef ValueT PlainType;\n    typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;\n    typedef GenericMemberIterator<Const, typename ValueT::EncodingType, typename ValueT::AllocatorType> MemberIterator;  // This may be const or non-const iterator\n    typedef GenericMemberIterator<true, typename ValueT::EncodingType, typename ValueT::AllocatorType> ConstMemberIterator;\n    typedef typename ValueType::AllocatorType AllocatorType;\n    typedef typename ValueType::StringRefType StringRefType;\n    typedef typename ValueType::EncodingType EncodingType;\n    typedef typename ValueType::Ch Ch;\n\n    template <typename, typename>\n    friend class GenericValue;\n\n    GenericObject(const GenericObject& rhs) : value_(rhs.value_) {}\n    GenericObject& operator=(const GenericObject& rhs) { value_ = rhs.value_; return *this; }\n    ~GenericObject() {}\n\n    SizeType MemberCount() const { return value_.MemberCount(); }\n    bool ObjectEmpty() const { return value_.ObjectEmpty(); }\n    template <typename T> ValueType& operator[](T* name) const { return value_[name]; }\n    template <typename SourceAllocator> ValueType& operator[](const GenericValue<EncodingType, SourceAllocator>& name) const { return value_[name]; }\n#if RAPIDJSON_HAS_STDSTRING\n    ValueType& operator[](const std::basic_string<Ch>& name) const { return value_[name]; }\n#endif\n    MemberIterator MemberBegin() const { return value_.MemberBegin(); }\n    MemberIterator MemberEnd() const { return value_.MemberEnd(); }\n    bool HasMember(const Ch* name) const { return value_.HasMember(name); }\n#if RAPIDJSON_HAS_STDSTRING\n    bool HasMember(const std::basic_string<Ch>& name) const { return value_.HasMember(name); }\n#endif\n    template <typename SourceAllocator> bool HasMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.HasMember(name); }\n    MemberIterator FindMember(const Ch* name) const { return value_.FindMember(name); }\n    template <typename SourceAllocator> MemberIterator FindMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.FindMember(name); }\n#if RAPIDJSON_HAS_STDSTRING\n    MemberIterator FindMember(const std::basic_string<Ch>& name) const { return value_.FindMember(name); }\n#endif\n    GenericObject AddMember(ValueType& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }\n    GenericObject AddMember(ValueType& name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }\n#if RAPIDJSON_HAS_STDSTRING\n    GenericObject AddMember(ValueType& name, std::basic_string<Ch>& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }\n#endif\n    template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&)) AddMember(ValueType& name, T value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }\n#if RAPIDJSON_HAS_CXX11_RVALUE_REFS\n    GenericObject AddMember(ValueType&& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }\n    GenericObject AddMember(ValueType&& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }\n    GenericObject AddMember(ValueType& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }\n    GenericObject AddMember(StringRefType name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }\n#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS\n    GenericObject AddMember(StringRefType name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }\n    GenericObject AddMember(StringRefType name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }\n    template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericObject)) AddMember(StringRefType name, T value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }\n    void RemoveAllMembers() { return value_.RemoveAllMembers(); }\n    bool RemoveMember(const Ch* name) const { return value_.RemoveMember(name); }\n#if RAPIDJSON_HAS_STDSTRING\n    bool RemoveMember(const std::basic_string<Ch>& name) const { return value_.RemoveMember(name); }\n#endif\n    template <typename SourceAllocator> bool RemoveMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.RemoveMember(name); }\n    MemberIterator RemoveMember(MemberIterator m) const { return value_.RemoveMember(m); }\n    MemberIterator EraseMember(ConstMemberIterator pos) const { return value_.EraseMember(pos); }\n    MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) const { return value_.EraseMember(first, last); }\n    bool EraseMember(const Ch* name) const { return value_.EraseMember(name); }\n#if RAPIDJSON_HAS_STDSTRING\n    bool EraseMember(const std::basic_string<Ch>& name) const { return EraseMember(ValueType(StringRef(name))); }\n#endif\n    template <typename SourceAllocator> bool EraseMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.EraseMember(name); }\n\n#if RAPIDJSON_HAS_CXX11_RANGE_FOR\n    MemberIterator begin() const { return value_.MemberBegin(); }\n    MemberIterator end() const { return value_.MemberEnd(); }\n#endif\n\nprivate:\n    GenericObject();\n    GenericObject(ValueType& value) : value_(value) {}\n    ValueType& value_;\n};\n\nRAPIDJSON_NAMESPACE_END\n#ifdef _MINWINDEF_       // see: http://stackoverflow.com/questions/22744262/cant-call-stdmax-because-minwindef-h-defines-max\n#ifndef NOMINMAX\n#pragma pop_macro(\"min\")\n#pragma pop_macro(\"max\")\n#endif\n#endif\nRAPIDJSON_DIAG_POP\n\n#endif // RAPIDJSON_DOCUMENT_H_\n"
  },
  {
    "path": "rapidjson/encodedstream.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_ENCODEDSTREAM_H_\n#define RAPIDJSON_ENCODEDSTREAM_H_\n\n#include \"stream.h\"\n#include \"memorystream.h\"\n\n#ifdef __GNUC__\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(effc++)\n#endif\n\n#ifdef __clang__\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(padded)\n#endif\n\nRAPIDJSON_NAMESPACE_BEGIN\n\n//! Input byte stream wrapper with a statically bound encoding.\n/*!\n    \\tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE.\n    \\tparam InputByteStream Type of input byte stream. For example, FileReadStream.\n*/\ntemplate <typename Encoding, typename InputByteStream>\nclass EncodedInputStream {\n    RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);\npublic:\n    typedef typename Encoding::Ch Ch;\n\n    EncodedInputStream(InputByteStream& is) : is_(is) { \n        current_ = Encoding::TakeBOM(is_);\n    }\n\n    Ch Peek() const { return current_; }\n    Ch Take() { Ch c = current_; current_ = Encoding::Take(is_); return c; }\n    size_t Tell() const { return is_.Tell(); }\n\n    // Not implemented\n    void Put(Ch) { RAPIDJSON_ASSERT(false); }\n    void Flush() { RAPIDJSON_ASSERT(false); } \n    Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }\n    size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }\n\nprivate:\n    EncodedInputStream(const EncodedInputStream&);\n    EncodedInputStream& operator=(const EncodedInputStream&);\n\n    InputByteStream& is_;\n    Ch current_;\n};\n\n//! Specialized for UTF8 MemoryStream.\ntemplate <>\nclass EncodedInputStream<UTF8<>, MemoryStream> {\npublic:\n    typedef UTF8<>::Ch Ch;\n\n    EncodedInputStream(MemoryStream& is) : is_(is) {\n        if (static_cast<unsigned char>(is_.Peek()) == 0xEFu) is_.Take();\n        if (static_cast<unsigned char>(is_.Peek()) == 0xBBu) is_.Take();\n        if (static_cast<unsigned char>(is_.Peek()) == 0xBFu) is_.Take();\n    }\n    Ch Peek() const { return is_.Peek(); }\n    Ch Take() { return is_.Take(); }\n    size_t Tell() const { return is_.Tell(); }\n\n    // Not implemented\n    void Put(Ch) {}\n    void Flush() {} \n    Ch* PutBegin() { return 0; }\n    size_t PutEnd(Ch*) { return 0; }\n\n    MemoryStream& is_;\n\nprivate:\n    EncodedInputStream(const EncodedInputStream&);\n    EncodedInputStream& operator=(const EncodedInputStream&);\n};\n\n//! Output byte stream wrapper with statically bound encoding.\n/*!\n    \\tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE.\n    \\tparam OutputByteStream Type of input byte stream. For example, FileWriteStream.\n*/\ntemplate <typename Encoding, typename OutputByteStream>\nclass EncodedOutputStream {\n    RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);\npublic:\n    typedef typename Encoding::Ch Ch;\n\n    EncodedOutputStream(OutputByteStream& os, bool putBOM = true) : os_(os) { \n        if (putBOM)\n            Encoding::PutBOM(os_);\n    }\n\n    void Put(Ch c) { Encoding::Put(os_, c);  }\n    void Flush() { os_.Flush(); }\n\n    // Not implemented\n    Ch Peek() const { RAPIDJSON_ASSERT(false); return 0;}\n    Ch Take() { RAPIDJSON_ASSERT(false); return 0;}\n    size_t Tell() const { RAPIDJSON_ASSERT(false);  return 0; }\n    Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }\n    size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }\n\nprivate:\n    EncodedOutputStream(const EncodedOutputStream&);\n    EncodedOutputStream& operator=(const EncodedOutputStream&);\n\n    OutputByteStream& os_;\n};\n\n#define RAPIDJSON_ENCODINGS_FUNC(x) UTF8<Ch>::x, UTF16LE<Ch>::x, UTF16BE<Ch>::x, UTF32LE<Ch>::x, UTF32BE<Ch>::x\n\n//! Input stream wrapper with dynamically bound encoding and automatic encoding detection.\n/*!\n    \\tparam CharType Type of character for reading.\n    \\tparam InputByteStream type of input byte stream to be wrapped.\n*/\ntemplate <typename CharType, typename InputByteStream>\nclass AutoUTFInputStream {\n    RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);\npublic:\n    typedef CharType Ch;\n\n    //! Constructor.\n    /*!\n        \\param is input stream to be wrapped.\n        \\param type UTF encoding type if it is not detected from the stream.\n    */\n    AutoUTFInputStream(InputByteStream& is, UTFType type = kUTF8) : is_(&is), type_(type), hasBOM_(false) {\n        RAPIDJSON_ASSERT(type >= kUTF8 && type <= kUTF32BE);        \n        DetectType();\n        static const TakeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Take) };\n        takeFunc_ = f[type_];\n        current_ = takeFunc_(*is_);\n    }\n\n    UTFType GetType() const { return type_; }\n    bool HasBOM() const { return hasBOM_; }\n\n    Ch Peek() const { return current_; }\n    Ch Take() { Ch c = current_; current_ = takeFunc_(*is_); return c; }\n    size_t Tell() const { return is_->Tell(); }\n\n    // Not implemented\n    void Put(Ch) { RAPIDJSON_ASSERT(false); }\n    void Flush() { RAPIDJSON_ASSERT(false); } \n    Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }\n    size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }\n\nprivate:\n    AutoUTFInputStream(const AutoUTFInputStream&);\n    AutoUTFInputStream& operator=(const AutoUTFInputStream&);\n\n    // Detect encoding type with BOM or RFC 4627\n    void DetectType() {\n        // BOM (Byte Order Mark):\n        // 00 00 FE FF  UTF-32BE\n        // FF FE 00 00  UTF-32LE\n        // FE FF        UTF-16BE\n        // FF FE        UTF-16LE\n        // EF BB BF     UTF-8\n\n        const unsigned char* c = reinterpret_cast<const unsigned char *>(is_->Peek4());\n        if (!c)\n            return;\n\n        unsigned bom = static_cast<unsigned>(c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24));\n        hasBOM_ = false;\n        if (bom == 0xFFFE0000)                  { type_ = kUTF32BE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); }\n        else if (bom == 0x0000FEFF)             { type_ = kUTF32LE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); }\n        else if ((bom & 0xFFFF) == 0xFFFE)      { type_ = kUTF16BE; hasBOM_ = true; is_->Take(); is_->Take();                           }\n        else if ((bom & 0xFFFF) == 0xFEFF)      { type_ = kUTF16LE; hasBOM_ = true; is_->Take(); is_->Take();                           }\n        else if ((bom & 0xFFFFFF) == 0xBFBBEF)  { type_ = kUTF8;    hasBOM_ = true; is_->Take(); is_->Take(); is_->Take();              }\n\n        // RFC 4627: Section 3\n        // \"Since the first two characters of a JSON text will always be ASCII\n        // characters [RFC0020], it is possible to determine whether an octet\n        // stream is UTF-8, UTF-16 (BE or LE), or UTF-32 (BE or LE) by looking\n        // at the pattern of nulls in the first four octets.\"\n        // 00 00 00 xx  UTF-32BE\n        // 00 xx 00 xx  UTF-16BE\n        // xx 00 00 00  UTF-32LE\n        // xx 00 xx 00  UTF-16LE\n        // xx xx xx xx  UTF-8\n\n        if (!hasBOM_) {\n            unsigned pattern = (c[0] ? 1 : 0) | (c[1] ? 2 : 0) | (c[2] ? 4 : 0) | (c[3] ? 8 : 0);\n            switch (pattern) {\n            case 0x08: type_ = kUTF32BE; break;\n            case 0x0A: type_ = kUTF16BE; break;\n            case 0x01: type_ = kUTF32LE; break;\n            case 0x05: type_ = kUTF16LE; break;\n            case 0x0F: type_ = kUTF8;    break;\n            default: break; // Use type defined by user.\n            }\n        }\n\n        // Runtime check whether the size of character type is sufficient. It only perform checks with assertion.\n        if (type_ == kUTF16LE || type_ == kUTF16BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 2);\n        if (type_ == kUTF32LE || type_ == kUTF32BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 4);\n    }\n\n    typedef Ch (*TakeFunc)(InputByteStream& is);\n    InputByteStream* is_;\n    UTFType type_;\n    Ch current_;\n    TakeFunc takeFunc_;\n    bool hasBOM_;\n};\n\n//! Output stream wrapper with dynamically bound encoding and automatic encoding detection.\n/*!\n    \\tparam CharType Type of character for writing.\n    \\tparam OutputByteStream type of output byte stream to be wrapped.\n*/\ntemplate <typename CharType, typename OutputByteStream>\nclass AutoUTFOutputStream {\n    RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);\npublic:\n    typedef CharType Ch;\n\n    //! Constructor.\n    /*!\n        \\param os output stream to be wrapped.\n        \\param type UTF encoding type.\n        \\param putBOM Whether to write BOM at the beginning of the stream.\n    */\n    AutoUTFOutputStream(OutputByteStream& os, UTFType type, bool putBOM) : os_(&os), type_(type) {\n        RAPIDJSON_ASSERT(type >= kUTF8 && type <= kUTF32BE);\n\n        // Runtime check whether the size of character type is sufficient. It only perform checks with assertion.\n        if (type_ == kUTF16LE || type_ == kUTF16BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 2);\n        if (type_ == kUTF32LE || type_ == kUTF32BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 4);\n\n        static const PutFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Put) };\n        putFunc_ = f[type_];\n\n        if (putBOM)\n            PutBOM();\n    }\n\n    UTFType GetType() const { return type_; }\n\n    void Put(Ch c) { putFunc_(*os_, c); }\n    void Flush() { os_->Flush(); } \n\n    // Not implemented\n    Ch Peek() const { RAPIDJSON_ASSERT(false); return 0;}\n    Ch Take() { RAPIDJSON_ASSERT(false); return 0;}\n    size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }\n    Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }\n    size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }\n\nprivate:\n    AutoUTFOutputStream(const AutoUTFOutputStream&);\n    AutoUTFOutputStream& operator=(const AutoUTFOutputStream&);\n\n    void PutBOM() { \n        typedef void (*PutBOMFunc)(OutputByteStream&);\n        static const PutBOMFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(PutBOM) };\n        f[type_](*os_);\n    }\n\n    typedef void (*PutFunc)(OutputByteStream&, Ch);\n\n    OutputByteStream* os_;\n    UTFType type_;\n    PutFunc putFunc_;\n};\n\n#undef RAPIDJSON_ENCODINGS_FUNC\n\nRAPIDJSON_NAMESPACE_END\n\n#ifdef __clang__\nRAPIDJSON_DIAG_POP\n#endif\n\n#ifdef __GNUC__\nRAPIDJSON_DIAG_POP\n#endif\n\n#endif // RAPIDJSON_FILESTREAM_H_\n"
  },
  {
    "path": "rapidjson/encodings.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_ENCODINGS_H_\n#define RAPIDJSON_ENCODINGS_H_\n\n#include \"rapidjson.h\"\n\n#ifdef _MSC_VER\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(4244) // conversion from 'type1' to 'type2', possible loss of data\nRAPIDJSON_DIAG_OFF(4702)  // unreachable code\n#elif defined(__GNUC__)\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(effc++)\nRAPIDJSON_DIAG_OFF(overflow)\n#endif\n\nRAPIDJSON_NAMESPACE_BEGIN\n\n///////////////////////////////////////////////////////////////////////////////\n// Encoding\n\n/*! \\class rapidjson::Encoding\n    \\brief Concept for encoding of Unicode characters.\n\n\\code\nconcept Encoding {\n    typename Ch;    //! Type of character. A \"character\" is actually a code unit in unicode's definition.\n\n    enum { supportUnicode = 1 }; // or 0 if not supporting unicode\n\n    //! \\brief Encode a Unicode codepoint to an output stream.\n    //! \\param os Output stream.\n    //! \\param codepoint An unicode codepoint, ranging from 0x0 to 0x10FFFF inclusively.\n    template<typename OutputStream>\n    static void Encode(OutputStream& os, unsigned codepoint);\n\n    //! \\brief Decode a Unicode codepoint from an input stream.\n    //! \\param is Input stream.\n    //! \\param codepoint Output of the unicode codepoint.\n    //! \\return true if a valid codepoint can be decoded from the stream.\n    template <typename InputStream>\n    static bool Decode(InputStream& is, unsigned* codepoint);\n\n    //! \\brief Validate one Unicode codepoint from an encoded stream.\n    //! \\param is Input stream to obtain codepoint.\n    //! \\param os Output for copying one codepoint.\n    //! \\return true if it is valid.\n    //! \\note This function just validating and copying the codepoint without actually decode it.\n    template <typename InputStream, typename OutputStream>\n    static bool Validate(InputStream& is, OutputStream& os);\n\n    // The following functions are deal with byte streams.\n\n    //! Take a character from input byte stream, skip BOM if exist.\n    template <typename InputByteStream>\n    static CharType TakeBOM(InputByteStream& is);\n\n    //! Take a character from input byte stream.\n    template <typename InputByteStream>\n    static Ch Take(InputByteStream& is);\n\n    //! Put BOM to output byte stream.\n    template <typename OutputByteStream>\n    static void PutBOM(OutputByteStream& os);\n\n    //! Put a character to output byte stream.\n    template <typename OutputByteStream>\n    static void Put(OutputByteStream& os, Ch c);\n};\n\\endcode\n*/\n\n///////////////////////////////////////////////////////////////////////////////\n// UTF8\n\n//! UTF-8 encoding.\n/*! http://en.wikipedia.org/wiki/UTF-8\n    http://tools.ietf.org/html/rfc3629\n    \\tparam CharType Code unit for storing 8-bit UTF-8 data. Default is char.\n    \\note implements Encoding concept\n*/\ntemplate<typename CharType = char>\nstruct UTF8 {\n    typedef CharType Ch;\n\n    enum { supportUnicode = 1 };\n\n    template<typename OutputStream>\n    static void Encode(OutputStream& os, unsigned codepoint) {\n        if (codepoint <= 0x7F) \n            os.Put(static_cast<Ch>(codepoint & 0xFF));\n        else if (codepoint <= 0x7FF) {\n            os.Put(static_cast<Ch>(0xC0 | ((codepoint >> 6) & 0xFF)));\n            os.Put(static_cast<Ch>(0x80 | ((codepoint & 0x3F))));\n        }\n        else if (codepoint <= 0xFFFF) {\n            os.Put(static_cast<Ch>(0xE0 | ((codepoint >> 12) & 0xFF)));\n            os.Put(static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F)));\n            os.Put(static_cast<Ch>(0x80 | (codepoint & 0x3F)));\n        }\n        else {\n            RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);\n            os.Put(static_cast<Ch>(0xF0 | ((codepoint >> 18) & 0xFF)));\n            os.Put(static_cast<Ch>(0x80 | ((codepoint >> 12) & 0x3F)));\n            os.Put(static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F)));\n            os.Put(static_cast<Ch>(0x80 | (codepoint & 0x3F)));\n        }\n    }\n\n    template<typename OutputStream>\n    static void EncodeUnsafe(OutputStream& os, unsigned codepoint) {\n        if (codepoint <= 0x7F) \n            PutUnsafe(os, static_cast<Ch>(codepoint & 0xFF));\n        else if (codepoint <= 0x7FF) {\n            PutUnsafe(os, static_cast<Ch>(0xC0 | ((codepoint >> 6) & 0xFF)));\n            PutUnsafe(os, static_cast<Ch>(0x80 | ((codepoint & 0x3F))));\n        }\n        else if (codepoint <= 0xFFFF) {\n            PutUnsafe(os, static_cast<Ch>(0xE0 | ((codepoint >> 12) & 0xFF)));\n            PutUnsafe(os, static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F)));\n            PutUnsafe(os, static_cast<Ch>(0x80 | (codepoint & 0x3F)));\n        }\n        else {\n            RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);\n            PutUnsafe(os, static_cast<Ch>(0xF0 | ((codepoint >> 18) & 0xFF)));\n            PutUnsafe(os, static_cast<Ch>(0x80 | ((codepoint >> 12) & 0x3F)));\n            PutUnsafe(os, static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F)));\n            PutUnsafe(os, static_cast<Ch>(0x80 | (codepoint & 0x3F)));\n        }\n    }\n\n    template <typename InputStream>\n    static bool Decode(InputStream& is, unsigned* codepoint) {\n#define COPY() c = is.Take(); *codepoint = (*codepoint << 6) | (static_cast<unsigned char>(c) & 0x3Fu)\n#define TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)\n#define TAIL() COPY(); TRANS(0x70)\n        typename InputStream::Ch c = is.Take();\n        if (!(c & 0x80)) {\n            *codepoint = static_cast<unsigned char>(c);\n            return true;\n        }\n\n        unsigned char type = GetRange(static_cast<unsigned char>(c));\n        if (type >= 32) {\n            *codepoint = 0;\n        } else {\n            *codepoint = (0xFF >> type) & static_cast<unsigned char>(c);\n        }\n        bool result = true;\n        switch (type) {\n        case 2: TAIL(); return result;\n        case 3: TAIL(); TAIL(); return result;\n        case 4: COPY(); TRANS(0x50); TAIL(); return result;\n        case 5: COPY(); TRANS(0x10); TAIL(); TAIL(); return result;\n        case 6: TAIL(); TAIL(); TAIL(); return result;\n        case 10: COPY(); TRANS(0x20); TAIL(); return result;\n        case 11: COPY(); TRANS(0x60); TAIL(); TAIL(); return result;\n        default: return false;\n        }\n#undef COPY\n#undef TRANS\n#undef TAIL\n    }\n\n    template <typename InputStream, typename OutputStream>\n    static bool Validate(InputStream& is, OutputStream& os) {\n#define COPY() os.Put(c = is.Take())\n#define TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)\n#define TAIL() COPY(); TRANS(0x70)\n        Ch c;\n        COPY();\n        if (!(c & 0x80))\n            return true;\n\n        bool result = true;\n        switch (GetRange(static_cast<unsigned char>(c))) {\n        case 2: TAIL(); return result;\n        case 3: TAIL(); TAIL(); return result;\n        case 4: COPY(); TRANS(0x50); TAIL(); return result;\n        case 5: COPY(); TRANS(0x10); TAIL(); TAIL(); return result;\n        case 6: TAIL(); TAIL(); TAIL(); return result;\n        case 10: COPY(); TRANS(0x20); TAIL(); return result;\n        case 11: COPY(); TRANS(0x60); TAIL(); TAIL(); return result;\n        default: return false;\n        }\n#undef COPY\n#undef TRANS\n#undef TAIL\n    }\n\n    static unsigned char GetRange(unsigned char c) {\n        // Referring to DFA of http://bjoern.hoehrmann.de/utf-8/decoder/dfa/\n        // With new mapping 1 -> 0x10, 7 -> 0x20, 9 -> 0x40, such that AND operation can test multiple types.\n        static const unsigned char type[] = {\n            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,\n            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,\n            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,\n            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,\n            0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,\n            0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,\n            0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n            0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n            8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,\n            10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8,\n        };\n        return type[c];\n    }\n\n    template <typename InputByteStream>\n    static CharType TakeBOM(InputByteStream& is) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);\n        typename InputByteStream::Ch c = Take(is);\n        if (static_cast<unsigned char>(c) != 0xEFu) return c;\n        c = is.Take();\n        if (static_cast<unsigned char>(c) != 0xBBu) return c;\n        c = is.Take();\n        if (static_cast<unsigned char>(c) != 0xBFu) return c;\n        c = is.Take();\n        return c;\n    }\n\n    template <typename InputByteStream>\n    static Ch Take(InputByteStream& is) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);\n        return static_cast<Ch>(is.Take());\n    }\n\n    template <typename OutputByteStream>\n    static void PutBOM(OutputByteStream& os) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);\n        os.Put(static_cast<typename OutputByteStream::Ch>(0xEFu));\n        os.Put(static_cast<typename OutputByteStream::Ch>(0xBBu));\n        os.Put(static_cast<typename OutputByteStream::Ch>(0xBFu));\n    }\n\n    template <typename OutputByteStream>\n    static void Put(OutputByteStream& os, Ch c) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);\n        os.Put(static_cast<typename OutputByteStream::Ch>(c));\n    }\n};\n\n///////////////////////////////////////////////////////////////////////////////\n// UTF16\n\n//! UTF-16 encoding.\n/*! http://en.wikipedia.org/wiki/UTF-16\n    http://tools.ietf.org/html/rfc2781\n    \\tparam CharType Type for storing 16-bit UTF-16 data. Default is wchar_t. C++11 may use char16_t instead.\n    \\note implements Encoding concept\n\n    \\note For in-memory access, no need to concern endianness. The code units and code points are represented by CPU's endianness.\n    For streaming, use UTF16LE and UTF16BE, which handle endianness.\n*/\ntemplate<typename CharType = wchar_t>\nstruct UTF16 {\n    typedef CharType Ch;\n    RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 2);\n\n    enum { supportUnicode = 1 };\n\n    template<typename OutputStream>\n    static void Encode(OutputStream& os, unsigned codepoint) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2);\n        if (codepoint <= 0xFFFF) {\n            RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair \n            os.Put(static_cast<typename OutputStream::Ch>(codepoint));\n        }\n        else {\n            RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);\n            unsigned v = codepoint - 0x10000;\n            os.Put(static_cast<typename OutputStream::Ch>((v >> 10) | 0xD800));\n            os.Put((v & 0x3FF) | 0xDC00);\n        }\n    }\n\n\n    template<typename OutputStream>\n    static void EncodeUnsafe(OutputStream& os, unsigned codepoint) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2);\n        if (codepoint <= 0xFFFF) {\n            RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair \n            PutUnsafe(os, static_cast<typename OutputStream::Ch>(codepoint));\n        }\n        else {\n            RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);\n            unsigned v = codepoint - 0x10000;\n            PutUnsafe(os, static_cast<typename OutputStream::Ch>((v >> 10) | 0xD800));\n            PutUnsafe(os, (v & 0x3FF) | 0xDC00);\n        }\n    }\n\n    template <typename InputStream>\n    static bool Decode(InputStream& is, unsigned* codepoint) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2);\n        typename InputStream::Ch c = is.Take();\n        if (c < 0xD800 || c > 0xDFFF) {\n            *codepoint = static_cast<unsigned>(c);\n            return true;\n        }\n        else if (c <= 0xDBFF) {\n            *codepoint = (static_cast<unsigned>(c) & 0x3FF) << 10;\n            c = is.Take();\n            *codepoint |= (static_cast<unsigned>(c) & 0x3FF);\n            *codepoint += 0x10000;\n            return c >= 0xDC00 && c <= 0xDFFF;\n        }\n        return false;\n    }\n\n    template <typename InputStream, typename OutputStream>\n    static bool Validate(InputStream& is, OutputStream& os) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2);\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2);\n        typename InputStream::Ch c;\n        os.Put(static_cast<typename OutputStream::Ch>(c = is.Take()));\n        if (c < 0xD800 || c > 0xDFFF)\n            return true;\n        else if (c <= 0xDBFF) {\n            os.Put(c = is.Take());\n            return c >= 0xDC00 && c <= 0xDFFF;\n        }\n        return false;\n    }\n};\n\n//! UTF-16 little endian encoding.\ntemplate<typename CharType = wchar_t>\nstruct UTF16LE : UTF16<CharType> {\n    template <typename InputByteStream>\n    static CharType TakeBOM(InputByteStream& is) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);\n        CharType c = Take(is);\n        return static_cast<uint16_t>(c) == 0xFEFFu ? Take(is) : c;\n    }\n\n    template <typename InputByteStream>\n    static CharType Take(InputByteStream& is) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);\n        unsigned c = static_cast<uint8_t>(is.Take());\n        c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8;\n        return static_cast<CharType>(c);\n    }\n\n    template <typename OutputByteStream>\n    static void PutBOM(OutputByteStream& os) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);\n        os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu));\n        os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu));\n    }\n\n    template <typename OutputByteStream>\n    static void Put(OutputByteStream& os, CharType c) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);\n        os.Put(static_cast<typename OutputByteStream::Ch>(static_cast<unsigned>(c) & 0xFFu));\n        os.Put(static_cast<typename OutputByteStream::Ch>((static_cast<unsigned>(c) >> 8) & 0xFFu));\n    }\n};\n\n//! UTF-16 big endian encoding.\ntemplate<typename CharType = wchar_t>\nstruct UTF16BE : UTF16<CharType> {\n    template <typename InputByteStream>\n    static CharType TakeBOM(InputByteStream& is) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);\n        CharType c = Take(is);\n        return static_cast<uint16_t>(c) == 0xFEFFu ? Take(is) : c;\n    }\n\n    template <typename InputByteStream>\n    static CharType Take(InputByteStream& is) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);\n        unsigned c = static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8;\n        c |= static_cast<uint8_t>(is.Take());\n        return static_cast<CharType>(c);\n    }\n\n    template <typename OutputByteStream>\n    static void PutBOM(OutputByteStream& os) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);\n        os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu));\n        os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu));\n    }\n\n    template <typename OutputByteStream>\n    static void Put(OutputByteStream& os, CharType c) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);\n        os.Put(static_cast<typename OutputByteStream::Ch>((static_cast<unsigned>(c) >> 8) & 0xFFu));\n        os.Put(static_cast<typename OutputByteStream::Ch>(static_cast<unsigned>(c) & 0xFFu));\n    }\n};\n\n///////////////////////////////////////////////////////////////////////////////\n// UTF32\n\n//! UTF-32 encoding. \n/*! http://en.wikipedia.org/wiki/UTF-32\n    \\tparam CharType Type for storing 32-bit UTF-32 data. Default is unsigned. C++11 may use char32_t instead.\n    \\note implements Encoding concept\n\n    \\note For in-memory access, no need to concern endianness. The code units and code points are represented by CPU's endianness.\n    For streaming, use UTF32LE and UTF32BE, which handle endianness.\n*/\ntemplate<typename CharType = unsigned>\nstruct UTF32 {\n    typedef CharType Ch;\n    RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 4);\n\n    enum { supportUnicode = 1 };\n\n    template<typename OutputStream>\n    static void Encode(OutputStream& os, unsigned codepoint) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 4);\n        RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);\n        os.Put(codepoint);\n    }\n\n    template<typename OutputStream>\n    static void EncodeUnsafe(OutputStream& os, unsigned codepoint) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 4);\n        RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);\n        PutUnsafe(os, codepoint);\n    }\n\n    template <typename InputStream>\n    static bool Decode(InputStream& is, unsigned* codepoint) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4);\n        Ch c = is.Take();\n        *codepoint = c;\n        return c <= 0x10FFFF;\n    }\n\n    template <typename InputStream, typename OutputStream>\n    static bool Validate(InputStream& is, OutputStream& os) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4);\n        Ch c;\n        os.Put(c = is.Take());\n        return c <= 0x10FFFF;\n    }\n};\n\n//! UTF-32 little endian enocoding.\ntemplate<typename CharType = unsigned>\nstruct UTF32LE : UTF32<CharType> {\n    template <typename InputByteStream>\n    static CharType TakeBOM(InputByteStream& is) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);\n        CharType c = Take(is);\n        return static_cast<uint32_t>(c) == 0x0000FEFFu ? Take(is) : c;\n    }\n\n    template <typename InputByteStream>\n    static CharType Take(InputByteStream& is) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);\n        unsigned c = static_cast<uint8_t>(is.Take());\n        c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8;\n        c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 16;\n        c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 24;\n        return static_cast<CharType>(c);\n    }\n\n    template <typename OutputByteStream>\n    static void PutBOM(OutputByteStream& os) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);\n        os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu));\n        os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu));\n        os.Put(static_cast<typename OutputByteStream::Ch>(0x00u));\n        os.Put(static_cast<typename OutputByteStream::Ch>(0x00u));\n    }\n\n    template <typename OutputByteStream>\n    static void Put(OutputByteStream& os, CharType c) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);\n        os.Put(static_cast<typename OutputByteStream::Ch>(c & 0xFFu));\n        os.Put(static_cast<typename OutputByteStream::Ch>((c >> 8) & 0xFFu));\n        os.Put(static_cast<typename OutputByteStream::Ch>((c >> 16) & 0xFFu));\n        os.Put(static_cast<typename OutputByteStream::Ch>((c >> 24) & 0xFFu));\n    }\n};\n\n//! UTF-32 big endian encoding.\ntemplate<typename CharType = unsigned>\nstruct UTF32BE : UTF32<CharType> {\n    template <typename InputByteStream>\n    static CharType TakeBOM(InputByteStream& is) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);\n        CharType c = Take(is);\n        return static_cast<uint32_t>(c) == 0x0000FEFFu ? Take(is) : c; \n    }\n\n    template <typename InputByteStream>\n    static CharType Take(InputByteStream& is) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);\n        unsigned c = static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 24;\n        c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 16;\n        c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8;\n        c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take()));\n        return static_cast<CharType>(c);\n    }\n\n    template <typename OutputByteStream>\n    static void PutBOM(OutputByteStream& os) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);\n        os.Put(static_cast<typename OutputByteStream::Ch>(0x00u));\n        os.Put(static_cast<typename OutputByteStream::Ch>(0x00u));\n        os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu));\n        os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu));\n    }\n\n    template <typename OutputByteStream>\n    static void Put(OutputByteStream& os, CharType c) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);\n        os.Put(static_cast<typename OutputByteStream::Ch>((c >> 24) & 0xFFu));\n        os.Put(static_cast<typename OutputByteStream::Ch>((c >> 16) & 0xFFu));\n        os.Put(static_cast<typename OutputByteStream::Ch>((c >> 8) & 0xFFu));\n        os.Put(static_cast<typename OutputByteStream::Ch>(c & 0xFFu));\n    }\n};\n\n///////////////////////////////////////////////////////////////////////////////\n// ASCII\n\n//! ASCII encoding.\n/*! http://en.wikipedia.org/wiki/ASCII\n    \\tparam CharType Code unit for storing 7-bit ASCII data. Default is char.\n    \\note implements Encoding concept\n*/\ntemplate<typename CharType = char>\nstruct ASCII {\n    typedef CharType Ch;\n\n    enum { supportUnicode = 0 };\n\n    template<typename OutputStream>\n    static void Encode(OutputStream& os, unsigned codepoint) {\n        RAPIDJSON_ASSERT(codepoint <= 0x7F);\n        os.Put(static_cast<Ch>(codepoint & 0xFF));\n    }\n\n    template<typename OutputStream>\n    static void EncodeUnsafe(OutputStream& os, unsigned codepoint) {\n        RAPIDJSON_ASSERT(codepoint <= 0x7F);\n        PutUnsafe(os, static_cast<Ch>(codepoint & 0xFF));\n    }\n\n    template <typename InputStream>\n    static bool Decode(InputStream& is, unsigned* codepoint) {\n        uint8_t c = static_cast<uint8_t>(is.Take());\n        *codepoint = c;\n        return c <= 0X7F;\n    }\n\n    template <typename InputStream, typename OutputStream>\n    static bool Validate(InputStream& is, OutputStream& os) {\n        uint8_t c = static_cast<uint8_t>(is.Take());\n        os.Put(static_cast<typename OutputStream::Ch>(c));\n        return c <= 0x7F;\n    }\n\n    template <typename InputByteStream>\n    static CharType TakeBOM(InputByteStream& is) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);\n        uint8_t c = static_cast<uint8_t>(Take(is));\n        return static_cast<Ch>(c);\n    }\n\n    template <typename InputByteStream>\n    static Ch Take(InputByteStream& is) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);\n        return static_cast<Ch>(is.Take());\n    }\n\n    template <typename OutputByteStream>\n    static void PutBOM(OutputByteStream& os) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);\n        (void)os;\n    }\n\n    template <typename OutputByteStream>\n    static void Put(OutputByteStream& os, Ch c) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);\n        os.Put(static_cast<typename OutputByteStream::Ch>(c));\n    }\n};\n\n///////////////////////////////////////////////////////////////////////////////\n// AutoUTF\n\n//! Runtime-specified UTF encoding type of a stream.\nenum UTFType {\n    kUTF8 = 0,      //!< UTF-8.\n    kUTF16LE = 1,   //!< UTF-16 little endian.\n    kUTF16BE = 2,   //!< UTF-16 big endian.\n    kUTF32LE = 3,   //!< UTF-32 little endian.\n    kUTF32BE = 4    //!< UTF-32 big endian.\n};\n\n//! Dynamically select encoding according to stream's runtime-specified UTF encoding type.\n/*! \\note This class can be used with AutoUTFInputtStream and AutoUTFOutputStream, which provides GetType().\n*/\ntemplate<typename CharType>\nstruct AutoUTF {\n    typedef CharType Ch;\n\n    enum { supportUnicode = 1 };\n\n#define RAPIDJSON_ENCODINGS_FUNC(x) UTF8<Ch>::x, UTF16LE<Ch>::x, UTF16BE<Ch>::x, UTF32LE<Ch>::x, UTF32BE<Ch>::x\n\n    template<typename OutputStream>\n    RAPIDJSON_FORCEINLINE static void Encode(OutputStream& os, unsigned codepoint) {\n        typedef void (*EncodeFunc)(OutputStream&, unsigned);\n        static const EncodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Encode) };\n        (*f[os.GetType()])(os, codepoint);\n    }\n\n    template<typename OutputStream>\n    RAPIDJSON_FORCEINLINE static void EncodeUnsafe(OutputStream& os, unsigned codepoint) {\n        typedef void (*EncodeFunc)(OutputStream&, unsigned);\n        static const EncodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(EncodeUnsafe) };\n        (*f[os.GetType()])(os, codepoint);\n    }\n\n    template <typename InputStream>\n    RAPIDJSON_FORCEINLINE static bool Decode(InputStream& is, unsigned* codepoint) {\n        typedef bool (*DecodeFunc)(InputStream&, unsigned*);\n        static const DecodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Decode) };\n        return (*f[is.GetType()])(is, codepoint);\n    }\n\n    template <typename InputStream, typename OutputStream>\n    RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) {\n        typedef bool (*ValidateFunc)(InputStream&, OutputStream&);\n        static const ValidateFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Validate) };\n        return (*f[is.GetType()])(is, os);\n    }\n\n#undef RAPIDJSON_ENCODINGS_FUNC\n};\n\n///////////////////////////////////////////////////////////////////////////////\n// Transcoder\n\n//! Encoding conversion.\ntemplate<typename SourceEncoding, typename TargetEncoding>\nstruct Transcoder {\n    //! Take one Unicode codepoint from source encoding, convert it to target encoding and put it to the output stream.\n    template<typename InputStream, typename OutputStream>\n    RAPIDJSON_FORCEINLINE static bool Transcode(InputStream& is, OutputStream& os) {\n        unsigned codepoint;\n        if (!SourceEncoding::Decode(is, &codepoint))\n            return false;\n        TargetEncoding::Encode(os, codepoint);\n        return true;\n    }\n\n    template<typename InputStream, typename OutputStream>\n    RAPIDJSON_FORCEINLINE static bool TranscodeUnsafe(InputStream& is, OutputStream& os) {\n        unsigned codepoint;\n        if (!SourceEncoding::Decode(is, &codepoint))\n            return false;\n        TargetEncoding::EncodeUnsafe(os, codepoint);\n        return true;\n    }\n\n    //! Validate one Unicode codepoint from an encoded stream.\n    template<typename InputStream, typename OutputStream>\n    RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) {\n        return Transcode(is, os);   // Since source/target encoding is different, must transcode.\n    }\n};\n\n// Forward declaration.\ntemplate<typename Stream>\ninline void PutUnsafe(Stream& stream, typename Stream::Ch c);\n\n//! Specialization of Transcoder with same source and target encoding.\ntemplate<typename Encoding>\nstruct Transcoder<Encoding, Encoding> {\n    template<typename InputStream, typename OutputStream>\n    RAPIDJSON_FORCEINLINE static bool Transcode(InputStream& is, OutputStream& os) {\n        os.Put(is.Take());  // Just copy one code unit. This semantic is different from primary template class.\n        return true;\n    }\n    \n    template<typename InputStream, typename OutputStream>\n    RAPIDJSON_FORCEINLINE static bool TranscodeUnsafe(InputStream& is, OutputStream& os) {\n        PutUnsafe(os, is.Take());  // Just copy one code unit. This semantic is different from primary template class.\n        return true;\n    }\n    \n    template<typename InputStream, typename OutputStream>\n    RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) {\n        return Encoding::Validate(is, os);  // source/target encoding are the same\n    }\n};\n\nRAPIDJSON_NAMESPACE_END\n\n#if defined(__GNUC__) || defined(_MSC_VER)\nRAPIDJSON_DIAG_POP\n#endif\n\n#endif // RAPIDJSON_ENCODINGS_H_\n"
  },
  {
    "path": "rapidjson/error/en.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_ERROR_EN_H_\n#define RAPIDJSON_ERROR_EN_H_\n\n#include \"error.h\"\n\n#ifdef __clang__\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(switch-enum)\nRAPIDJSON_DIAG_OFF(covered-switch-default)\n#endif\n\nRAPIDJSON_NAMESPACE_BEGIN\n\n//! Maps error code of parsing into error message.\n/*!\n    \\ingroup RAPIDJSON_ERRORS\n    \\param parseErrorCode Error code obtained in parsing.\n    \\return the error message.\n    \\note User can make a copy of this function for localization.\n        Using switch-case is safer for future modification of error codes.\n*/\ninline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErrorCode) {\n    switch (parseErrorCode) {\n        case kParseErrorNone:                           return RAPIDJSON_ERROR_STRING(\"No error.\");\n\n        case kParseErrorDocumentEmpty:                  return RAPIDJSON_ERROR_STRING(\"The document is empty.\");\n        case kParseErrorDocumentRootNotSingular:        return RAPIDJSON_ERROR_STRING(\"The document root must not be followed by other values.\");\n    \n        case kParseErrorValueInvalid:                   return RAPIDJSON_ERROR_STRING(\"Invalid value.\");\n    \n        case kParseErrorObjectMissName:                 return RAPIDJSON_ERROR_STRING(\"Missing a name for object member.\");\n        case kParseErrorObjectMissColon:                return RAPIDJSON_ERROR_STRING(\"Missing a colon after a name of object member.\");\n        case kParseErrorObjectMissCommaOrCurlyBracket:  return RAPIDJSON_ERROR_STRING(\"Missing a comma or '}' after an object member.\");\n    \n        case kParseErrorArrayMissCommaOrSquareBracket:  return RAPIDJSON_ERROR_STRING(\"Missing a comma or ']' after an array element.\");\n\n        case kParseErrorStringUnicodeEscapeInvalidHex:  return RAPIDJSON_ERROR_STRING(\"Incorrect hex digit after \\\\u escape in string.\");\n        case kParseErrorStringUnicodeSurrogateInvalid:  return RAPIDJSON_ERROR_STRING(\"The surrogate pair in string is invalid.\");\n        case kParseErrorStringEscapeInvalid:            return RAPIDJSON_ERROR_STRING(\"Invalid escape character in string.\");\n        case kParseErrorStringMissQuotationMark:        return RAPIDJSON_ERROR_STRING(\"Missing a closing quotation mark in string.\");\n        case kParseErrorStringInvalidEncoding:          return RAPIDJSON_ERROR_STRING(\"Invalid encoding in string.\");\n\n        case kParseErrorNumberTooBig:                   return RAPIDJSON_ERROR_STRING(\"Number too big to be stored in double.\");\n        case kParseErrorNumberMissFraction:             return RAPIDJSON_ERROR_STRING(\"Miss fraction part in number.\");\n        case kParseErrorNumberMissExponent:             return RAPIDJSON_ERROR_STRING(\"Miss exponent in number.\");\n\n        case kParseErrorTermination:                    return RAPIDJSON_ERROR_STRING(\"Terminate parsing due to Handler error.\");\n        case kParseErrorUnspecificSyntaxError:          return RAPIDJSON_ERROR_STRING(\"Unspecific syntax error.\");\n\n        default:                                        return RAPIDJSON_ERROR_STRING(\"Unknown error.\");\n    }\n}\n\nRAPIDJSON_NAMESPACE_END\n\n#ifdef __clang__\nRAPIDJSON_DIAG_POP\n#endif\n\n#endif // RAPIDJSON_ERROR_EN_H_\n"
  },
  {
    "path": "rapidjson/error/error.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_ERROR_ERROR_H_\n#define RAPIDJSON_ERROR_ERROR_H_\n\n#include \"../rapidjson.h\"\n\n#ifdef __clang__\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(padded)\n#endif\n\n/*! \\file error.h */\n\n/*! \\defgroup RAPIDJSON_ERRORS RapidJSON error handling */\n\n///////////////////////////////////////////////////////////////////////////////\n// RAPIDJSON_ERROR_CHARTYPE\n\n//! Character type of error messages.\n/*! \\ingroup RAPIDJSON_ERRORS\n    The default character type is \\c char.\n    On Windows, user can define this macro as \\c TCHAR for supporting both\n    unicode/non-unicode settings.\n*/\n#ifndef RAPIDJSON_ERROR_CHARTYPE\n#define RAPIDJSON_ERROR_CHARTYPE char\n#endif\n\n///////////////////////////////////////////////////////////////////////////////\n// RAPIDJSON_ERROR_STRING\n\n//! Macro for converting string literial to \\ref RAPIDJSON_ERROR_CHARTYPE[].\n/*! \\ingroup RAPIDJSON_ERRORS\n    By default this conversion macro does nothing.\n    On Windows, user can define this macro as \\c _T(x) for supporting both\n    unicode/non-unicode settings.\n*/\n#ifndef RAPIDJSON_ERROR_STRING\n#define RAPIDJSON_ERROR_STRING(x) x\n#endif\n\nRAPIDJSON_NAMESPACE_BEGIN\n\n///////////////////////////////////////////////////////////////////////////////\n// ParseErrorCode\n\n//! Error code of parsing.\n/*! \\ingroup RAPIDJSON_ERRORS\n    \\see GenericReader::Parse, GenericReader::GetParseErrorCode\n*/\nenum ParseErrorCode {\n    kParseErrorNone = 0,                        //!< No error.\n\n    kParseErrorDocumentEmpty,                   //!< The document is empty.\n    kParseErrorDocumentRootNotSingular,         //!< The document root must not follow by other values.\n\n    kParseErrorValueInvalid,                    //!< Invalid value.\n\n    kParseErrorObjectMissName,                  //!< Missing a name for object member.\n    kParseErrorObjectMissColon,                 //!< Missing a colon after a name of object member.\n    kParseErrorObjectMissCommaOrCurlyBracket,   //!< Missing a comma or '}' after an object member.\n\n    kParseErrorArrayMissCommaOrSquareBracket,   //!< Missing a comma or ']' after an array element.\n\n    kParseErrorStringUnicodeEscapeInvalidHex,   //!< Incorrect hex digit after \\\\u escape in string.\n    kParseErrorStringUnicodeSurrogateInvalid,   //!< The surrogate pair in string is invalid.\n    kParseErrorStringEscapeInvalid,             //!< Invalid escape character in string.\n    kParseErrorStringMissQuotationMark,         //!< Missing a closing quotation mark in string.\n    kParseErrorStringInvalidEncoding,           //!< Invalid encoding in string.\n\n    kParseErrorNumberTooBig,                    //!< Number too big to be stored in double.\n    kParseErrorNumberMissFraction,              //!< Miss fraction part in number.\n    kParseErrorNumberMissExponent,              //!< Miss exponent in number.\n\n    kParseErrorTermination,                     //!< Parsing was terminated.\n    kParseErrorUnspecificSyntaxError            //!< Unspecific syntax error.\n};\n\n//! Result of parsing (wraps ParseErrorCode)\n/*!\n    \\ingroup RAPIDJSON_ERRORS\n    \\code\n        Document doc;\n        ParseResult ok = doc.Parse(\"[42]\");\n        if (!ok) {\n            fprintf(stderr, \"JSON parse error: %s (%u)\",\n                    GetParseError_En(ok.Code()), ok.Offset());\n            exit(EXIT_FAILURE);\n        }\n    \\endcode\n    \\see GenericReader::Parse, GenericDocument::Parse\n*/\nstruct ParseResult {\npublic:\n    //! Default constructor, no error.\n    ParseResult() : code_(kParseErrorNone), offset_(0) {}\n    //! Constructor to set an error.\n    ParseResult(ParseErrorCode code, size_t offset) : code_(code), offset_(offset) {}\n\n    //! Get the error code.\n    ParseErrorCode Code() const { return code_; }\n    //! Get the error offset, if \\ref IsError(), 0 otherwise.\n    size_t Offset() const { return offset_; }\n\n    //! Conversion to \\c bool, returns \\c true, iff !\\ref IsError().\n    operator bool() const { return !IsError(); }\n    //! Whether the result is an error.\n    bool IsError() const { return code_ != kParseErrorNone; }\n\n    bool operator==(const ParseResult& that) const { return code_ == that.code_; }\n    bool operator==(ParseErrorCode code) const { return code_ == code; }\n    friend bool operator==(ParseErrorCode code, const ParseResult & err) { return code == err.code_; }\n\n    //! Reset error code.\n    void Clear() { Set(kParseErrorNone); }\n    //! Update error code and offset.\n    void Set(ParseErrorCode code, size_t offset = 0) { code_ = code; offset_ = offset; }\n\nprivate:\n    ParseErrorCode code_;\n    size_t offset_;\n};\n\n//! Function pointer type of GetParseError().\n/*! \\ingroup RAPIDJSON_ERRORS\n\n    This is the prototype for \\c GetParseError_X(), where \\c X is a locale.\n    User can dynamically change locale in runtime, e.g.:\n\\code\n    GetParseErrorFunc GetParseError = GetParseError_En; // or whatever\n    const RAPIDJSON_ERROR_CHARTYPE* s = GetParseError(document.GetParseErrorCode());\n\\endcode\n*/\ntypedef const RAPIDJSON_ERROR_CHARTYPE* (*GetParseErrorFunc)(ParseErrorCode);\n\nRAPIDJSON_NAMESPACE_END\n\n#ifdef __clang__\nRAPIDJSON_DIAG_POP\n#endif\n\n#endif // RAPIDJSON_ERROR_ERROR_H_\n"
  },
  {
    "path": "rapidjson/filereadstream.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_FILEREADSTREAM_H_\n#define RAPIDJSON_FILEREADSTREAM_H_\n\n#include \"stream.h\"\n#include <cstdio>\n\n#ifdef __clang__\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(padded)\nRAPIDJSON_DIAG_OFF(unreachable-code)\nRAPIDJSON_DIAG_OFF(missing-noreturn)\n#endif\n\nRAPIDJSON_NAMESPACE_BEGIN\n\n//! File byte stream for input using fread().\n/*!\n    \\note implements Stream concept\n*/\nclass FileReadStream {\npublic:\n    typedef char Ch;    //!< Character type (byte).\n\n    //! Constructor.\n    /*!\n        \\param fp File pointer opened for read.\n        \\param buffer user-supplied buffer.\n        \\param bufferSize size of buffer in bytes. Must >=4 bytes.\n    */\n    FileReadStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) { \n        RAPIDJSON_ASSERT(fp_ != 0);\n        RAPIDJSON_ASSERT(bufferSize >= 4);\n        Read();\n    }\n\n    Ch Peek() const { return *current_; }\n    Ch Take() { Ch c = *current_; Read(); return c; }\n    size_t Tell() const { return count_ + static_cast<size_t>(current_ - buffer_); }\n\n    // Not implemented\n    void Put(Ch) { RAPIDJSON_ASSERT(false); }\n    void Flush() { RAPIDJSON_ASSERT(false); } \n    Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }\n    size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }\n\n    // For encoding detection only.\n    const Ch* Peek4() const {\n        return (current_ + 4 <= bufferLast_) ? current_ : 0;\n    }\n\nprivate:\n    void Read() {\n        if (current_ < bufferLast_)\n            ++current_;\n        else if (!eof_) {\n            count_ += readCount_;\n            readCount_ = fread(buffer_, 1, bufferSize_, fp_);\n            bufferLast_ = buffer_ + readCount_ - 1;\n            current_ = buffer_;\n\n            if (readCount_ < bufferSize_) {\n                buffer_[readCount_] = '\\0';\n                ++bufferLast_;\n                eof_ = true;\n            }\n        }\n    }\n\n    std::FILE* fp_;\n    Ch *buffer_;\n    size_t bufferSize_;\n    Ch *bufferLast_;\n    Ch *current_;\n    size_t readCount_;\n    size_t count_;  //!< Number of characters read\n    bool eof_;\n};\n\nRAPIDJSON_NAMESPACE_END\n\n#ifdef __clang__\nRAPIDJSON_DIAG_POP\n#endif\n\n#endif // RAPIDJSON_FILESTREAM_H_\n"
  },
  {
    "path": "rapidjson/filewritestream.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_FILEWRITESTREAM_H_\n#define RAPIDJSON_FILEWRITESTREAM_H_\n\n#include \"stream.h\"\n#include <cstdio>\n\n#ifdef __clang__\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(unreachable-code)\n#endif\n\nRAPIDJSON_NAMESPACE_BEGIN\n\n//! Wrapper of C file stream for input using fread().\n/*!\n    \\note implements Stream concept\n*/\nclass FileWriteStream {\npublic:\n    typedef char Ch;    //!< Character type. Only support char.\n\n    FileWriteStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferEnd_(buffer + bufferSize), current_(buffer_) { \n        RAPIDJSON_ASSERT(fp_ != 0);\n    }\n\n    void Put(char c) { \n        if (current_ >= bufferEnd_)\n            Flush();\n\n        *current_++ = c;\n    }\n\n    void PutN(char c, size_t n) {\n        size_t avail = static_cast<size_t>(bufferEnd_ - current_);\n        while (n > avail) {\n            std::memset(current_, c, avail);\n            current_ += avail;\n            Flush();\n            n -= avail;\n            avail = static_cast<size_t>(bufferEnd_ - current_);\n        }\n\n        if (n > 0) {\n            std::memset(current_, c, n);\n            current_ += n;\n        }\n    }\n\n    void Flush() {\n        if (current_ != buffer_) {\n            size_t result = fwrite(buffer_, 1, static_cast<size_t>(current_ - buffer_), fp_);\n            if (result < static_cast<size_t>(current_ - buffer_)) {\n                // failure deliberately ignored at this time\n                // added to avoid warn_unused_result build errors\n            }\n            current_ = buffer_;\n        }\n    }\n\n    // Not implemented\n    char Peek() const { RAPIDJSON_ASSERT(false); return 0; }\n    char Take() { RAPIDJSON_ASSERT(false); return 0; }\n    size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }\n    char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }\n    size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; }\n\nprivate:\n    // Prohibit copy constructor & assignment operator.\n    FileWriteStream(const FileWriteStream&);\n    FileWriteStream& operator=(const FileWriteStream&);\n\n    std::FILE* fp_;\n    char *buffer_;\n    char *bufferEnd_;\n    char *current_;\n};\n\n//! Implement specialized version of PutN() with memset() for better performance.\ntemplate<>\ninline void PutN(FileWriteStream& stream, char c, size_t n) {\n    stream.PutN(c, n);\n}\n\nRAPIDJSON_NAMESPACE_END\n\n#ifdef __clang__\nRAPIDJSON_DIAG_POP\n#endif\n\n#endif // RAPIDJSON_FILESTREAM_H_\n"
  },
  {
    "path": "rapidjson/fwd.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_FWD_H_\n#define RAPIDJSON_FWD_H_\n\n#include \"rapidjson.h\"\n\nRAPIDJSON_NAMESPACE_BEGIN\n\n// encodings.h\n\ntemplate<typename CharType> struct UTF8;\ntemplate<typename CharType> struct UTF16;\ntemplate<typename CharType> struct UTF16BE;\ntemplate<typename CharType> struct UTF16LE;\ntemplate<typename CharType> struct UTF32;\ntemplate<typename CharType> struct UTF32BE;\ntemplate<typename CharType> struct UTF32LE;\ntemplate<typename CharType> struct ASCII;\ntemplate<typename CharType> struct AutoUTF;\n\ntemplate<typename SourceEncoding, typename TargetEncoding>\nstruct Transcoder;\n\n// allocators.h\n\nclass CrtAllocator;\n\ntemplate <typename BaseAllocator>\nclass MemoryPoolAllocator;\n\n// stream.h\n\ntemplate <typename Encoding>\nstruct GenericStringStream;\n\ntypedef GenericStringStream<UTF8<char> > StringStream;\n\ntemplate <typename Encoding>\nstruct GenericInsituStringStream;\n\ntypedef GenericInsituStringStream<UTF8<char> > InsituStringStream;\n\n// stringbuffer.h\n\ntemplate <typename Encoding, typename Allocator>\nclass GenericStringBuffer;\n\ntypedef GenericStringBuffer<UTF8<char>, CrtAllocator> StringBuffer;\n\n// filereadstream.h\n\nclass FileReadStream;\n\n// filewritestream.h\n\nclass FileWriteStream;\n\n// memorybuffer.h\n\ntemplate <typename Allocator>\nstruct GenericMemoryBuffer;\n\ntypedef GenericMemoryBuffer<CrtAllocator> MemoryBuffer;\n\n// memorystream.h\n\nstruct MemoryStream;\n\n// reader.h\n\ntemplate<typename Encoding, typename Derived>\nstruct BaseReaderHandler;\n\ntemplate <typename SourceEncoding, typename TargetEncoding, typename StackAllocator>\nclass GenericReader;\n\ntypedef GenericReader<UTF8<char>, UTF8<char>, CrtAllocator> Reader;\n\n// writer.h\n\ntemplate<typename OutputStream, typename SourceEncoding, typename TargetEncoding, typename StackAllocator, unsigned writeFlags>\nclass Writer;\n\n// prettywriter.h\n\ntemplate<typename OutputStream, typename SourceEncoding, typename TargetEncoding, typename StackAllocator, unsigned writeFlags>\nclass PrettyWriter;\n\n// document.h\n\ntemplate <typename Encoding, typename Allocator> \nstruct GenericMember;\n\ntemplate <bool Const, typename Encoding, typename Allocator>\nclass GenericMemberIterator;\n\ntemplate<typename CharType>\nstruct GenericStringRef;\n\ntemplate <typename Encoding, typename Allocator> \nclass GenericValue;\n\ntypedef GenericValue<UTF8<char>, MemoryPoolAllocator<CrtAllocator> > Value;\n\ntemplate <typename Encoding, typename Allocator, typename StackAllocator>\nclass GenericDocument;\n\ntypedef GenericDocument<UTF8<char>, MemoryPoolAllocator<CrtAllocator>, CrtAllocator> Document;\n\n// pointer.h\n\ntemplate <typename ValueType, typename Allocator>\nclass GenericPointer;\n\ntypedef GenericPointer<Value, CrtAllocator> Pointer;\n\n// schema.h\n\ntemplate <typename SchemaDocumentType>\nclass IGenericRemoteSchemaDocumentProvider;\n\ntemplate <typename ValueT, typename Allocator>\nclass GenericSchemaDocument;\n\ntypedef GenericSchemaDocument<Value, CrtAllocator> SchemaDocument;\ntypedef IGenericRemoteSchemaDocumentProvider<SchemaDocument> IRemoteSchemaDocumentProvider;\n\ntemplate <\n    typename SchemaDocumentType,\n    typename OutputHandler,\n    typename StateAllocator>\nclass GenericSchemaValidator;\n\ntypedef GenericSchemaValidator<SchemaDocument, BaseReaderHandler<UTF8<char>, void>, CrtAllocator> SchemaValidator;\n\nRAPIDJSON_NAMESPACE_END\n\n#endif // RAPIDJSON_RAPIDJSONFWD_H_\n"
  },
  {
    "path": "rapidjson/internal/biginteger.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_BIGINTEGER_H_\n#define RAPIDJSON_BIGINTEGER_H_\n\n#include \"../rapidjson.h\"\n\n#if defined(_MSC_VER) && defined(_M_AMD64)\n#include <intrin.h> // for _umul128\n#pragma intrinsic(_umul128)\n#endif\n\nRAPIDJSON_NAMESPACE_BEGIN\nnamespace internal {\n\nclass BigInteger {\npublic:\n    typedef uint64_t Type;\n\n    BigInteger(const BigInteger& rhs) : count_(rhs.count_) {\n        std::memcpy(digits_, rhs.digits_, count_ * sizeof(Type));\n    }\n\n    explicit BigInteger(uint64_t u) : count_(1) {\n        digits_[0] = u;\n    }\n\n    BigInteger(const char* decimals, size_t length) : count_(1) {\n        RAPIDJSON_ASSERT(length > 0);\n        digits_[0] = 0;\n        size_t i = 0;\n        const size_t kMaxDigitPerIteration = 19;  // 2^64 = 18446744073709551616 > 10^19\n        while (length >= kMaxDigitPerIteration) {\n            AppendDecimal64(decimals + i, decimals + i + kMaxDigitPerIteration);\n            length -= kMaxDigitPerIteration;\n            i += kMaxDigitPerIteration;\n        }\n\n        if (length > 0)\n            AppendDecimal64(decimals + i, decimals + i + length);\n    }\n    \n    BigInteger& operator=(const BigInteger &rhs)\n    {\n        if (this != &rhs) {\n            count_ = rhs.count_;\n            std::memcpy(digits_, rhs.digits_, count_ * sizeof(Type));\n        }\n        return *this;\n    }\n    \n    BigInteger& operator=(uint64_t u) {\n        digits_[0] = u;            \n        count_ = 1;\n        return *this;\n    }\n\n    BigInteger& operator+=(uint64_t u) {\n        Type backup = digits_[0];\n        digits_[0] += u;\n        for (size_t i = 0; i < count_ - 1; i++) {\n            if (digits_[i] >= backup)\n                return *this; // no carry\n            backup = digits_[i + 1];\n            digits_[i + 1] += 1;\n        }\n\n        // Last carry\n        if (digits_[count_ - 1] < backup)\n            PushBack(1);\n\n        return *this;\n    }\n\n    BigInteger& operator*=(uint64_t u) {\n        if (u == 0) return *this = 0;\n        if (u == 1) return *this;\n        if (*this == 1) return *this = u;\n\n        uint64_t k = 0;\n        for (size_t i = 0; i < count_; i++) {\n            uint64_t hi;\n            digits_[i] = MulAdd64(digits_[i], u, k, &hi);\n            k = hi;\n        }\n        \n        if (k > 0)\n            PushBack(k);\n\n        return *this;\n    }\n\n    BigInteger& operator*=(uint32_t u) {\n        if (u == 0) return *this = 0;\n        if (u == 1) return *this;\n        if (*this == 1) return *this = u;\n\n        uint64_t k = 0;\n        for (size_t i = 0; i < count_; i++) {\n            const uint64_t c = digits_[i] >> 32;\n            const uint64_t d = digits_[i] & 0xFFFFFFFF;\n            const uint64_t uc = u * c;\n            const uint64_t ud = u * d;\n            const uint64_t p0 = ud + k;\n            const uint64_t p1 = uc + (p0 >> 32);\n            digits_[i] = (p0 & 0xFFFFFFFF) | (p1 << 32);\n            k = p1 >> 32;\n        }\n        \n        if (k > 0)\n            PushBack(k);\n\n        return *this;\n    }\n\n    BigInteger& operator<<=(size_t shift) {\n        if (IsZero() || shift == 0) return *this;\n\n        size_t offset = shift / kTypeBit;\n        size_t interShift = shift % kTypeBit;\n        RAPIDJSON_ASSERT(count_ + offset <= kCapacity);\n\n        if (interShift == 0) {\n            std::memmove(&digits_[count_ - 1 + offset], &digits_[count_ - 1], count_ * sizeof(Type));\n            count_ += offset;\n        }\n        else {\n            digits_[count_] = 0;\n            for (size_t i = count_; i > 0; i--)\n                digits_[i + offset] = (digits_[i] << interShift) | (digits_[i - 1] >> (kTypeBit - interShift));\n            digits_[offset] = digits_[0] << interShift;\n            count_ += offset;\n            if (digits_[count_])\n                count_++;\n        }\n\n        std::memset(digits_, 0, offset * sizeof(Type));\n\n        return *this;\n    }\n\n    bool operator==(const BigInteger& rhs) const {\n        return count_ == rhs.count_ && std::memcmp(digits_, rhs.digits_, count_ * sizeof(Type)) == 0;\n    }\n\n    bool operator==(const Type rhs) const {\n        return count_ == 1 && digits_[0] == rhs;\n    }\n\n    BigInteger& MultiplyPow5(unsigned exp) {\n        static const uint32_t kPow5[12] = {\n            5,\n            5 * 5,\n            5 * 5 * 5,\n            5 * 5 * 5 * 5,\n            5 * 5 * 5 * 5 * 5,\n            5 * 5 * 5 * 5 * 5 * 5,\n            5 * 5 * 5 * 5 * 5 * 5 * 5,\n            5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,\n            5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,\n            5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,\n            5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,\n            5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5\n        };\n        if (exp == 0) return *this;\n        for (; exp >= 27; exp -= 27) *this *= RAPIDJSON_UINT64_C2(0X6765C793, 0XFA10079D); // 5^27\n        for (; exp >= 13; exp -= 13) *this *= static_cast<uint32_t>(1220703125u); // 5^13\n        if (exp > 0)                 *this *= kPow5[exp - 1];\n        return *this;\n    }\n\n    // Compute absolute difference of this and rhs.\n    // Assume this != rhs\n    bool Difference(const BigInteger& rhs, BigInteger* out) const {\n        int cmp = Compare(rhs);\n        RAPIDJSON_ASSERT(cmp != 0);\n        const BigInteger *a, *b;  // Makes a > b\n        bool ret;\n        if (cmp < 0) { a = &rhs; b = this; ret = true; }\n        else         { a = this; b = &rhs; ret = false; }\n\n        Type borrow = 0;\n        for (size_t i = 0; i < a->count_; i++) {\n            Type d = a->digits_[i] - borrow;\n            if (i < b->count_)\n                d -= b->digits_[i];\n            borrow = (d > a->digits_[i]) ? 1 : 0;\n            out->digits_[i] = d;\n            if (d != 0)\n                out->count_ = i + 1;\n        }\n\n        return ret;\n    }\n\n    int Compare(const BigInteger& rhs) const {\n        if (count_ != rhs.count_)\n            return count_ < rhs.count_ ? -1 : 1;\n\n        for (size_t i = count_; i-- > 0;)\n            if (digits_[i] != rhs.digits_[i])\n                return digits_[i] < rhs.digits_[i] ? -1 : 1;\n\n        return 0;\n    }\n\n    size_t GetCount() const { return count_; }\n    Type GetDigit(size_t index) const { RAPIDJSON_ASSERT(index < count_); return digits_[index]; }\n    bool IsZero() const { return count_ == 1 && digits_[0] == 0; }\n\nprivate:\n    void AppendDecimal64(const char* begin, const char* end) {\n        uint64_t u = ParseUint64(begin, end);\n        if (IsZero())\n            *this = u;\n        else {\n            unsigned exp = static_cast<unsigned>(end - begin);\n            (MultiplyPow5(exp) <<= exp) += u;   // *this = *this * 10^exp + u\n        }\n    }\n\n    void PushBack(Type digit) {\n        RAPIDJSON_ASSERT(count_ < kCapacity);\n        digits_[count_++] = digit;\n    }\n\n    static uint64_t ParseUint64(const char* begin, const char* end) {\n        uint64_t r = 0;\n        for (const char* p = begin; p != end; ++p) {\n            RAPIDJSON_ASSERT(*p >= '0' && *p <= '9');\n            r = r * 10u + static_cast<unsigned>(*p - '0');\n        }\n        return r;\n    }\n\n    // Assume a * b + k < 2^128\n    static uint64_t MulAdd64(uint64_t a, uint64_t b, uint64_t k, uint64_t* outHigh) {\n#if defined(_MSC_VER) && defined(_M_AMD64)\n        uint64_t low = _umul128(a, b, outHigh) + k;\n        if (low < k)\n            (*outHigh)++;\n        return low;\n#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__)\n        __extension__ typedef unsigned __int128 uint128;\n        uint128 p = static_cast<uint128>(a) * static_cast<uint128>(b);\n        p += k;\n        *outHigh = static_cast<uint64_t>(p >> 64);\n        return static_cast<uint64_t>(p);\n#else\n        const uint64_t a0 = a & 0xFFFFFFFF, a1 = a >> 32, b0 = b & 0xFFFFFFFF, b1 = b >> 32;\n        uint64_t x0 = a0 * b0, x1 = a0 * b1, x2 = a1 * b0, x3 = a1 * b1;\n        x1 += (x0 >> 32); // can't give carry\n        x1 += x2;\n        if (x1 < x2)\n            x3 += (static_cast<uint64_t>(1) << 32);\n        uint64_t lo = (x1 << 32) + (x0 & 0xFFFFFFFF);\n        uint64_t hi = x3 + (x1 >> 32);\n\n        lo += k;\n        if (lo < k)\n            hi++;\n        *outHigh = hi;\n        return lo;\n#endif\n    }\n\n    static const size_t kBitCount = 3328;  // 64bit * 54 > 10^1000\n    static const size_t kCapacity = kBitCount / sizeof(Type);\n    static const size_t kTypeBit = sizeof(Type) * 8;\n\n    Type digits_[kCapacity];\n    size_t count_;\n};\n\n} // namespace internal\nRAPIDJSON_NAMESPACE_END\n\n#endif // RAPIDJSON_BIGINTEGER_H_\n"
  },
  {
    "path": "rapidjson/internal/diyfp.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n// This is a C++ header-only implementation of Grisu2 algorithm from the publication:\n// Loitsch, Florian. \"Printing floating-point numbers quickly and accurately with\n// integers.\" ACM Sigplan Notices 45.6 (2010): 233-243.\n\n#ifndef RAPIDJSON_DIYFP_H_\n#define RAPIDJSON_DIYFP_H_\n\n#include \"../rapidjson.h\"\n\n#if defined(_MSC_VER) && defined(_M_AMD64)\n#include <intrin.h>\n#pragma intrinsic(_BitScanReverse64)\n#pragma intrinsic(_umul128)\n#endif\n\nRAPIDJSON_NAMESPACE_BEGIN\nnamespace internal {\n\n#ifdef __GNUC__\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(effc++)\n#endif\n\n#ifdef __clang__\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(padded)\n#endif\n\nstruct DiyFp {\n    DiyFp() : f(), e() {}\n\n    DiyFp(uint64_t fp, int exp) : f(fp), e(exp) {}\n\n    explicit DiyFp(double d) {\n        union {\n            double d;\n            uint64_t u64;\n        } u = { d };\n\n        int biased_e = static_cast<int>((u.u64 & kDpExponentMask) >> kDpSignificandSize);\n        uint64_t significand = (u.u64 & kDpSignificandMask);\n        if (biased_e != 0) {\n            f = significand + kDpHiddenBit;\n            e = biased_e - kDpExponentBias;\n        } \n        else {\n            f = significand;\n            e = kDpMinExponent + 1;\n        }\n    }\n\n    DiyFp operator-(const DiyFp& rhs) const {\n        return DiyFp(f - rhs.f, e);\n    }\n\n    DiyFp operator*(const DiyFp& rhs) const {\n#if defined(_MSC_VER) && defined(_M_AMD64)\n        uint64_t h;\n        uint64_t l = _umul128(f, rhs.f, &h);\n        if (l & (uint64_t(1) << 63)) // rounding\n            h++;\n        return DiyFp(h, e + rhs.e + 64);\n#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__)\n        __extension__ typedef unsigned __int128 uint128;\n        uint128 p = static_cast<uint128>(f) * static_cast<uint128>(rhs.f);\n        uint64_t h = static_cast<uint64_t>(p >> 64);\n        uint64_t l = static_cast<uint64_t>(p);\n        if (l & (uint64_t(1) << 63)) // rounding\n            h++;\n        return DiyFp(h, e + rhs.e + 64);\n#else\n        const uint64_t M32 = 0xFFFFFFFF;\n        const uint64_t a = f >> 32;\n        const uint64_t b = f & M32;\n        const uint64_t c = rhs.f >> 32;\n        const uint64_t d = rhs.f & M32;\n        const uint64_t ac = a * c;\n        const uint64_t bc = b * c;\n        const uint64_t ad = a * d;\n        const uint64_t bd = b * d;\n        uint64_t tmp = (bd >> 32) + (ad & M32) + (bc & M32);\n        tmp += 1U << 31;  /// mult_round\n        return DiyFp(ac + (ad >> 32) + (bc >> 32) + (tmp >> 32), e + rhs.e + 64);\n#endif\n    }\n\n    DiyFp Normalize() const {\n#if defined(_MSC_VER) && defined(_M_AMD64)\n        unsigned long index;\n        _BitScanReverse64(&index, f);\n        return DiyFp(f << (63 - index), e - (63 - index));\n#elif defined(__GNUC__) && __GNUC__ >= 4\n        int s = __builtin_clzll(f);\n        return DiyFp(f << s, e - s);\n#else\n        DiyFp res = *this;\n        while (!(res.f & (static_cast<uint64_t>(1) << 63))) {\n            res.f <<= 1;\n            res.e--;\n        }\n        return res;\n#endif\n    }\n\n    DiyFp NormalizeBoundary() const {\n        DiyFp res = *this;\n        while (!(res.f & (kDpHiddenBit << 1))) {\n            res.f <<= 1;\n            res.e--;\n        }\n        res.f <<= (kDiySignificandSize - kDpSignificandSize - 2);\n        res.e = res.e - (kDiySignificandSize - kDpSignificandSize - 2);\n        return res;\n    }\n\n    void NormalizedBoundaries(DiyFp* minus, DiyFp* plus) const {\n        DiyFp pl = DiyFp((f << 1) + 1, e - 1).NormalizeBoundary();\n        DiyFp mi = (f == kDpHiddenBit) ? DiyFp((f << 2) - 1, e - 2) : DiyFp((f << 1) - 1, e - 1);\n        mi.f <<= mi.e - pl.e;\n        mi.e = pl.e;\n        *plus = pl;\n        *minus = mi;\n    }\n\n    double ToDouble() const {\n        union {\n            double d;\n            uint64_t u64;\n        }u;\n        const uint64_t be = (e == kDpDenormalExponent && (f & kDpHiddenBit) == 0) ? 0 : \n            static_cast<uint64_t>(e + kDpExponentBias);\n        u.u64 = (f & kDpSignificandMask) | (be << kDpSignificandSize);\n        return u.d;\n    }\n\n    static const int kDiySignificandSize = 64;\n    static const int kDpSignificandSize = 52;\n    static const int kDpExponentBias = 0x3FF + kDpSignificandSize;\n    static const int kDpMaxExponent = 0x7FF - kDpExponentBias;\n    static const int kDpMinExponent = -kDpExponentBias;\n    static const int kDpDenormalExponent = -kDpExponentBias + 1;\n    static const uint64_t kDpExponentMask = RAPIDJSON_UINT64_C2(0x7FF00000, 0x00000000);\n    static const uint64_t kDpSignificandMask = RAPIDJSON_UINT64_C2(0x000FFFFF, 0xFFFFFFFF);\n    static const uint64_t kDpHiddenBit = RAPIDJSON_UINT64_C2(0x00100000, 0x00000000);\n\n    uint64_t f;\n    int e;\n};\n\ninline DiyFp GetCachedPowerByIndex(size_t index) {\n    // 10^-348, 10^-340, ..., 10^340\n    static const uint64_t kCachedPowers_F[] = {\n        RAPIDJSON_UINT64_C2(0xfa8fd5a0, 0x081c0288), RAPIDJSON_UINT64_C2(0xbaaee17f, 0xa23ebf76),\n        RAPIDJSON_UINT64_C2(0x8b16fb20, 0x3055ac76), RAPIDJSON_UINT64_C2(0xcf42894a, 0x5dce35ea),\n        RAPIDJSON_UINT64_C2(0x9a6bb0aa, 0x55653b2d), RAPIDJSON_UINT64_C2(0xe61acf03, 0x3d1a45df),\n        RAPIDJSON_UINT64_C2(0xab70fe17, 0xc79ac6ca), RAPIDJSON_UINT64_C2(0xff77b1fc, 0xbebcdc4f),\n        RAPIDJSON_UINT64_C2(0xbe5691ef, 0x416bd60c), RAPIDJSON_UINT64_C2(0x8dd01fad, 0x907ffc3c),\n        RAPIDJSON_UINT64_C2(0xd3515c28, 0x31559a83), RAPIDJSON_UINT64_C2(0x9d71ac8f, 0xada6c9b5),\n        RAPIDJSON_UINT64_C2(0xea9c2277, 0x23ee8bcb), RAPIDJSON_UINT64_C2(0xaecc4991, 0x4078536d),\n        RAPIDJSON_UINT64_C2(0x823c1279, 0x5db6ce57), RAPIDJSON_UINT64_C2(0xc2109436, 0x4dfb5637),\n        RAPIDJSON_UINT64_C2(0x9096ea6f, 0x3848984f), RAPIDJSON_UINT64_C2(0xd77485cb, 0x25823ac7),\n        RAPIDJSON_UINT64_C2(0xa086cfcd, 0x97bf97f4), RAPIDJSON_UINT64_C2(0xef340a98, 0x172aace5),\n        RAPIDJSON_UINT64_C2(0xb23867fb, 0x2a35b28e), RAPIDJSON_UINT64_C2(0x84c8d4df, 0xd2c63f3b),\n        RAPIDJSON_UINT64_C2(0xc5dd4427, 0x1ad3cdba), RAPIDJSON_UINT64_C2(0x936b9fce, 0xbb25c996),\n        RAPIDJSON_UINT64_C2(0xdbac6c24, 0x7d62a584), RAPIDJSON_UINT64_C2(0xa3ab6658, 0x0d5fdaf6),\n        RAPIDJSON_UINT64_C2(0xf3e2f893, 0xdec3f126), RAPIDJSON_UINT64_C2(0xb5b5ada8, 0xaaff80b8),\n        RAPIDJSON_UINT64_C2(0x87625f05, 0x6c7c4a8b), RAPIDJSON_UINT64_C2(0xc9bcff60, 0x34c13053),\n        RAPIDJSON_UINT64_C2(0x964e858c, 0x91ba2655), RAPIDJSON_UINT64_C2(0xdff97724, 0x70297ebd),\n        RAPIDJSON_UINT64_C2(0xa6dfbd9f, 0xb8e5b88f), RAPIDJSON_UINT64_C2(0xf8a95fcf, 0x88747d94),\n        RAPIDJSON_UINT64_C2(0xb9447093, 0x8fa89bcf), RAPIDJSON_UINT64_C2(0x8a08f0f8, 0xbf0f156b),\n        RAPIDJSON_UINT64_C2(0xcdb02555, 0x653131b6), RAPIDJSON_UINT64_C2(0x993fe2c6, 0xd07b7fac),\n        RAPIDJSON_UINT64_C2(0xe45c10c4, 0x2a2b3b06), RAPIDJSON_UINT64_C2(0xaa242499, 0x697392d3),\n        RAPIDJSON_UINT64_C2(0xfd87b5f2, 0x8300ca0e), RAPIDJSON_UINT64_C2(0xbce50864, 0x92111aeb),\n        RAPIDJSON_UINT64_C2(0x8cbccc09, 0x6f5088cc), RAPIDJSON_UINT64_C2(0xd1b71758, 0xe219652c),\n        RAPIDJSON_UINT64_C2(0x9c400000, 0x00000000), RAPIDJSON_UINT64_C2(0xe8d4a510, 0x00000000),\n        RAPIDJSON_UINT64_C2(0xad78ebc5, 0xac620000), RAPIDJSON_UINT64_C2(0x813f3978, 0xf8940984),\n        RAPIDJSON_UINT64_C2(0xc097ce7b, 0xc90715b3), RAPIDJSON_UINT64_C2(0x8f7e32ce, 0x7bea5c70),\n        RAPIDJSON_UINT64_C2(0xd5d238a4, 0xabe98068), RAPIDJSON_UINT64_C2(0x9f4f2726, 0x179a2245),\n        RAPIDJSON_UINT64_C2(0xed63a231, 0xd4c4fb27), RAPIDJSON_UINT64_C2(0xb0de6538, 0x8cc8ada8),\n        RAPIDJSON_UINT64_C2(0x83c7088e, 0x1aab65db), RAPIDJSON_UINT64_C2(0xc45d1df9, 0x42711d9a),\n        RAPIDJSON_UINT64_C2(0x924d692c, 0xa61be758), RAPIDJSON_UINT64_C2(0xda01ee64, 0x1a708dea),\n        RAPIDJSON_UINT64_C2(0xa26da399, 0x9aef774a), RAPIDJSON_UINT64_C2(0xf209787b, 0xb47d6b85),\n        RAPIDJSON_UINT64_C2(0xb454e4a1, 0x79dd1877), RAPIDJSON_UINT64_C2(0x865b8692, 0x5b9bc5c2),\n        RAPIDJSON_UINT64_C2(0xc83553c5, 0xc8965d3d), RAPIDJSON_UINT64_C2(0x952ab45c, 0xfa97a0b3),\n        RAPIDJSON_UINT64_C2(0xde469fbd, 0x99a05fe3), RAPIDJSON_UINT64_C2(0xa59bc234, 0xdb398c25),\n        RAPIDJSON_UINT64_C2(0xf6c69a72, 0xa3989f5c), RAPIDJSON_UINT64_C2(0xb7dcbf53, 0x54e9bece),\n        RAPIDJSON_UINT64_C2(0x88fcf317, 0xf22241e2), RAPIDJSON_UINT64_C2(0xcc20ce9b, 0xd35c78a5),\n        RAPIDJSON_UINT64_C2(0x98165af3, 0x7b2153df), RAPIDJSON_UINT64_C2(0xe2a0b5dc, 0x971f303a),\n        RAPIDJSON_UINT64_C2(0xa8d9d153, 0x5ce3b396), RAPIDJSON_UINT64_C2(0xfb9b7cd9, 0xa4a7443c),\n        RAPIDJSON_UINT64_C2(0xbb764c4c, 0xa7a44410), RAPIDJSON_UINT64_C2(0x8bab8eef, 0xb6409c1a),\n        RAPIDJSON_UINT64_C2(0xd01fef10, 0xa657842c), RAPIDJSON_UINT64_C2(0x9b10a4e5, 0xe9913129),\n        RAPIDJSON_UINT64_C2(0xe7109bfb, 0xa19c0c9d), RAPIDJSON_UINT64_C2(0xac2820d9, 0x623bf429),\n        RAPIDJSON_UINT64_C2(0x80444b5e, 0x7aa7cf85), RAPIDJSON_UINT64_C2(0xbf21e440, 0x03acdd2d),\n        RAPIDJSON_UINT64_C2(0x8e679c2f, 0x5e44ff8f), RAPIDJSON_UINT64_C2(0xd433179d, 0x9c8cb841),\n        RAPIDJSON_UINT64_C2(0x9e19db92, 0xb4e31ba9), RAPIDJSON_UINT64_C2(0xeb96bf6e, 0xbadf77d9),\n        RAPIDJSON_UINT64_C2(0xaf87023b, 0x9bf0ee6b)\n    };\n    static const int16_t kCachedPowers_E[] = {\n        -1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007,  -980,\n        -954,  -927,  -901,  -874,  -847,  -821,  -794,  -768,  -741,  -715,\n        -688,  -661,  -635,  -608,  -582,  -555,  -529,  -502,  -475,  -449,\n        -422,  -396,  -369,  -343,  -316,  -289,  -263,  -236,  -210,  -183,\n        -157,  -130,  -103,   -77,   -50,   -24,     3,    30,    56,    83,\n        109,   136,   162,   189,   216,   242,   269,   295,   322,   348,\n        375,   402,   428,   455,   481,   508,   534,   561,   588,   614,\n        641,   667,   694,   720,   747,   774,   800,   827,   853,   880,\n        907,   933,   960,   986,  1013,  1039,  1066\n    };\n    return DiyFp(kCachedPowers_F[index], kCachedPowers_E[index]);\n}\n    \ninline DiyFp GetCachedPower(int e, int* K) {\n\n    //int k = static_cast<int>(ceil((-61 - e) * 0.30102999566398114)) + 374;\n    double dk = (-61 - e) * 0.30102999566398114 + 347;  // dk must be positive, so can do ceiling in positive\n    int k = static_cast<int>(dk);\n    if (dk - k > 0.0)\n        k++;\n\n    unsigned index = static_cast<unsigned>((k >> 3) + 1);\n    *K = -(-348 + static_cast<int>(index << 3));    // decimal exponent no need lookup table\n\n    return GetCachedPowerByIndex(index);\n}\n\ninline DiyFp GetCachedPower10(int exp, int *outExp) {\n     unsigned index = (static_cast<unsigned>(exp) + 348u) / 8u;\n     *outExp = -348 + static_cast<int>(index) * 8;\n     return GetCachedPowerByIndex(index);\n }\n\n#ifdef __GNUC__\nRAPIDJSON_DIAG_POP\n#endif\n\n#ifdef __clang__\nRAPIDJSON_DIAG_POP\nRAPIDJSON_DIAG_OFF(padded)\n#endif\n\n} // namespace internal\nRAPIDJSON_NAMESPACE_END\n\n#endif // RAPIDJSON_DIYFP_H_\n"
  },
  {
    "path": "rapidjson/internal/dtoa.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n// This is a C++ header-only implementation of Grisu2 algorithm from the publication:\n// Loitsch, Florian. \"Printing floating-point numbers quickly and accurately with\n// integers.\" ACM Sigplan Notices 45.6 (2010): 233-243.\n\n#ifndef RAPIDJSON_DTOA_\n#define RAPIDJSON_DTOA_\n\n#include \"itoa.h\" // GetDigitsLut()\n#include \"diyfp.h\"\n#include \"ieee754.h\"\n\nRAPIDJSON_NAMESPACE_BEGIN\nnamespace internal {\n\n#ifdef __GNUC__\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(effc++)\nRAPIDJSON_DIAG_OFF(array-bounds) // some gcc versions generate wrong warnings https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59124\n#endif\n\ninline void GrisuRound(char* buffer, int len, uint64_t delta, uint64_t rest, uint64_t ten_kappa, uint64_t wp_w) {\n    while (rest < wp_w && delta - rest >= ten_kappa &&\n           (rest + ten_kappa < wp_w ||  /// closer\n            wp_w - rest > rest + ten_kappa - wp_w)) {\n        buffer[len - 1]--;\n        rest += ten_kappa;\n    }\n}\n\ninline unsigned CountDecimalDigit32(uint32_t n) {\n    // Simple pure C++ implementation was faster than __builtin_clz version in this situation.\n    if (n < 10) return 1;\n    if (n < 100) return 2;\n    if (n < 1000) return 3;\n    if (n < 10000) return 4;\n    if (n < 100000) return 5;\n    if (n < 1000000) return 6;\n    if (n < 10000000) return 7;\n    if (n < 100000000) return 8;\n    // Will not reach 10 digits in DigitGen()\n    //if (n < 1000000000) return 9;\n    //return 10;\n    return 9;\n}\n\ninline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buffer, int* len, int* K) {\n    static const uint32_t kPow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };\n    const DiyFp one(uint64_t(1) << -Mp.e, Mp.e);\n    const DiyFp wp_w = Mp - W;\n    uint32_t p1 = static_cast<uint32_t>(Mp.f >> -one.e);\n    uint64_t p2 = Mp.f & (one.f - 1);\n    unsigned kappa = CountDecimalDigit32(p1); // kappa in [0, 9]\n    *len = 0;\n\n    while (kappa > 0) {\n        uint32_t d = 0;\n        switch (kappa) {\n            case  9: d = p1 /  100000000; p1 %=  100000000; break;\n            case  8: d = p1 /   10000000; p1 %=   10000000; break;\n            case  7: d = p1 /    1000000; p1 %=    1000000; break;\n            case  6: d = p1 /     100000; p1 %=     100000; break;\n            case  5: d = p1 /      10000; p1 %=      10000; break;\n            case  4: d = p1 /       1000; p1 %=       1000; break;\n            case  3: d = p1 /        100; p1 %=        100; break;\n            case  2: d = p1 /         10; p1 %=         10; break;\n            case  1: d = p1;              p1 =           0; break;\n            default:;\n        }\n        if (d || *len)\n            buffer[(*len)++] = static_cast<char>('0' + static_cast<char>(d));\n        kappa--;\n        uint64_t tmp = (static_cast<uint64_t>(p1) << -one.e) + p2;\n        if (tmp <= delta) {\n            *K += kappa;\n            GrisuRound(buffer, *len, delta, tmp, static_cast<uint64_t>(kPow10[kappa]) << -one.e, wp_w.f);\n            return;\n        }\n    }\n\n    // kappa = 0\n    for (;;) {\n        p2 *= 10;\n        delta *= 10;\n        char d = static_cast<char>(p2 >> -one.e);\n        if (d || *len)\n            buffer[(*len)++] = static_cast<char>('0' + d);\n        p2 &= one.f - 1;\n        kappa--;\n        if (p2 < delta) {\n            *K += kappa;\n            int index = -static_cast<int>(kappa);\n            GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * (index < 9 ? kPow10[-static_cast<int>(kappa)] : 0));\n            return;\n        }\n    }\n}\n\ninline void Grisu2(double value, char* buffer, int* length, int* K) {\n    const DiyFp v(value);\n    DiyFp w_m, w_p;\n    v.NormalizedBoundaries(&w_m, &w_p);\n\n    const DiyFp c_mk = GetCachedPower(w_p.e, K);\n    const DiyFp W = v.Normalize() * c_mk;\n    DiyFp Wp = w_p * c_mk;\n    DiyFp Wm = w_m * c_mk;\n    Wm.f++;\n    Wp.f--;\n    DigitGen(W, Wp, Wp.f - Wm.f, buffer, length, K);\n}\n\ninline char* WriteExponent(int K, char* buffer) {\n    if (K < 0) {\n        *buffer++ = '-';\n        K = -K;\n    }\n\n    if (K >= 100) {\n        *buffer++ = static_cast<char>('0' + static_cast<char>(K / 100));\n        K %= 100;\n        const char* d = GetDigitsLut() + K * 2;\n        *buffer++ = d[0];\n        *buffer++ = d[1];\n    }\n    else if (K >= 10) {\n        const char* d = GetDigitsLut() + K * 2;\n        *buffer++ = d[0];\n        *buffer++ = d[1];\n    }\n    else\n        *buffer++ = static_cast<char>('0' + static_cast<char>(K));\n\n    return buffer;\n}\n\ninline char* Prettify(char* buffer, int length, int k, int maxDecimalPlaces) {\n    const int kk = length + k;  // 10^(kk-1) <= v < 10^kk\n\n    if (0 <= k && kk <= 21) {\n        // 1234e7 -> 12340000000\n        for (int i = length; i < kk; i++)\n            buffer[i] = '0';\n        buffer[kk] = '.';\n        buffer[kk + 1] = '0';\n        return &buffer[kk + 2];\n    }\n    else if (0 < kk && kk <= 21) {\n        // 1234e-2 -> 12.34\n        std::memmove(&buffer[kk + 1], &buffer[kk], static_cast<size_t>(length - kk));\n        buffer[kk] = '.';\n        if (0 > k + maxDecimalPlaces) {\n            // When maxDecimalPlaces = 2, 1.2345 -> 1.23, 1.102 -> 1.1\n            // Remove extra trailing zeros (at least one) after truncation.\n            for (int i = kk + maxDecimalPlaces; i > kk + 1; i--)\n                if (buffer[i] != '0')\n                    return &buffer[i + 1];\n            return &buffer[kk + 2]; // Reserve one zero\n        }\n        else\n            return &buffer[length + 1];\n    }\n    else if (-6 < kk && kk <= 0) {\n        // 1234e-6 -> 0.001234\n        const int offset = 2 - kk;\n        std::memmove(&buffer[offset], &buffer[0], static_cast<size_t>(length));\n        buffer[0] = '0';\n        buffer[1] = '.';\n        for (int i = 2; i < offset; i++)\n            buffer[i] = '0';\n        if (length - kk > maxDecimalPlaces) {\n            // When maxDecimalPlaces = 2, 0.123 -> 0.12, 0.102 -> 0.1\n            // Remove extra trailing zeros (at least one) after truncation.\n            for (int i = maxDecimalPlaces + 1; i > 2; i--)\n                if (buffer[i] != '0')\n                    return &buffer[i + 1];\n            return &buffer[3]; // Reserve one zero\n        }\n        else\n            return &buffer[length + offset];\n    }\n    else if (kk < -maxDecimalPlaces) {\n        // Truncate to zero\n        buffer[0] = '0';\n        buffer[1] = '.';\n        buffer[2] = '0';\n        return &buffer[3];\n    }\n    else if (length == 1) {\n        // 1e30\n        buffer[1] = 'e';\n        return WriteExponent(kk - 1, &buffer[2]);\n    }\n    else {\n        // 1234e30 -> 1.234e33\n        std::memmove(&buffer[2], &buffer[1], static_cast<size_t>(length - 1));\n        buffer[1] = '.';\n        buffer[length + 1] = 'e';\n        return WriteExponent(kk - 1, &buffer[0 + length + 2]);\n    }\n}\n\ninline char* dtoa(double value, char* buffer, int maxDecimalPlaces = 324) {\n    RAPIDJSON_ASSERT(maxDecimalPlaces >= 1);\n    Double d(value);\n    if (d.IsZero()) {\n        if (d.Sign())\n            *buffer++ = '-';     // -0.0, Issue #289\n        buffer[0] = '0';\n        buffer[1] = '.';\n        buffer[2] = '0';\n        return &buffer[3];\n    }\n    else {\n        if (value < 0) {\n            *buffer++ = '-';\n            value = -value;\n        }\n        int length, K;\n        Grisu2(value, buffer, &length, &K);\n        return Prettify(buffer, length, K, maxDecimalPlaces);\n    }\n}\n\n#ifdef __GNUC__\nRAPIDJSON_DIAG_POP\n#endif\n\n} // namespace internal\nRAPIDJSON_NAMESPACE_END\n\n#endif // RAPIDJSON_DTOA_\n"
  },
  {
    "path": "rapidjson/internal/ieee754.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_IEEE754_\n#define RAPIDJSON_IEEE754_\n\n#include \"../rapidjson.h\"\n\nRAPIDJSON_NAMESPACE_BEGIN\nnamespace internal {\n\nclass Double {\npublic:\n    Double() {}\n    Double(double d) : d_(d) {}\n    Double(uint64_t u) : u_(u) {}\n\n    double Value() const { return d_; }\n    uint64_t Uint64Value() const { return u_; }\n\n    double NextPositiveDouble() const {\n        RAPIDJSON_ASSERT(!Sign());\n        return Double(u_ + 1).Value();\n    }\n\n    bool Sign() const { return (u_ & kSignMask) != 0; }\n    uint64_t Significand() const { return u_ & kSignificandMask; }\n    int Exponent() const { return static_cast<int>(((u_ & kExponentMask) >> kSignificandSize) - kExponentBias); }\n\n    bool IsNan() const { return (u_ & kExponentMask) == kExponentMask && Significand() != 0; }\n    bool IsInf() const { return (u_ & kExponentMask) == kExponentMask && Significand() == 0; }\n    bool IsNanOrInf() const { return (u_ & kExponentMask) == kExponentMask; }\n    bool IsNormal() const { return (u_ & kExponentMask) != 0 || Significand() == 0; }\n    bool IsZero() const { return (u_ & (kExponentMask | kSignificandMask)) == 0; }\n\n    uint64_t IntegerSignificand() const { return IsNormal() ? Significand() | kHiddenBit : Significand(); }\n    int IntegerExponent() const { return (IsNormal() ? Exponent() : kDenormalExponent) - kSignificandSize; }\n    uint64_t ToBias() const { return (u_ & kSignMask) ? ~u_ + 1 : u_ | kSignMask; }\n\n    static unsigned EffectiveSignificandSize(int order) {\n        if (order >= -1021)\n            return 53;\n        else if (order <= -1074)\n            return 0;\n        else\n            return static_cast<unsigned>(order) + 1074;\n    }\n\nprivate:\n    static const int kSignificandSize = 52;\n    static const int kExponentBias = 0x3FF;\n    static const int kDenormalExponent = 1 - kExponentBias;\n    static const uint64_t kSignMask = RAPIDJSON_UINT64_C2(0x80000000, 0x00000000);\n    static const uint64_t kExponentMask = RAPIDJSON_UINT64_C2(0x7FF00000, 0x00000000);\n    static const uint64_t kSignificandMask = RAPIDJSON_UINT64_C2(0x000FFFFF, 0xFFFFFFFF);\n    static const uint64_t kHiddenBit = RAPIDJSON_UINT64_C2(0x00100000, 0x00000000);\n\n    union {\n        double d_;\n        uint64_t u_;\n    };\n};\n\n} // namespace internal\nRAPIDJSON_NAMESPACE_END\n\n#endif // RAPIDJSON_IEEE754_\n"
  },
  {
    "path": "rapidjson/internal/itoa.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_ITOA_\n#define RAPIDJSON_ITOA_\n\n#include \"../rapidjson.h\"\n\nRAPIDJSON_NAMESPACE_BEGIN\nnamespace internal {\n\ninline const char* GetDigitsLut() {\n    static const char cDigitsLut[200] = {\n        '0','0','0','1','0','2','0','3','0','4','0','5','0','6','0','7','0','8','0','9',\n        '1','0','1','1','1','2','1','3','1','4','1','5','1','6','1','7','1','8','1','9',\n        '2','0','2','1','2','2','2','3','2','4','2','5','2','6','2','7','2','8','2','9',\n        '3','0','3','1','3','2','3','3','3','4','3','5','3','6','3','7','3','8','3','9',\n        '4','0','4','1','4','2','4','3','4','4','4','5','4','6','4','7','4','8','4','9',\n        '5','0','5','1','5','2','5','3','5','4','5','5','5','6','5','7','5','8','5','9',\n        '6','0','6','1','6','2','6','3','6','4','6','5','6','6','6','7','6','8','6','9',\n        '7','0','7','1','7','2','7','3','7','4','7','5','7','6','7','7','7','8','7','9',\n        '8','0','8','1','8','2','8','3','8','4','8','5','8','6','8','7','8','8','8','9',\n        '9','0','9','1','9','2','9','3','9','4','9','5','9','6','9','7','9','8','9','9'\n    };\n    return cDigitsLut;\n}\n\ninline char* u32toa(uint32_t value, char* buffer) {\n    const char* cDigitsLut = GetDigitsLut();\n\n    if (value < 10000) {\n        const uint32_t d1 = (value / 100) << 1;\n        const uint32_t d2 = (value % 100) << 1;\n        \n        if (value >= 1000)\n            *buffer++ = cDigitsLut[d1];\n        if (value >= 100)\n            *buffer++ = cDigitsLut[d1 + 1];\n        if (value >= 10)\n            *buffer++ = cDigitsLut[d2];\n        *buffer++ = cDigitsLut[d2 + 1];\n    }\n    else if (value < 100000000) {\n        // value = bbbbcccc\n        const uint32_t b = value / 10000;\n        const uint32_t c = value % 10000;\n        \n        const uint32_t d1 = (b / 100) << 1;\n        const uint32_t d2 = (b % 100) << 1;\n        \n        const uint32_t d3 = (c / 100) << 1;\n        const uint32_t d4 = (c % 100) << 1;\n        \n        if (value >= 10000000)\n            *buffer++ = cDigitsLut[d1];\n        if (value >= 1000000)\n            *buffer++ = cDigitsLut[d1 + 1];\n        if (value >= 100000)\n            *buffer++ = cDigitsLut[d2];\n        *buffer++ = cDigitsLut[d2 + 1];\n        \n        *buffer++ = cDigitsLut[d3];\n        *buffer++ = cDigitsLut[d3 + 1];\n        *buffer++ = cDigitsLut[d4];\n        *buffer++ = cDigitsLut[d4 + 1];\n    }\n    else {\n        // value = aabbbbcccc in decimal\n        \n        const uint32_t a = value / 100000000; // 1 to 42\n        value %= 100000000;\n        \n        if (a >= 10) {\n            const unsigned i = a << 1;\n            *buffer++ = cDigitsLut[i];\n            *buffer++ = cDigitsLut[i + 1];\n        }\n        else\n            *buffer++ = static_cast<char>('0' + static_cast<char>(a));\n\n        const uint32_t b = value / 10000; // 0 to 9999\n        const uint32_t c = value % 10000; // 0 to 9999\n        \n        const uint32_t d1 = (b / 100) << 1;\n        const uint32_t d2 = (b % 100) << 1;\n        \n        const uint32_t d3 = (c / 100) << 1;\n        const uint32_t d4 = (c % 100) << 1;\n        \n        *buffer++ = cDigitsLut[d1];\n        *buffer++ = cDigitsLut[d1 + 1];\n        *buffer++ = cDigitsLut[d2];\n        *buffer++ = cDigitsLut[d2 + 1];\n        *buffer++ = cDigitsLut[d3];\n        *buffer++ = cDigitsLut[d3 + 1];\n        *buffer++ = cDigitsLut[d4];\n        *buffer++ = cDigitsLut[d4 + 1];\n    }\n    return buffer;\n}\n\ninline char* i32toa(int32_t value, char* buffer) {\n    uint32_t u = static_cast<uint32_t>(value);\n    if (value < 0) {\n        *buffer++ = '-';\n        u = ~u + 1;\n    }\n\n    return u32toa(u, buffer);\n}\n\ninline char* u64toa(uint64_t value, char* buffer) {\n    const char* cDigitsLut = GetDigitsLut();\n    const uint64_t  kTen8 = 100000000;\n    const uint64_t  kTen9 = kTen8 * 10;\n    const uint64_t kTen10 = kTen8 * 100;\n    const uint64_t kTen11 = kTen8 * 1000;\n    const uint64_t kTen12 = kTen8 * 10000;\n    const uint64_t kTen13 = kTen8 * 100000;\n    const uint64_t kTen14 = kTen8 * 1000000;\n    const uint64_t kTen15 = kTen8 * 10000000;\n    const uint64_t kTen16 = kTen8 * kTen8;\n    \n    if (value < kTen8) {\n        uint32_t v = static_cast<uint32_t>(value);\n        if (v < 10000) {\n            const uint32_t d1 = (v / 100) << 1;\n            const uint32_t d2 = (v % 100) << 1;\n            \n            if (v >= 1000)\n                *buffer++ = cDigitsLut[d1];\n            if (v >= 100)\n                *buffer++ = cDigitsLut[d1 + 1];\n            if (v >= 10)\n                *buffer++ = cDigitsLut[d2];\n            *buffer++ = cDigitsLut[d2 + 1];\n        }\n        else {\n            // value = bbbbcccc\n            const uint32_t b = v / 10000;\n            const uint32_t c = v % 10000;\n            \n            const uint32_t d1 = (b / 100) << 1;\n            const uint32_t d2 = (b % 100) << 1;\n            \n            const uint32_t d3 = (c / 100) << 1;\n            const uint32_t d4 = (c % 100) << 1;\n            \n            if (value >= 10000000)\n                *buffer++ = cDigitsLut[d1];\n            if (value >= 1000000)\n                *buffer++ = cDigitsLut[d1 + 1];\n            if (value >= 100000)\n                *buffer++ = cDigitsLut[d2];\n            *buffer++ = cDigitsLut[d2 + 1];\n            \n            *buffer++ = cDigitsLut[d3];\n            *buffer++ = cDigitsLut[d3 + 1];\n            *buffer++ = cDigitsLut[d4];\n            *buffer++ = cDigitsLut[d4 + 1];\n        }\n    }\n    else if (value < kTen16) {\n        const uint32_t v0 = static_cast<uint32_t>(value / kTen8);\n        const uint32_t v1 = static_cast<uint32_t>(value % kTen8);\n        \n        const uint32_t b0 = v0 / 10000;\n        const uint32_t c0 = v0 % 10000;\n        \n        const uint32_t d1 = (b0 / 100) << 1;\n        const uint32_t d2 = (b0 % 100) << 1;\n        \n        const uint32_t d3 = (c0 / 100) << 1;\n        const uint32_t d4 = (c0 % 100) << 1;\n\n        const uint32_t b1 = v1 / 10000;\n        const uint32_t c1 = v1 % 10000;\n        \n        const uint32_t d5 = (b1 / 100) << 1;\n        const uint32_t d6 = (b1 % 100) << 1;\n        \n        const uint32_t d7 = (c1 / 100) << 1;\n        const uint32_t d8 = (c1 % 100) << 1;\n\n        if (value >= kTen15)\n            *buffer++ = cDigitsLut[d1];\n        if (value >= kTen14)\n            *buffer++ = cDigitsLut[d1 + 1];\n        if (value >= kTen13)\n            *buffer++ = cDigitsLut[d2];\n        if (value >= kTen12)\n            *buffer++ = cDigitsLut[d2 + 1];\n        if (value >= kTen11)\n            *buffer++ = cDigitsLut[d3];\n        if (value >= kTen10)\n            *buffer++ = cDigitsLut[d3 + 1];\n        if (value >= kTen9)\n            *buffer++ = cDigitsLut[d4];\n        if (value >= kTen8)\n            *buffer++ = cDigitsLut[d4 + 1];\n        \n        *buffer++ = cDigitsLut[d5];\n        *buffer++ = cDigitsLut[d5 + 1];\n        *buffer++ = cDigitsLut[d6];\n        *buffer++ = cDigitsLut[d6 + 1];\n        *buffer++ = cDigitsLut[d7];\n        *buffer++ = cDigitsLut[d7 + 1];\n        *buffer++ = cDigitsLut[d8];\n        *buffer++ = cDigitsLut[d8 + 1];\n    }\n    else {\n        const uint32_t a = static_cast<uint32_t>(value / kTen16); // 1 to 1844\n        value %= kTen16;\n        \n        if (a < 10)\n            *buffer++ = static_cast<char>('0' + static_cast<char>(a));\n        else if (a < 100) {\n            const uint32_t i = a << 1;\n            *buffer++ = cDigitsLut[i];\n            *buffer++ = cDigitsLut[i + 1];\n        }\n        else if (a < 1000) {\n            *buffer++ = static_cast<char>('0' + static_cast<char>(a / 100));\n            \n            const uint32_t i = (a % 100) << 1;\n            *buffer++ = cDigitsLut[i];\n            *buffer++ = cDigitsLut[i + 1];\n        }\n        else {\n            const uint32_t i = (a / 100) << 1;\n            const uint32_t j = (a % 100) << 1;\n            *buffer++ = cDigitsLut[i];\n            *buffer++ = cDigitsLut[i + 1];\n            *buffer++ = cDigitsLut[j];\n            *buffer++ = cDigitsLut[j + 1];\n        }\n        \n        const uint32_t v0 = static_cast<uint32_t>(value / kTen8);\n        const uint32_t v1 = static_cast<uint32_t>(value % kTen8);\n        \n        const uint32_t b0 = v0 / 10000;\n        const uint32_t c0 = v0 % 10000;\n        \n        const uint32_t d1 = (b0 / 100) << 1;\n        const uint32_t d2 = (b0 % 100) << 1;\n        \n        const uint32_t d3 = (c0 / 100) << 1;\n        const uint32_t d4 = (c0 % 100) << 1;\n        \n        const uint32_t b1 = v1 / 10000;\n        const uint32_t c1 = v1 % 10000;\n        \n        const uint32_t d5 = (b1 / 100) << 1;\n        const uint32_t d6 = (b1 % 100) << 1;\n        \n        const uint32_t d7 = (c1 / 100) << 1;\n        const uint32_t d8 = (c1 % 100) << 1;\n        \n        *buffer++ = cDigitsLut[d1];\n        *buffer++ = cDigitsLut[d1 + 1];\n        *buffer++ = cDigitsLut[d2];\n        *buffer++ = cDigitsLut[d2 + 1];\n        *buffer++ = cDigitsLut[d3];\n        *buffer++ = cDigitsLut[d3 + 1];\n        *buffer++ = cDigitsLut[d4];\n        *buffer++ = cDigitsLut[d4 + 1];\n        *buffer++ = cDigitsLut[d5];\n        *buffer++ = cDigitsLut[d5 + 1];\n        *buffer++ = cDigitsLut[d6];\n        *buffer++ = cDigitsLut[d6 + 1];\n        *buffer++ = cDigitsLut[d7];\n        *buffer++ = cDigitsLut[d7 + 1];\n        *buffer++ = cDigitsLut[d8];\n        *buffer++ = cDigitsLut[d8 + 1];\n    }\n    \n    return buffer;\n}\n\ninline char* i64toa(int64_t value, char* buffer) {\n    uint64_t u = static_cast<uint64_t>(value);\n    if (value < 0) {\n        *buffer++ = '-';\n        u = ~u + 1;\n    }\n\n    return u64toa(u, buffer);\n}\n\n} // namespace internal\nRAPIDJSON_NAMESPACE_END\n\n#endif // RAPIDJSON_ITOA_\n"
  },
  {
    "path": "rapidjson/internal/meta.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_INTERNAL_META_H_\n#define RAPIDJSON_INTERNAL_META_H_\n\n#include \"../rapidjson.h\"\n\n#ifdef __GNUC__\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(effc++)\n#endif\n#if defined(_MSC_VER)\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(6334)\n#endif\n\n#if RAPIDJSON_HAS_CXX11_TYPETRAITS\n#include <type_traits>\n#endif\n\n//@cond RAPIDJSON_INTERNAL\nRAPIDJSON_NAMESPACE_BEGIN\nnamespace internal {\n\n// Helper to wrap/convert arbitrary types to void, useful for arbitrary type matching\ntemplate <typename T> struct Void { typedef void Type; };\n\n///////////////////////////////////////////////////////////////////////////////\n// BoolType, TrueType, FalseType\n//\ntemplate <bool Cond> struct BoolType {\n    static const bool Value = Cond;\n    typedef BoolType Type;\n};\ntypedef BoolType<true> TrueType;\ntypedef BoolType<false> FalseType;\n\n\n///////////////////////////////////////////////////////////////////////////////\n// SelectIf, BoolExpr, NotExpr, AndExpr, OrExpr\n//\n\ntemplate <bool C> struct SelectIfImpl { template <typename T1, typename T2> struct Apply { typedef T1 Type; }; };\ntemplate <> struct SelectIfImpl<false> { template <typename T1, typename T2> struct Apply { typedef T2 Type; }; };\ntemplate <bool C, typename T1, typename T2> struct SelectIfCond : SelectIfImpl<C>::template Apply<T1,T2> {};\ntemplate <typename C, typename T1, typename T2> struct SelectIf : SelectIfCond<C::Value, T1, T2> {};\n\ntemplate <bool Cond1, bool Cond2> struct AndExprCond : FalseType {};\ntemplate <> struct AndExprCond<true, true> : TrueType {};\ntemplate <bool Cond1, bool Cond2> struct OrExprCond : TrueType {};\ntemplate <> struct OrExprCond<false, false> : FalseType {};\n\ntemplate <typename C> struct BoolExpr : SelectIf<C,TrueType,FalseType>::Type {};\ntemplate <typename C> struct NotExpr  : SelectIf<C,FalseType,TrueType>::Type {};\ntemplate <typename C1, typename C2> struct AndExpr : AndExprCond<C1::Value, C2::Value>::Type {};\ntemplate <typename C1, typename C2> struct OrExpr  : OrExprCond<C1::Value, C2::Value>::Type {};\n\n\n///////////////////////////////////////////////////////////////////////////////\n// AddConst, MaybeAddConst, RemoveConst\ntemplate <typename T> struct AddConst { typedef const T Type; };\ntemplate <bool Constify, typename T> struct MaybeAddConst : SelectIfCond<Constify, const T, T> {};\ntemplate <typename T> struct RemoveConst { typedef T Type; };\ntemplate <typename T> struct RemoveConst<const T> { typedef T Type; };\n\n\n///////////////////////////////////////////////////////////////////////////////\n// IsSame, IsConst, IsMoreConst, IsPointer\n//\ntemplate <typename T, typename U> struct IsSame : FalseType {};\ntemplate <typename T> struct IsSame<T, T> : TrueType {};\n\ntemplate <typename T> struct IsConst : FalseType {};\ntemplate <typename T> struct IsConst<const T> : TrueType {};\n\ntemplate <typename CT, typename T>\nstruct IsMoreConst\n    : AndExpr<IsSame<typename RemoveConst<CT>::Type, typename RemoveConst<T>::Type>,\n              BoolType<IsConst<CT>::Value >= IsConst<T>::Value> >::Type {};\n\ntemplate <typename T> struct IsPointer : FalseType {};\ntemplate <typename T> struct IsPointer<T*> : TrueType {};\n\n///////////////////////////////////////////////////////////////////////////////\n// IsBaseOf\n//\n#if RAPIDJSON_HAS_CXX11_TYPETRAITS\n\ntemplate <typename B, typename D> struct IsBaseOf\n    : BoolType< ::std::is_base_of<B,D>::value> {};\n\n#else // simplified version adopted from Boost\n\ntemplate<typename B, typename D> struct IsBaseOfImpl {\n    RAPIDJSON_STATIC_ASSERT(sizeof(B) != 0);\n    RAPIDJSON_STATIC_ASSERT(sizeof(D) != 0);\n\n    typedef char (&Yes)[1];\n    typedef char (&No) [2];\n\n    template <typename T>\n    static Yes Check(const D*, T);\n    static No  Check(const B*, int);\n\n    struct Host {\n        operator const B*() const;\n        operator const D*();\n    };\n\n    enum { Value = (sizeof(Check(Host(), 0)) == sizeof(Yes)) };\n};\n\ntemplate <typename B, typename D> struct IsBaseOf\n    : OrExpr<IsSame<B, D>, BoolExpr<IsBaseOfImpl<B, D> > >::Type {};\n\n#endif // RAPIDJSON_HAS_CXX11_TYPETRAITS\n\n\n//////////////////////////////////////////////////////////////////////////\n// EnableIf / DisableIf\n//\ntemplate <bool Condition, typename T = void> struct EnableIfCond  { typedef T Type; };\ntemplate <typename T> struct EnableIfCond<false, T> { /* empty */ };\n\ntemplate <bool Condition, typename T = void> struct DisableIfCond { typedef T Type; };\ntemplate <typename T> struct DisableIfCond<true, T> { /* empty */ };\n\ntemplate <typename Condition, typename T = void>\nstruct EnableIf : EnableIfCond<Condition::Value, T> {};\n\ntemplate <typename Condition, typename T = void>\nstruct DisableIf : DisableIfCond<Condition::Value, T> {};\n\n// SFINAE helpers\nstruct SfinaeTag {};\ntemplate <typename T> struct RemoveSfinaeTag;\ntemplate <typename T> struct RemoveSfinaeTag<SfinaeTag&(*)(T)> { typedef T Type; };\n\n#define RAPIDJSON_REMOVEFPTR_(type) \\\n    typename ::RAPIDJSON_NAMESPACE::internal::RemoveSfinaeTag \\\n        < ::RAPIDJSON_NAMESPACE::internal::SfinaeTag&(*) type>::Type\n\n#define RAPIDJSON_ENABLEIF(cond) \\\n    typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \\\n        <RAPIDJSON_REMOVEFPTR_(cond)>::Type * = NULL\n\n#define RAPIDJSON_DISABLEIF(cond) \\\n    typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \\\n        <RAPIDJSON_REMOVEFPTR_(cond)>::Type * = NULL\n\n#define RAPIDJSON_ENABLEIF_RETURN(cond,returntype) \\\n    typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \\\n        <RAPIDJSON_REMOVEFPTR_(cond), \\\n         RAPIDJSON_REMOVEFPTR_(returntype)>::Type\n\n#define RAPIDJSON_DISABLEIF_RETURN(cond,returntype) \\\n    typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \\\n        <RAPIDJSON_REMOVEFPTR_(cond), \\\n         RAPIDJSON_REMOVEFPTR_(returntype)>::Type\n\n} // namespace internal\nRAPIDJSON_NAMESPACE_END\n//@endcond\n\n#if defined(__GNUC__) || defined(_MSC_VER)\nRAPIDJSON_DIAG_POP\n#endif\n\n#endif // RAPIDJSON_INTERNAL_META_H_\n"
  },
  {
    "path": "rapidjson/internal/pow10.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_POW10_\n#define RAPIDJSON_POW10_\n\n#include \"../rapidjson.h\"\n\nRAPIDJSON_NAMESPACE_BEGIN\nnamespace internal {\n\n//! Computes integer powers of 10 in double (10.0^n).\n/*! This function uses lookup table for fast and accurate results.\n    \\param n non-negative exponent. Must <= 308.\n    \\return 10.0^n\n*/\ninline double Pow10(int n) {\n    static const double e[] = { // 1e-0...1e308: 309 * 8 bytes = 2472 bytes\n        1e+0,  \n        1e+1,  1e+2,  1e+3,  1e+4,  1e+5,  1e+6,  1e+7,  1e+8,  1e+9,  1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20, \n        1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40,\n        1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60,\n        1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80,\n        1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100,\n        1e+101,1e+102,1e+103,1e+104,1e+105,1e+106,1e+107,1e+108,1e+109,1e+110,1e+111,1e+112,1e+113,1e+114,1e+115,1e+116,1e+117,1e+118,1e+119,1e+120,\n        1e+121,1e+122,1e+123,1e+124,1e+125,1e+126,1e+127,1e+128,1e+129,1e+130,1e+131,1e+132,1e+133,1e+134,1e+135,1e+136,1e+137,1e+138,1e+139,1e+140,\n        1e+141,1e+142,1e+143,1e+144,1e+145,1e+146,1e+147,1e+148,1e+149,1e+150,1e+151,1e+152,1e+153,1e+154,1e+155,1e+156,1e+157,1e+158,1e+159,1e+160,\n        1e+161,1e+162,1e+163,1e+164,1e+165,1e+166,1e+167,1e+168,1e+169,1e+170,1e+171,1e+172,1e+173,1e+174,1e+175,1e+176,1e+177,1e+178,1e+179,1e+180,\n        1e+181,1e+182,1e+183,1e+184,1e+185,1e+186,1e+187,1e+188,1e+189,1e+190,1e+191,1e+192,1e+193,1e+194,1e+195,1e+196,1e+197,1e+198,1e+199,1e+200,\n        1e+201,1e+202,1e+203,1e+204,1e+205,1e+206,1e+207,1e+208,1e+209,1e+210,1e+211,1e+212,1e+213,1e+214,1e+215,1e+216,1e+217,1e+218,1e+219,1e+220,\n        1e+221,1e+222,1e+223,1e+224,1e+225,1e+226,1e+227,1e+228,1e+229,1e+230,1e+231,1e+232,1e+233,1e+234,1e+235,1e+236,1e+237,1e+238,1e+239,1e+240,\n        1e+241,1e+242,1e+243,1e+244,1e+245,1e+246,1e+247,1e+248,1e+249,1e+250,1e+251,1e+252,1e+253,1e+254,1e+255,1e+256,1e+257,1e+258,1e+259,1e+260,\n        1e+261,1e+262,1e+263,1e+264,1e+265,1e+266,1e+267,1e+268,1e+269,1e+270,1e+271,1e+272,1e+273,1e+274,1e+275,1e+276,1e+277,1e+278,1e+279,1e+280,\n        1e+281,1e+282,1e+283,1e+284,1e+285,1e+286,1e+287,1e+288,1e+289,1e+290,1e+291,1e+292,1e+293,1e+294,1e+295,1e+296,1e+297,1e+298,1e+299,1e+300,\n        1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308\n    };\n    RAPIDJSON_ASSERT(n >= 0 && n <= 308);\n    return e[n];\n}\n\n} // namespace internal\nRAPIDJSON_NAMESPACE_END\n\n#endif // RAPIDJSON_POW10_\n"
  },
  {
    "path": "rapidjson/internal/regex.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_INTERNAL_REGEX_H_\n#define RAPIDJSON_INTERNAL_REGEX_H_\n\n#include \"../allocators.h\"\n#include \"../stream.h\"\n#include \"stack.h\"\n\n#ifdef __clang__\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(padded)\nRAPIDJSON_DIAG_OFF(switch-enum)\nRAPIDJSON_DIAG_OFF(implicit-fallthrough)\n#endif\n\n#ifdef __GNUC__\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(effc++)\n#endif\n\n#ifdef _MSC_VER\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated\n#endif\n\n#ifndef RAPIDJSON_REGEX_VERBOSE\n#define RAPIDJSON_REGEX_VERBOSE 0\n#endif\n\nRAPIDJSON_NAMESPACE_BEGIN\nnamespace internal {\n\n///////////////////////////////////////////////////////////////////////////////\n// DecodedStream\n\ntemplate <typename SourceStream, typename Encoding>\nclass DecodedStream {\npublic:\n    DecodedStream(SourceStream& ss) : ss_(ss), codepoint_() { Decode(); }\n    unsigned Peek() { return codepoint_; }\n    unsigned Take() {\n        unsigned c = codepoint_;\n        if (c) // No further decoding when '\\0'\n            Decode();\n        return c;\n    }\n\nprivate:\n    void Decode() {\n        if (!Encoding::Decode(ss_, &codepoint_))\n            codepoint_ = 0;\n    }\n\n    SourceStream& ss_;\n    unsigned codepoint_;\n};\n\n///////////////////////////////////////////////////////////////////////////////\n// GenericRegex\n\nstatic const SizeType kRegexInvalidState = ~SizeType(0);  //!< Represents an invalid index in GenericRegex::State::out, out1\nstatic const SizeType kRegexInvalidRange = ~SizeType(0);\n\ntemplate <typename Encoding, typename Allocator>\nclass GenericRegexSearch;\n\n//! Regular expression engine with subset of ECMAscript grammar.\n/*!\n    Supported regular expression syntax:\n    - \\c ab     Concatenation\n    - \\c a|b    Alternation\n    - \\c a?     Zero or one\n    - \\c a*     Zero or more\n    - \\c a+     One or more\n    - \\c a{3}   Exactly 3 times\n    - \\c a{3,}  At least 3 times\n    - \\c a{3,5} 3 to 5 times\n    - \\c (ab)   Grouping\n    - \\c ^a     At the beginning\n    - \\c a$     At the end\n    - \\c .      Any character\n    - \\c [abc]  Character classes\n    - \\c [a-c]  Character class range\n    - \\c [a-z0-9_] Character class combination\n    - \\c [^abc] Negated character classes\n    - \\c [^a-c] Negated character class range\n    - \\c [\\b]   Backspace (U+0008)\n    - \\c \\\\| \\\\\\\\ ...  Escape characters\n    - \\c \\\\f Form feed (U+000C)\n    - \\c \\\\n Line feed (U+000A)\n    - \\c \\\\r Carriage return (U+000D)\n    - \\c \\\\t Tab (U+0009)\n    - \\c \\\\v Vertical tab (U+000B)\n\n    \\note This is a Thompson NFA engine, implemented with reference to \n        Cox, Russ. \"Regular Expression Matching Can Be Simple And Fast (but is slow in Java, Perl, PHP, Python, Ruby,...).\", \n        https://swtch.com/~rsc/regexp/regexp1.html \n*/\ntemplate <typename Encoding, typename Allocator = CrtAllocator>\nclass GenericRegex {\npublic:\n    typedef Encoding EncodingType;\n    typedef typename Encoding::Ch Ch;\n    template <typename, typename> friend class GenericRegexSearch;\n\n    GenericRegex(const Ch* source, Allocator* allocator = 0) : \n        states_(allocator, 256), ranges_(allocator, 256), root_(kRegexInvalidState), stateCount_(), rangeCount_(), \n        anchorBegin_(), anchorEnd_()\n    {\n        GenericStringStream<Encoding> ss(source);\n        DecodedStream<GenericStringStream<Encoding>, Encoding> ds(ss);\n        Parse(ds);\n    }\n\n    ~GenericRegex() {}\n\n    bool IsValid() const {\n        return root_ != kRegexInvalidState;\n    }\n\nprivate:\n    enum Operator {\n        kZeroOrOne,\n        kZeroOrMore,\n        kOneOrMore,\n        kConcatenation,\n        kAlternation,\n        kLeftParenthesis\n    };\n\n    static const unsigned kAnyCharacterClass = 0xFFFFFFFF;   //!< For '.'\n    static const unsigned kRangeCharacterClass = 0xFFFFFFFE;\n    static const unsigned kRangeNegationFlag = 0x80000000;\n\n    struct Range {\n        unsigned start; // \n        unsigned end;\n        SizeType next;\n    };\n\n    struct State {\n        SizeType out;     //!< Equals to kInvalid for matching state\n        SizeType out1;    //!< Equals to non-kInvalid for split\n        SizeType rangeStart;\n        unsigned codepoint;\n    };\n\n    struct Frag {\n        Frag(SizeType s, SizeType o, SizeType m) : start(s), out(o), minIndex(m) {}\n        SizeType start;\n        SizeType out; //!< link-list of all output states\n        SizeType minIndex;\n    };\n\n    State& GetState(SizeType index) {\n        RAPIDJSON_ASSERT(index < stateCount_);\n        return states_.template Bottom<State>()[index];\n    }\n\n    const State& GetState(SizeType index) const {\n        RAPIDJSON_ASSERT(index < stateCount_);\n        return states_.template Bottom<State>()[index];\n    }\n\n    Range& GetRange(SizeType index) {\n        RAPIDJSON_ASSERT(index < rangeCount_);\n        return ranges_.template Bottom<Range>()[index];\n    }\n\n    const Range& GetRange(SizeType index) const {\n        RAPIDJSON_ASSERT(index < rangeCount_);\n        return ranges_.template Bottom<Range>()[index];\n    }\n\n    template <typename InputStream>\n    void Parse(DecodedStream<InputStream, Encoding>& ds) {\n        Allocator allocator;\n        Stack<Allocator> operandStack(&allocator, 256);     // Frag\n        Stack<Allocator> operatorStack(&allocator, 256);    // Operator\n        Stack<Allocator> atomCountStack(&allocator, 256);   // unsigned (Atom per parenthesis)\n\n        *atomCountStack.template Push<unsigned>() = 0;\n\n        unsigned codepoint;\n        while (ds.Peek() != 0) {\n            switch (codepoint = ds.Take()) {\n                case '^':\n                    anchorBegin_ = true;\n                    break;\n\n                case '$':\n                    anchorEnd_ = true;\n                    break;\n\n                case '|':\n                    while (!operatorStack.Empty() && *operatorStack.template Top<Operator>() < kAlternation)\n                        if (!Eval(operandStack, *operatorStack.template Pop<Operator>(1)))\n                            return;\n                    *operatorStack.template Push<Operator>() = kAlternation;\n                    *atomCountStack.template Top<unsigned>() = 0;\n                    break;\n\n                case '(':\n                    *operatorStack.template Push<Operator>() = kLeftParenthesis;\n                    *atomCountStack.template Push<unsigned>() = 0;\n                    break;\n\n                case ')':\n                    while (!operatorStack.Empty() && *operatorStack.template Top<Operator>() != kLeftParenthesis)\n                        if (!Eval(operandStack, *operatorStack.template Pop<Operator>(1)))\n                            return;\n                    if (operatorStack.Empty())\n                        return;\n                    operatorStack.template Pop<Operator>(1);\n                    atomCountStack.template Pop<unsigned>(1);\n                    ImplicitConcatenation(atomCountStack, operatorStack);\n                    break;\n\n                case '?':\n                    if (!Eval(operandStack, kZeroOrOne))\n                        return;\n                    break;\n\n                case '*':\n                    if (!Eval(operandStack, kZeroOrMore))\n                        return;\n                    break;\n\n                case '+':\n                    if (!Eval(operandStack, kOneOrMore))\n                        return;\n                    break;\n\n                case '{':\n                    {\n                        unsigned n, m;\n                        if (!ParseUnsigned(ds, &n))\n                            return;\n\n                        if (ds.Peek() == ',') {\n                            ds.Take();\n                            if (ds.Peek() == '}')\n                                m = kInfinityQuantifier;\n                            else if (!ParseUnsigned(ds, &m) || m < n)\n                                return;\n                        }\n                        else\n                            m = n;\n\n                        if (!EvalQuantifier(operandStack, n, m) || ds.Peek() != '}')\n                            return;\n                        ds.Take();\n                    }\n                    break;\n\n                case '.':\n                    PushOperand(operandStack, kAnyCharacterClass);\n                    ImplicitConcatenation(atomCountStack, operatorStack);\n                    break;\n\n                case '[':\n                    {\n                        SizeType range;\n                        if (!ParseRange(ds, &range))\n                            return;\n                        SizeType s = NewState(kRegexInvalidState, kRegexInvalidState, kRangeCharacterClass);\n                        GetState(s).rangeStart = range;\n                        *operandStack.template Push<Frag>() = Frag(s, s, s);\n                    }\n                    ImplicitConcatenation(atomCountStack, operatorStack);\n                    break;\n\n                case '\\\\': // Escape character\n                    if (!CharacterEscape(ds, &codepoint))\n                        return; // Unsupported escape character\n                    // fall through to default\n\n                default: // Pattern character\n                    PushOperand(operandStack, codepoint);\n                    ImplicitConcatenation(atomCountStack, operatorStack);\n            }\n        }\n\n        while (!operatorStack.Empty())\n            if (!Eval(operandStack, *operatorStack.template Pop<Operator>(1)))\n                return;\n\n        // Link the operand to matching state.\n        if (operandStack.GetSize() == sizeof(Frag)) {\n            Frag* e = operandStack.template Pop<Frag>(1);\n            Patch(e->out, NewState(kRegexInvalidState, kRegexInvalidState, 0));\n            root_ = e->start;\n\n#if RAPIDJSON_REGEX_VERBOSE\n            printf(\"root: %d\\n\", root_);\n            for (SizeType i = 0; i < stateCount_ ; i++) {\n                State& s = GetState(i);\n                printf(\"[%2d] out: %2d out1: %2d c: '%c'\\n\", i, s.out, s.out1, (char)s.codepoint);\n            }\n            printf(\"\\n\");\n#endif\n        }\n    }\n\n    SizeType NewState(SizeType out, SizeType out1, unsigned codepoint) {\n        State* s = states_.template Push<State>();\n        s->out = out;\n        s->out1 = out1;\n        s->codepoint = codepoint;\n        s->rangeStart = kRegexInvalidRange;\n        return stateCount_++;\n    }\n\n    void PushOperand(Stack<Allocator>& operandStack, unsigned codepoint) {\n        SizeType s = NewState(kRegexInvalidState, kRegexInvalidState, codepoint);\n        *operandStack.template Push<Frag>() = Frag(s, s, s);\n    }\n\n    void ImplicitConcatenation(Stack<Allocator>& atomCountStack, Stack<Allocator>& operatorStack) {\n        if (*atomCountStack.template Top<unsigned>())\n            *operatorStack.template Push<Operator>() = kConcatenation;\n        (*atomCountStack.template Top<unsigned>())++;\n    }\n\n    SizeType Append(SizeType l1, SizeType l2) {\n        SizeType old = l1;\n        while (GetState(l1).out != kRegexInvalidState)\n            l1 = GetState(l1).out;\n        GetState(l1).out = l2;\n        return old;\n    }\n\n    void Patch(SizeType l, SizeType s) {\n        for (SizeType next; l != kRegexInvalidState; l = next) {\n            next = GetState(l).out;\n            GetState(l).out = s;\n        }\n    }\n\n    bool Eval(Stack<Allocator>& operandStack, Operator op) {\n        switch (op) {\n            case kConcatenation:\n                RAPIDJSON_ASSERT(operandStack.GetSize() >= sizeof(Frag) * 2);\n                {\n                    Frag e2 = *operandStack.template Pop<Frag>(1);\n                    Frag e1 = *operandStack.template Pop<Frag>(1);\n                    Patch(e1.out, e2.start);\n                    *operandStack.template Push<Frag>() = Frag(e1.start, e2.out, Min(e1.minIndex, e2.minIndex));\n                }\n                return true;\n\n            case kAlternation:\n                if (operandStack.GetSize() >= sizeof(Frag) * 2) {\n                    Frag e2 = *operandStack.template Pop<Frag>(1);\n                    Frag e1 = *operandStack.template Pop<Frag>(1);\n                    SizeType s = NewState(e1.start, e2.start, 0);\n                    *operandStack.template Push<Frag>() = Frag(s, Append(e1.out, e2.out), Min(e1.minIndex, e2.minIndex));\n                    return true;\n                }\n                return false;\n\n            case kZeroOrOne:\n                if (operandStack.GetSize() >= sizeof(Frag)) {\n                    Frag e = *operandStack.template Pop<Frag>(1);\n                    SizeType s = NewState(kRegexInvalidState, e.start, 0);\n                    *operandStack.template Push<Frag>() = Frag(s, Append(e.out, s), e.minIndex);\n                    return true;\n                }\n                return false;\n\n            case kZeroOrMore:\n                if (operandStack.GetSize() >= sizeof(Frag)) {\n                    Frag e = *operandStack.template Pop<Frag>(1);\n                    SizeType s = NewState(kRegexInvalidState, e.start, 0);\n                    Patch(e.out, s);\n                    *operandStack.template Push<Frag>() = Frag(s, s, e.minIndex);\n                    return true;\n                }\n                return false;\n\n            default: \n                RAPIDJSON_ASSERT(op == kOneOrMore);\n                if (operandStack.GetSize() >= sizeof(Frag)) {\n                    Frag e = *operandStack.template Pop<Frag>(1);\n                    SizeType s = NewState(kRegexInvalidState, e.start, 0);\n                    Patch(e.out, s);\n                    *operandStack.template Push<Frag>() = Frag(e.start, s, e.minIndex);\n                    return true;\n                }\n                return false;\n        }\n    }\n\n    bool EvalQuantifier(Stack<Allocator>& operandStack, unsigned n, unsigned m) {\n        RAPIDJSON_ASSERT(n <= m);\n        RAPIDJSON_ASSERT(operandStack.GetSize() >= sizeof(Frag));\n\n        if (n == 0) {\n            if (m == 0)                             // a{0} not support\n                return false;\n            else if (m == kInfinityQuantifier)\n                Eval(operandStack, kZeroOrMore);    // a{0,} -> a*\n            else {\n                Eval(operandStack, kZeroOrOne);         // a{0,5} -> a?\n                for (unsigned i = 0; i < m - 1; i++)\n                    CloneTopOperand(operandStack);      // a{0,5} -> a? a? a? a? a?\n                for (unsigned i = 0; i < m - 1; i++)\n                    Eval(operandStack, kConcatenation); // a{0,5} -> a?a?a?a?a?\n            }\n            return true;\n        }\n\n        for (unsigned i = 0; i < n - 1; i++)        // a{3} -> a a a\n            CloneTopOperand(operandStack);\n\n        if (m == kInfinityQuantifier)\n            Eval(operandStack, kOneOrMore);         // a{3,} -> a a a+\n        else if (m > n) {\n            CloneTopOperand(operandStack);          // a{3,5} -> a a a a\n            Eval(operandStack, kZeroOrOne);         // a{3,5} -> a a a a?\n            for (unsigned i = n; i < m - 1; i++)\n                CloneTopOperand(operandStack);      // a{3,5} -> a a a a? a?\n            for (unsigned i = n; i < m; i++)\n                Eval(operandStack, kConcatenation); // a{3,5} -> a a aa?a?\n        }\n\n        for (unsigned i = 0; i < n - 1; i++)\n            Eval(operandStack, kConcatenation);     // a{3} -> aaa, a{3,} -> aaa+, a{3.5} -> aaaa?a?\n\n        return true;\n    }\n\n    static SizeType Min(SizeType a, SizeType b) { return a < b ? a : b; }\n\n    void CloneTopOperand(Stack<Allocator>& operandStack) {\n        const Frag src = *operandStack.template Top<Frag>(); // Copy constructor to prevent invalidation\n        SizeType count = stateCount_ - src.minIndex; // Assumes top operand contains states in [src->minIndex, stateCount_)\n        State* s = states_.template Push<State>(count);\n        memcpy(s, &GetState(src.minIndex), count * sizeof(State));\n        for (SizeType j = 0; j < count; j++) {\n            if (s[j].out != kRegexInvalidState)\n                s[j].out += count;\n            if (s[j].out1 != kRegexInvalidState)\n                s[j].out1 += count;\n        }\n        *operandStack.template Push<Frag>() = Frag(src.start + count, src.out + count, src.minIndex + count);\n        stateCount_ += count;\n    }\n\n    template <typename InputStream>\n    bool ParseUnsigned(DecodedStream<InputStream, Encoding>& ds, unsigned* u) {\n        unsigned r = 0;\n        if (ds.Peek() < '0' || ds.Peek() > '9')\n            return false;\n        while (ds.Peek() >= '0' && ds.Peek() <= '9') {\n            if (r >= 429496729 && ds.Peek() > '5') // 2^32 - 1 = 4294967295\n                return false; // overflow\n            r = r * 10 + (ds.Take() - '0');\n        }\n        *u = r;\n        return true;\n    }\n\n    template <typename InputStream>\n    bool ParseRange(DecodedStream<InputStream, Encoding>& ds, SizeType* range) {\n        bool isBegin = true;\n        bool negate = false;\n        int step = 0;\n        SizeType start = kRegexInvalidRange;\n        SizeType current = kRegexInvalidRange;\n        unsigned codepoint;\n        while ((codepoint = ds.Take()) != 0) {\n            if (isBegin) {\n                isBegin = false;\n                if (codepoint == '^') {\n                    negate = true;\n                    continue;\n                }\n            }\n\n            switch (codepoint) {\n            case ']':\n                if (start == kRegexInvalidRange)\n                    return false;   // Error: nothing inside []\n                if (step == 2) { // Add trailing '-'\n                    SizeType r = NewRange('-');\n                    RAPIDJSON_ASSERT(current != kRegexInvalidRange);\n                    GetRange(current).next = r;\n                }\n                if (negate)\n                    GetRange(start).start |= kRangeNegationFlag;\n                *range = start;\n                return true;\n\n            case '\\\\':\n                if (ds.Peek() == 'b') {\n                    ds.Take();\n                    codepoint = 0x0008; // Escape backspace character\n                }\n                else if (!CharacterEscape(ds, &codepoint))\n                    return false;\n                // fall through to default\n\n            default:\n                switch (step) {\n                case 1:\n                    if (codepoint == '-') {\n                        step++;\n                        break;\n                    }\n                    // fall through to step 0 for other characters\n\n                case 0:\n                    {\n                        SizeType r = NewRange(codepoint);\n                        if (current != kRegexInvalidRange)\n                            GetRange(current).next = r;\n                        if (start == kRegexInvalidRange)\n                            start = r;\n                        current = r;\n                    }\n                    step = 1;\n                    break;\n\n                default:\n                    RAPIDJSON_ASSERT(step == 2);\n                    GetRange(current).end = codepoint;\n                    step = 0;\n                }\n            }\n        }\n        return false;\n    }\n    \n    SizeType NewRange(unsigned codepoint) {\n        Range* r = ranges_.template Push<Range>();\n        r->start = r->end = codepoint;\n        r->next = kRegexInvalidRange;\n        return rangeCount_++;\n    }\n\n    template <typename InputStream>\n    bool CharacterEscape(DecodedStream<InputStream, Encoding>& ds, unsigned* escapedCodepoint) {\n        unsigned codepoint;\n        switch (codepoint = ds.Take()) {\n            case '^':\n            case '$':\n            case '|':\n            case '(':\n            case ')':\n            case '?':\n            case '*':\n            case '+':\n            case '.':\n            case '[':\n            case ']':\n            case '{':\n            case '}':\n            case '\\\\':\n                *escapedCodepoint = codepoint; return true;\n            case 'f': *escapedCodepoint = 0x000C; return true;\n            case 'n': *escapedCodepoint = 0x000A; return true;\n            case 'r': *escapedCodepoint = 0x000D; return true;\n            case 't': *escapedCodepoint = 0x0009; return true;\n            case 'v': *escapedCodepoint = 0x000B; return true;\n            default:\n                return false; // Unsupported escape character\n        }\n    }\n\n    Stack<Allocator> states_;\n    Stack<Allocator> ranges_;\n    SizeType root_;\n    SizeType stateCount_;\n    SizeType rangeCount_;\n\n    static const unsigned kInfinityQuantifier = ~0u;\n\n    // For SearchWithAnchoring()\n    bool anchorBegin_;\n    bool anchorEnd_;\n};\n\ntemplate <typename RegexType, typename Allocator = CrtAllocator>\nclass GenericRegexSearch {\npublic:\n    typedef typename RegexType::EncodingType Encoding;\n    typedef typename Encoding::Ch Ch;\n\n    GenericRegexSearch(const RegexType& regex, Allocator* allocator = 0) : \n        regex_(regex), allocator_(allocator), ownAllocator_(0),\n        state0_(allocator, 0), state1_(allocator, 0), stateSet_()\n    {\n        RAPIDJSON_ASSERT(regex_.IsValid());\n        if (!allocator_)\n            ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator());\n        stateSet_ = static_cast<unsigned*>(allocator_->Malloc(GetStateSetSize()));\n        state0_.template Reserve<SizeType>(regex_.stateCount_);\n        state1_.template Reserve<SizeType>(regex_.stateCount_);\n    }\n\n    ~GenericRegexSearch() {\n        Allocator::Free(stateSet_);\n        RAPIDJSON_DELETE(ownAllocator_);\n    }\n\n    template <typename InputStream>\n    bool Match(InputStream& is) {\n        return SearchWithAnchoring(is, true, true);\n    }\n\n    bool Match(const Ch* s) {\n        GenericStringStream<Encoding> is(s);\n        return Match(is);\n    }\n\n    template <typename InputStream>\n    bool Search(InputStream& is) {\n        return SearchWithAnchoring(is, regex_.anchorBegin_, regex_.anchorEnd_);\n    }\n\n    bool Search(const Ch* s) {\n        GenericStringStream<Encoding> is(s);\n        return Search(is);\n    }\n\nprivate:\n    typedef typename RegexType::State State;\n    typedef typename RegexType::Range Range;\n\n    template <typename InputStream>\n    bool SearchWithAnchoring(InputStream& is, bool anchorBegin, bool anchorEnd) {\n        DecodedStream<InputStream, Encoding> ds(is);\n\n        state0_.Clear();\n        Stack<Allocator> *current = &state0_, *next = &state1_;\n        const size_t stateSetSize = GetStateSetSize();\n        std::memset(stateSet_, 0, stateSetSize);\n\n        bool matched = AddState(*current, regex_.root_);\n        unsigned codepoint;\n        while (!current->Empty() && (codepoint = ds.Take()) != 0) {\n            std::memset(stateSet_, 0, stateSetSize);\n            next->Clear();\n            matched = false;\n            for (const SizeType* s = current->template Bottom<SizeType>(); s != current->template End<SizeType>(); ++s) {\n                const State& sr = regex_.GetState(*s);\n                if (sr.codepoint == codepoint ||\n                    sr.codepoint == RegexType::kAnyCharacterClass || \n                    (sr.codepoint == RegexType::kRangeCharacterClass && MatchRange(sr.rangeStart, codepoint)))\n                {\n                    matched = AddState(*next, sr.out) || matched;\n                    if (!anchorEnd && matched)\n                        return true;\n                }\n                if (!anchorBegin)\n                    AddState(*next, regex_.root_);\n            }\n            internal::Swap(current, next);\n        }\n\n        return matched;\n    }\n\n    size_t GetStateSetSize() const {\n        return (regex_.stateCount_ + 31) / 32 * 4;\n    }\n\n    // Return whether the added states is a match state\n    bool AddState(Stack<Allocator>& l, SizeType index) {\n        RAPIDJSON_ASSERT(index != kRegexInvalidState);\n\n        const State& s = regex_.GetState(index);\n        if (s.out1 != kRegexInvalidState) { // Split\n            bool matched = AddState(l, s.out);\n            return AddState(l, s.out1) || matched;\n        }\n        else if (!(stateSet_[index >> 5] & (1 << (index & 31)))) {\n            stateSet_[index >> 5] |= (1 << (index & 31));\n            *l.template PushUnsafe<SizeType>() = index;\n        }\n        return s.out == kRegexInvalidState; // by using PushUnsafe() above, we can ensure s is not validated due to reallocation.\n    }\n\n    bool MatchRange(SizeType rangeIndex, unsigned codepoint) const {\n        bool yes = (regex_.GetRange(rangeIndex).start & RegexType::kRangeNegationFlag) == 0;\n        while (rangeIndex != kRegexInvalidRange) {\n            const Range& r = regex_.GetRange(rangeIndex);\n            if (codepoint >= (r.start & ~RegexType::kRangeNegationFlag) && codepoint <= r.end)\n                return yes;\n            rangeIndex = r.next;\n        }\n        return !yes;\n    }\n\n    const RegexType& regex_;\n    Allocator* allocator_;\n    Allocator* ownAllocator_;\n    Stack<Allocator> state0_;\n    Stack<Allocator> state1_;\n    uint32_t* stateSet_;\n};\n\ntypedef GenericRegex<UTF8<> > Regex;\ntypedef GenericRegexSearch<Regex> RegexSearch;\n\n} // namespace internal\nRAPIDJSON_NAMESPACE_END\n\n#ifdef __clang__\nRAPIDJSON_DIAG_POP\n#endif\n\n#ifdef _MSC_VER\nRAPIDJSON_DIAG_POP\n#endif\n\n#endif // RAPIDJSON_INTERNAL_REGEX_H_\n"
  },
  {
    "path": "rapidjson/internal/stack.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_INTERNAL_STACK_H_\n#define RAPIDJSON_INTERNAL_STACK_H_\n\n#include \"../allocators.h\"\n#include \"swap.h\"\n\n#if defined(__clang__)\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(c++98-compat)\n#endif\n\nRAPIDJSON_NAMESPACE_BEGIN\nnamespace internal {\n\n///////////////////////////////////////////////////////////////////////////////\n// Stack\n\n//! A type-unsafe stack for storing different types of data.\n/*! \\tparam Allocator Allocator for allocating stack memory.\n*/\ntemplate <typename Allocator>\nclass Stack {\npublic:\n    // Optimization note: Do not allocate memory for stack_ in constructor.\n    // Do it lazily when first Push() -> Expand() -> Resize().\n    Stack(Allocator* allocator, size_t stackCapacity) : allocator_(allocator), ownAllocator_(0), stack_(0), stackTop_(0), stackEnd_(0), initialCapacity_(stackCapacity) {\n    }\n\n#if RAPIDJSON_HAS_CXX11_RVALUE_REFS\n    Stack(Stack&& rhs)\n        : allocator_(rhs.allocator_),\n          ownAllocator_(rhs.ownAllocator_),\n          stack_(rhs.stack_),\n          stackTop_(rhs.stackTop_),\n          stackEnd_(rhs.stackEnd_),\n          initialCapacity_(rhs.initialCapacity_)\n    {\n        rhs.allocator_ = 0;\n        rhs.ownAllocator_ = 0;\n        rhs.stack_ = 0;\n        rhs.stackTop_ = 0;\n        rhs.stackEnd_ = 0;\n        rhs.initialCapacity_ = 0;\n    }\n#endif\n\n    ~Stack() {\n        Destroy();\n    }\n\n#if RAPIDJSON_HAS_CXX11_RVALUE_REFS\n    Stack& operator=(Stack&& rhs) {\n        if (&rhs != this)\n        {\n            Destroy();\n\n            allocator_ = rhs.allocator_;\n            ownAllocator_ = rhs.ownAllocator_;\n            stack_ = rhs.stack_;\n            stackTop_ = rhs.stackTop_;\n            stackEnd_ = rhs.stackEnd_;\n            initialCapacity_ = rhs.initialCapacity_;\n\n            rhs.allocator_ = 0;\n            rhs.ownAllocator_ = 0;\n            rhs.stack_ = 0;\n            rhs.stackTop_ = 0;\n            rhs.stackEnd_ = 0;\n            rhs.initialCapacity_ = 0;\n        }\n        return *this;\n    }\n#endif\n\n    void Swap(Stack& rhs) RAPIDJSON_NOEXCEPT {\n        internal::Swap(allocator_, rhs.allocator_);\n        internal::Swap(ownAllocator_, rhs.ownAllocator_);\n        internal::Swap(stack_, rhs.stack_);\n        internal::Swap(stackTop_, rhs.stackTop_);\n        internal::Swap(stackEnd_, rhs.stackEnd_);\n        internal::Swap(initialCapacity_, rhs.initialCapacity_);\n    }\n\n    void Clear() { stackTop_ = stack_; }\n\n    void ShrinkToFit() { \n        if (Empty()) {\n            // If the stack is empty, completely deallocate the memory.\n            Allocator::Free(stack_);\n            stack_ = 0;\n            stackTop_ = 0;\n            stackEnd_ = 0;\n        }\n        else\n            Resize(GetSize());\n    }\n\n    // Optimization note: try to minimize the size of this function for force inline.\n    // Expansion is run very infrequently, so it is moved to another (probably non-inline) function.\n    template<typename T>\n    RAPIDJSON_FORCEINLINE void Reserve(size_t count = 1) {\n         // Expand the stack if needed\n        if (RAPIDJSON_UNLIKELY(stackTop_ + sizeof(T) * count > stackEnd_))\n            Expand<T>(count);\n    }\n\n    template<typename T>\n    RAPIDJSON_FORCEINLINE T* Push(size_t count = 1) {\n        Reserve<T>(count);\n        return PushUnsafe<T>(count);\n    }\n\n    template<typename T>\n    RAPIDJSON_FORCEINLINE T* PushUnsafe(size_t count = 1) {\n        RAPIDJSON_ASSERT(stackTop_ + sizeof(T) * count <= stackEnd_);\n        T* ret = reinterpret_cast<T*>(stackTop_);\n        stackTop_ += sizeof(T) * count;\n        return ret;\n    }\n\n    template<typename T>\n    T* Pop(size_t count) {\n        RAPIDJSON_ASSERT(GetSize() >= count * sizeof(T));\n        stackTop_ -= count * sizeof(T);\n        return reinterpret_cast<T*>(stackTop_);\n    }\n\n    template<typename T>\n    T* Top() { \n        RAPIDJSON_ASSERT(GetSize() >= sizeof(T));\n        return reinterpret_cast<T*>(stackTop_ - sizeof(T));\n    }\n\n    template<typename T>\n    const T* Top() const {\n        RAPIDJSON_ASSERT(GetSize() >= sizeof(T));\n        return reinterpret_cast<T*>(stackTop_ - sizeof(T));\n    }\n\n    template<typename T>\n    T* End() { return reinterpret_cast<T*>(stackTop_); }\n\n    template<typename T>\n    const T* End() const { return reinterpret_cast<T*>(stackTop_); }\n\n    template<typename T>\n    T* Bottom() { return reinterpret_cast<T*>(stack_); }\n\n    template<typename T>\n    const T* Bottom() const { return reinterpret_cast<T*>(stack_); }\n\n    bool HasAllocator() const {\n        return allocator_ != 0;\n    }\n\n    Allocator& GetAllocator() {\n        RAPIDJSON_ASSERT(allocator_);\n        return *allocator_;\n    }\n\n    bool Empty() const { return stackTop_ == stack_; }\n    size_t GetSize() const { return static_cast<size_t>(stackTop_ - stack_); }\n    size_t GetCapacity() const { return static_cast<size_t>(stackEnd_ - stack_); }\n\nprivate:\n    template<typename T>\n    void Expand(size_t count) {\n        // Only expand the capacity if the current stack exists. Otherwise just create a stack with initial capacity.\n        size_t newCapacity;\n        if (stack_ == 0) {\n            if (!allocator_)\n                ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator());\n            newCapacity = initialCapacity_;\n        } else {\n            newCapacity = GetCapacity();\n            newCapacity += (newCapacity + 1) / 2;\n        }\n        size_t newSize = GetSize() + sizeof(T) * count;\n        if (newCapacity < newSize)\n            newCapacity = newSize;\n\n        Resize(newCapacity);\n    }\n\n    void Resize(size_t newCapacity) {\n        const size_t size = GetSize();  // Backup the current size\n        stack_ = static_cast<char*>(allocator_->Realloc(stack_, GetCapacity(), newCapacity));\n        stackTop_ = stack_ + size;\n        stackEnd_ = stack_ + newCapacity;\n    }\n\n    void Destroy() {\n        Allocator::Free(stack_);\n        RAPIDJSON_DELETE(ownAllocator_); // Only delete if it is owned by the stack\n    }\n\n    // Prohibit copy constructor & assignment operator.\n    Stack(const Stack&);\n    Stack& operator=(const Stack&);\n\n    Allocator* allocator_;\n    Allocator* ownAllocator_;\n    char *stack_;\n    char *stackTop_;\n    char *stackEnd_;\n    size_t initialCapacity_;\n};\n\n} // namespace internal\nRAPIDJSON_NAMESPACE_END\n\n#if defined(__clang__)\nRAPIDJSON_DIAG_POP\n#endif\n\n#endif // RAPIDJSON_STACK_H_\n"
  },
  {
    "path": "rapidjson/internal/strfunc.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_INTERNAL_STRFUNC_H_\n#define RAPIDJSON_INTERNAL_STRFUNC_H_\n\n#include \"../stream.h\"\n\nRAPIDJSON_NAMESPACE_BEGIN\nnamespace internal {\n\n//! Custom strlen() which works on different character types.\n/*! \\tparam Ch Character type (e.g. char, wchar_t, short)\n    \\param s Null-terminated input string.\n    \\return Number of characters in the string. \n    \\note This has the same semantics as strlen(), the return value is not number of Unicode codepoints.\n*/\ntemplate <typename Ch>\ninline SizeType StrLen(const Ch* s) {\n    RAPIDJSON_ASSERT(s != 0);\n    const Ch* p = s;\n    while (*p) ++p;\n    return SizeType(p - s);\n}\n\n//! Returns number of code points in a encoded string.\ntemplate<typename Encoding>\nbool CountStringCodePoint(const typename Encoding::Ch* s, SizeType length, SizeType* outCount) {\n    RAPIDJSON_ASSERT(s != 0);\n    RAPIDJSON_ASSERT(outCount != 0);\n    GenericStringStream<Encoding> is(s);\n    const typename Encoding::Ch* end = s + length;\n    SizeType count = 0;\n    while (is.src_ < end) {\n        unsigned codepoint;\n        if (!Encoding::Decode(is, &codepoint))\n            return false;\n        count++;\n    }\n    *outCount = count;\n    return true;\n}\n\n} // namespace internal\nRAPIDJSON_NAMESPACE_END\n\n#endif // RAPIDJSON_INTERNAL_STRFUNC_H_\n"
  },
  {
    "path": "rapidjson/internal/strtod.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_STRTOD_\n#define RAPIDJSON_STRTOD_\n\n#include \"ieee754.h\"\n#include \"biginteger.h\"\n#include \"diyfp.h\"\n#include \"pow10.h\"\n\nRAPIDJSON_NAMESPACE_BEGIN\nnamespace internal {\n\ninline double FastPath(double significand, int exp) {\n    if (exp < -308)\n        return 0.0;\n    else if (exp >= 0)\n        return significand * internal::Pow10(exp);\n    else\n        return significand / internal::Pow10(-exp);\n}\n\ninline double StrtodNormalPrecision(double d, int p) {\n    if (p < -308) {\n        // Prevent expSum < -308, making Pow10(p) = 0\n        d = FastPath(d, -308);\n        d = FastPath(d, p + 308);\n    }\n    else\n        d = FastPath(d, p);\n    return d;\n}\n\ntemplate <typename T>\ninline T Min3(T a, T b, T c) {\n    T m = a;\n    if (m > b) m = b;\n    if (m > c) m = c;\n    return m;\n}\n\ninline int CheckWithinHalfULP(double b, const BigInteger& d, int dExp) {\n    const Double db(b);\n    const uint64_t bInt = db.IntegerSignificand();\n    const int bExp = db.IntegerExponent();\n    const int hExp = bExp - 1;\n\n    int dS_Exp2 = 0, dS_Exp5 = 0, bS_Exp2 = 0, bS_Exp5 = 0, hS_Exp2 = 0, hS_Exp5 = 0;\n\n    // Adjust for decimal exponent\n    if (dExp >= 0) {\n        dS_Exp2 += dExp;\n        dS_Exp5 += dExp;\n    }\n    else {\n        bS_Exp2 -= dExp;\n        bS_Exp5 -= dExp;\n        hS_Exp2 -= dExp;\n        hS_Exp5 -= dExp;\n    }\n\n    // Adjust for binary exponent\n    if (bExp >= 0)\n        bS_Exp2 += bExp;\n    else {\n        dS_Exp2 -= bExp;\n        hS_Exp2 -= bExp;\n    }\n\n    // Adjust for half ulp exponent\n    if (hExp >= 0)\n        hS_Exp2 += hExp;\n    else {\n        dS_Exp2 -= hExp;\n        bS_Exp2 -= hExp;\n    }\n\n    // Remove common power of two factor from all three scaled values\n    int common_Exp2 = Min3(dS_Exp2, bS_Exp2, hS_Exp2);\n    dS_Exp2 -= common_Exp2;\n    bS_Exp2 -= common_Exp2;\n    hS_Exp2 -= common_Exp2;\n\n    BigInteger dS = d;\n    dS.MultiplyPow5(static_cast<unsigned>(dS_Exp5)) <<= static_cast<unsigned>(dS_Exp2);\n\n    BigInteger bS(bInt);\n    bS.MultiplyPow5(static_cast<unsigned>(bS_Exp5)) <<= static_cast<unsigned>(bS_Exp2);\n\n    BigInteger hS(1);\n    hS.MultiplyPow5(static_cast<unsigned>(hS_Exp5)) <<= static_cast<unsigned>(hS_Exp2);\n\n    BigInteger delta(0);\n    dS.Difference(bS, &delta);\n\n    return delta.Compare(hS);\n}\n\ninline bool StrtodFast(double d, int p, double* result) {\n    // Use fast path for string-to-double conversion if possible\n    // see http://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/\n    if (p > 22  && p < 22 + 16) {\n        // Fast Path Cases In Disguise\n        d *= internal::Pow10(p - 22);\n        p = 22;\n    }\n\n    if (p >= -22 && p <= 22 && d <= 9007199254740991.0) { // 2^53 - 1\n        *result = FastPath(d, p);\n        return true;\n    }\n    else\n        return false;\n}\n\n// Compute an approximation and see if it is within 1/2 ULP\ninline bool StrtodDiyFp(const char* decimals, size_t length, size_t decimalPosition, int exp, double* result) {\n    uint64_t significand = 0;\n    size_t i = 0;   // 2^64 - 1 = 18446744073709551615, 1844674407370955161 = 0x1999999999999999    \n    for (; i < length; i++) {\n        if (significand  >  RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) ||\n            (significand == RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) && decimals[i] > '5'))\n            break;\n        significand = significand * 10u + static_cast<unsigned>(decimals[i] - '0');\n    }\n    \n    if (i < length && decimals[i] >= '5') // Rounding\n        significand++;\n\n    size_t remaining = length - i;\n    const unsigned kUlpShift = 3;\n    const unsigned kUlp = 1 << kUlpShift;\n    int64_t error = (remaining == 0) ? 0 : kUlp / 2;\n\n    DiyFp v(significand, 0);\n    v = v.Normalize();\n    error <<= -v.e;\n\n    const int dExp = static_cast<int>(decimalPosition) - static_cast<int>(i) + exp;\n\n    int actualExp;\n    DiyFp cachedPower = GetCachedPower10(dExp, &actualExp);\n    if (actualExp != dExp) {\n        static const DiyFp kPow10[] = {\n            DiyFp(RAPIDJSON_UINT64_C2(0xa0000000, 00000000), -60),  // 10^1\n            DiyFp(RAPIDJSON_UINT64_C2(0xc8000000, 00000000), -57),  // 10^2\n            DiyFp(RAPIDJSON_UINT64_C2(0xfa000000, 00000000), -54),  // 10^3\n            DiyFp(RAPIDJSON_UINT64_C2(0x9c400000, 00000000), -50),  // 10^4\n            DiyFp(RAPIDJSON_UINT64_C2(0xc3500000, 00000000), -47),  // 10^5\n            DiyFp(RAPIDJSON_UINT64_C2(0xf4240000, 00000000), -44),  // 10^6\n            DiyFp(RAPIDJSON_UINT64_C2(0x98968000, 00000000), -40)   // 10^7\n        };\n        int  adjustment = dExp - actualExp - 1;\n        RAPIDJSON_ASSERT(adjustment >= 0 && adjustment < 7);\n        v = v * kPow10[adjustment];\n        if (length + static_cast<unsigned>(adjustment)> 19u) // has more digits than decimal digits in 64-bit\n            error += kUlp / 2;\n    }\n\n    v = v * cachedPower;\n\n    error += kUlp + (error == 0 ? 0 : 1);\n\n    const int oldExp = v.e;\n    v = v.Normalize();\n    error <<= oldExp - v.e;\n\n    const unsigned effectiveSignificandSize = Double::EffectiveSignificandSize(64 + v.e);\n    unsigned precisionSize = 64 - effectiveSignificandSize;\n    if (precisionSize + kUlpShift >= 64) {\n        unsigned scaleExp = (precisionSize + kUlpShift) - 63;\n        v.f >>= scaleExp;\n        v.e += scaleExp; \n        error = (error >> scaleExp) + 1 + static_cast<int>(kUlp);\n        precisionSize -= scaleExp;\n    }\n\n    DiyFp rounded(v.f >> precisionSize, v.e + static_cast<int>(precisionSize));\n    const uint64_t precisionBits = (v.f & ((uint64_t(1) << precisionSize) - 1)) * kUlp;\n    const uint64_t halfWay = (uint64_t(1) << (precisionSize - 1)) * kUlp;\n    if (precisionBits >= halfWay + static_cast<unsigned>(error)) {\n        rounded.f++;\n        if (rounded.f & (DiyFp::kDpHiddenBit << 1)) { // rounding overflows mantissa (issue #340)\n            rounded.f >>= 1;\n            rounded.e++;\n        }\n    }\n\n    *result = rounded.ToDouble();\n\n    return halfWay - static_cast<unsigned>(error) >= precisionBits || precisionBits >= halfWay + static_cast<unsigned>(error);\n}\n\ninline double StrtodBigInteger(double approx, const char* decimals, size_t length, size_t decimalPosition, int exp) {\n    const BigInteger dInt(decimals, length);\n    const int dExp = static_cast<int>(decimalPosition) - static_cast<int>(length) + exp;\n    Double a(approx);\n    int cmp = CheckWithinHalfULP(a.Value(), dInt, dExp);\n    if (cmp < 0)\n        return a.Value();  // within half ULP\n    else if (cmp == 0) {\n        // Round towards even\n        if (a.Significand() & 1)\n            return a.NextPositiveDouble();\n        else\n            return a.Value();\n    }\n    else // adjustment\n        return a.NextPositiveDouble();\n}\n\ninline double StrtodFullPrecision(double d, int p, const char* decimals, size_t length, size_t decimalPosition, int exp) {\n    RAPIDJSON_ASSERT(d >= 0.0);\n    RAPIDJSON_ASSERT(length >= 1);\n\n    double result;\n    if (StrtodFast(d, p, &result))\n        return result;\n\n    // Trim leading zeros\n    while (*decimals == '0' && length > 1) {\n        length--;\n        decimals++;\n        decimalPosition--;\n    }\n\n    // Trim trailing zeros\n    while (decimals[length - 1] == '0' && length > 1) {\n        length--;\n        decimalPosition--;\n        exp++;\n    }\n\n    // Trim right-most digits\n    const int kMaxDecimalDigit = 780;\n    if (static_cast<int>(length) > kMaxDecimalDigit) {\n        int delta = (static_cast<int>(length) - kMaxDecimalDigit);\n        exp += delta;\n        decimalPosition -= static_cast<unsigned>(delta);\n        length = kMaxDecimalDigit;\n    }\n\n    // If too small, underflow to zero\n    if (int(length) + exp < -324)\n        return 0.0;\n\n    if (StrtodDiyFp(decimals, length, decimalPosition, exp, &result))\n        return result;\n\n    // Use approximation from StrtodDiyFp and make adjustment with BigInteger comparison\n    return StrtodBigInteger(result, decimals, length, decimalPosition, exp);\n}\n\n} // namespace internal\nRAPIDJSON_NAMESPACE_END\n\n#endif // RAPIDJSON_STRTOD_\n"
  },
  {
    "path": "rapidjson/internal/swap.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n//\n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_INTERNAL_SWAP_H_\n#define RAPIDJSON_INTERNAL_SWAP_H_\n\n#include \"../rapidjson.h\"\n\n#if defined(__clang__)\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(c++98-compat)\n#endif\n\nRAPIDJSON_NAMESPACE_BEGIN\nnamespace internal {\n\n//! Custom swap() to avoid dependency on C++ <algorithm> header\n/*! \\tparam T Type of the arguments to swap, should be instantiated with primitive C++ types only.\n    \\note This has the same semantics as std::swap().\n*/\ntemplate <typename T>\ninline void Swap(T& a, T& b) RAPIDJSON_NOEXCEPT {\n    T tmp = a;\n        a = b;\n        b = tmp;\n}\n\n} // namespace internal\nRAPIDJSON_NAMESPACE_END\n\n#if defined(__clang__)\nRAPIDJSON_DIAG_POP\n#endif\n\n#endif // RAPIDJSON_INTERNAL_SWAP_H_\n"
  },
  {
    "path": "rapidjson/istreamwrapper.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_ISTREAMWRAPPER_H_\n#define RAPIDJSON_ISTREAMWRAPPER_H_\n\n#include \"stream.h\"\n#include <iosfwd>\n\n#ifdef __clang__\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(padded)\n#endif\n\n#ifdef _MSC_VER\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(4351) // new behavior: elements of array 'array' will be default initialized\n#endif\n\nRAPIDJSON_NAMESPACE_BEGIN\n\n//! Wrapper of \\c std::basic_istream into RapidJSON's Stream concept.\n/*!\n    The classes can be wrapped including but not limited to:\n\n    - \\c std::istringstream\n    - \\c std::stringstream\n    - \\c std::wistringstream\n    - \\c std::wstringstream\n    - \\c std::ifstream\n    - \\c std::fstream\n    - \\c std::wifstream\n    - \\c std::wfstream\n\n    \\tparam StreamType Class derived from \\c std::basic_istream.\n*/\n   \ntemplate <typename StreamType>\nclass BasicIStreamWrapper {\npublic:\n    typedef typename StreamType::char_type Ch;\n    BasicIStreamWrapper(StreamType& stream) : stream_(stream), count_(), peekBuffer_() {}\n\n    Ch Peek() const { \n        typename StreamType::int_type c = stream_.peek();\n        return RAPIDJSON_LIKELY(c != StreamType::traits_type::eof()) ? static_cast<Ch>(c) : '\\0';\n    }\n\n    Ch Take() { \n        typename StreamType::int_type c = stream_.get();\n        if (RAPIDJSON_LIKELY(c != StreamType::traits_type::eof())) {\n            count_++;\n            return static_cast<Ch>(c);\n        }\n        else\n            return '\\0';\n    }\n\n    // tellg() may return -1 when failed. So we count by ourself.\n    size_t Tell() const { return count_; }\n\n    Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }\n    void Put(Ch) { RAPIDJSON_ASSERT(false); }\n    void Flush() { RAPIDJSON_ASSERT(false); }\n    size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }\n\n    // For encoding detection only.\n    const Ch* Peek4() const {\n        RAPIDJSON_ASSERT(sizeof(Ch) == 1); // Only usable for byte stream.\n        int i;\n        bool hasError = false;\n        for (i = 0; i < 4; ++i) {\n            typename StreamType::int_type c = stream_.get();\n            if (c == StreamType::traits_type::eof()) {\n                hasError = true;\n                stream_.clear();\n                break;\n            }\n            peekBuffer_[i] = static_cast<Ch>(c);\n        }\n        for (--i; i >= 0; --i)\n            stream_.putback(peekBuffer_[i]);\n        return !hasError ? peekBuffer_ : 0;\n    }\n\nprivate:\n    BasicIStreamWrapper(const BasicIStreamWrapper&);\n    BasicIStreamWrapper& operator=(const BasicIStreamWrapper&);\n\n    StreamType& stream_;\n    size_t count_;  //!< Number of characters read. Note:\n    mutable Ch peekBuffer_[4];\n};\n\ntypedef BasicIStreamWrapper<std::istream> IStreamWrapper;\ntypedef BasicIStreamWrapper<std::wistream> WIStreamWrapper;\n\n#if defined(__clang__) || defined(_MSC_VER)\nRAPIDJSON_DIAG_POP\n#endif\n\nRAPIDJSON_NAMESPACE_END\n\n#endif // RAPIDJSON_ISTREAMWRAPPER_H_\n"
  },
  {
    "path": "rapidjson/memorybuffer.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_MEMORYBUFFER_H_\n#define RAPIDJSON_MEMORYBUFFER_H_\n\n#include \"stream.h\"\n#include \"internal/stack.h\"\n\nRAPIDJSON_NAMESPACE_BEGIN\n\n//! Represents an in-memory output byte stream.\n/*!\n    This class is mainly for being wrapped by EncodedOutputStream or AutoUTFOutputStream.\n\n    It is similar to FileWriteBuffer but the destination is an in-memory buffer instead of a file.\n\n    Differences between MemoryBuffer and StringBuffer:\n    1. StringBuffer has Encoding but MemoryBuffer is only a byte buffer. \n    2. StringBuffer::GetString() returns a null-terminated string. MemoryBuffer::GetBuffer() returns a buffer without terminator.\n\n    \\tparam Allocator type for allocating memory buffer.\n    \\note implements Stream concept\n*/\ntemplate <typename Allocator = CrtAllocator>\nstruct GenericMemoryBuffer {\n    typedef char Ch; // byte\n\n    GenericMemoryBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {}\n\n    void Put(Ch c) { *stack_.template Push<Ch>() = c; }\n    void Flush() {}\n\n    void Clear() { stack_.Clear(); }\n    void ShrinkToFit() { stack_.ShrinkToFit(); }\n    Ch* Push(size_t count) { return stack_.template Push<Ch>(count); }\n    void Pop(size_t count) { stack_.template Pop<Ch>(count); }\n\n    const Ch* GetBuffer() const {\n        return stack_.template Bottom<Ch>();\n    }\n\n    size_t GetSize() const { return stack_.GetSize(); }\n\n    static const size_t kDefaultCapacity = 256;\n    mutable internal::Stack<Allocator> stack_;\n};\n\ntypedef GenericMemoryBuffer<> MemoryBuffer;\n\n//! Implement specialized version of PutN() with memset() for better performance.\ntemplate<>\ninline void PutN(MemoryBuffer& memoryBuffer, char c, size_t n) {\n    std::memset(memoryBuffer.stack_.Push<char>(n), c, n * sizeof(c));\n}\n\nRAPIDJSON_NAMESPACE_END\n\n#endif // RAPIDJSON_MEMORYBUFFER_H_\n"
  },
  {
    "path": "rapidjson/memorystream.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_MEMORYSTREAM_H_\n#define RAPIDJSON_MEMORYSTREAM_H_\n\n#include \"stream.h\"\n\n#ifdef __clang__\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(unreachable-code)\nRAPIDJSON_DIAG_OFF(missing-noreturn)\n#endif\n\nRAPIDJSON_NAMESPACE_BEGIN\n\n//! Represents an in-memory input byte stream.\n/*!\n    This class is mainly for being wrapped by EncodedInputStream or AutoUTFInputStream.\n\n    It is similar to FileReadBuffer but the source is an in-memory buffer instead of a file.\n\n    Differences between MemoryStream and StringStream:\n    1. StringStream has encoding but MemoryStream is a byte stream.\n    2. MemoryStream needs size of the source buffer and the buffer don't need to be null terminated. StringStream assume null-terminated string as source.\n    3. MemoryStream supports Peek4() for encoding detection. StringStream is specified with an encoding so it should not have Peek4().\n    \\note implements Stream concept\n*/\nstruct MemoryStream {\n    typedef char Ch; // byte\n\n    MemoryStream(const Ch *src, size_t size) : src_(src), begin_(src), end_(src + size), size_(size) {}\n\n    Ch Peek() const { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\\0' : *src_; }\n    Ch Take() { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\\0' : *src_++; }\n    size_t Tell() const { return static_cast<size_t>(src_ - begin_); }\n\n    Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }\n    void Put(Ch) { RAPIDJSON_ASSERT(false); }\n    void Flush() { RAPIDJSON_ASSERT(false); }\n    size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }\n\n    // For encoding detection only.\n    const Ch* Peek4() const {\n        return Tell() + 4 <= size_ ? src_ : 0;\n    }\n\n    const Ch* src_;     //!< Current read position.\n    const Ch* begin_;   //!< Original head of the string.\n    const Ch* end_;     //!< End of stream.\n    size_t size_;       //!< Size of the stream.\n};\n\nRAPIDJSON_NAMESPACE_END\n\n#ifdef __clang__\nRAPIDJSON_DIAG_POP\n#endif\n\n#endif // RAPIDJSON_MEMORYBUFFER_H_\n"
  },
  {
    "path": "rapidjson/msinttypes/inttypes.h",
    "content": "// ISO C9x  compliant inttypes.h for Microsoft Visual Studio\n// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 \n// \n//  Copyright (c) 2006-2013 Alexander Chemeris\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are met:\n// \n//   1. Redistributions of source code must retain the above copyright notice,\n//      this list of conditions and the following disclaimer.\n// \n//   2. Redistributions in binary form must reproduce the above copyright\n//      notice, this list of conditions and the following disclaimer in the\n//      documentation and/or other materials provided with the distribution.\n// \n//   3. Neither the name of the product nor the names of its contributors may\n//      be used to endorse or promote products derived from this software\n//      without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\n// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO\n// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;\n// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \n// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\n// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n// \n///////////////////////////////////////////////////////////////////////////////\n\n// The above software in this distribution may have been modified by \n// THL A29 Limited (\"Tencent Modifications\"). \n// All Tencent Modifications are Copyright (C) 2015 THL A29 Limited.\n\n#ifndef _MSC_VER // [\n#error \"Use this header only with Microsoft Visual C++ compilers!\"\n#endif // _MSC_VER ]\n\n#ifndef _MSC_INTTYPES_H_ // [\n#define _MSC_INTTYPES_H_\n\n#if _MSC_VER > 1000\n#pragma once\n#endif\n\n#include \"stdint.h\"\n\n// miloyip: VC supports inttypes.h since VC2013\n#if _MSC_VER >= 1800\n#include <inttypes.h>\n#else\n\n// 7.8 Format conversion of integer types\n\ntypedef struct {\n   intmax_t quot;\n   intmax_t rem;\n} imaxdiv_t;\n\n// 7.8.1 Macros for format specifiers\n\n#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [   See footnote 185 at page 198\n\n// The fprintf macros for signed integers are:\n#define PRId8       \"d\"\n#define PRIi8       \"i\"\n#define PRIdLEAST8  \"d\"\n#define PRIiLEAST8  \"i\"\n#define PRIdFAST8   \"d\"\n#define PRIiFAST8   \"i\"\n\n#define PRId16       \"hd\"\n#define PRIi16       \"hi\"\n#define PRIdLEAST16  \"hd\"\n#define PRIiLEAST16  \"hi\"\n#define PRIdFAST16   \"hd\"\n#define PRIiFAST16   \"hi\"\n\n#define PRId32       \"I32d\"\n#define PRIi32       \"I32i\"\n#define PRIdLEAST32  \"I32d\"\n#define PRIiLEAST32  \"I32i\"\n#define PRIdFAST32   \"I32d\"\n#define PRIiFAST32   \"I32i\"\n\n#define PRId64       \"I64d\"\n#define PRIi64       \"I64i\"\n#define PRIdLEAST64  \"I64d\"\n#define PRIiLEAST64  \"I64i\"\n#define PRIdFAST64   \"I64d\"\n#define PRIiFAST64   \"I64i\"\n\n#define PRIdMAX     \"I64d\"\n#define PRIiMAX     \"I64i\"\n\n#define PRIdPTR     \"Id\"\n#define PRIiPTR     \"Ii\"\n\n// The fprintf macros for unsigned integers are:\n#define PRIo8       \"o\"\n#define PRIu8       \"u\"\n#define PRIx8       \"x\"\n#define PRIX8       \"X\"\n#define PRIoLEAST8  \"o\"\n#define PRIuLEAST8  \"u\"\n#define PRIxLEAST8  \"x\"\n#define PRIXLEAST8  \"X\"\n#define PRIoFAST8   \"o\"\n#define PRIuFAST8   \"u\"\n#define PRIxFAST8   \"x\"\n#define PRIXFAST8   \"X\"\n\n#define PRIo16       \"ho\"\n#define PRIu16       \"hu\"\n#define PRIx16       \"hx\"\n#define PRIX16       \"hX\"\n#define PRIoLEAST16  \"ho\"\n#define PRIuLEAST16  \"hu\"\n#define PRIxLEAST16  \"hx\"\n#define PRIXLEAST16  \"hX\"\n#define PRIoFAST16   \"ho\"\n#define PRIuFAST16   \"hu\"\n#define PRIxFAST16   \"hx\"\n#define PRIXFAST16   \"hX\"\n\n#define PRIo32       \"I32o\"\n#define PRIu32       \"I32u\"\n#define PRIx32       \"I32x\"\n#define PRIX32       \"I32X\"\n#define PRIoLEAST32  \"I32o\"\n#define PRIuLEAST32  \"I32u\"\n#define PRIxLEAST32  \"I32x\"\n#define PRIXLEAST32  \"I32X\"\n#define PRIoFAST32   \"I32o\"\n#define PRIuFAST32   \"I32u\"\n#define PRIxFAST32   \"I32x\"\n#define PRIXFAST32   \"I32X\"\n\n#define PRIo64       \"I64o\"\n#define PRIu64       \"I64u\"\n#define PRIx64       \"I64x\"\n#define PRIX64       \"I64X\"\n#define PRIoLEAST64  \"I64o\"\n#define PRIuLEAST64  \"I64u\"\n#define PRIxLEAST64  \"I64x\"\n#define PRIXLEAST64  \"I64X\"\n#define PRIoFAST64   \"I64o\"\n#define PRIuFAST64   \"I64u\"\n#define PRIxFAST64   \"I64x\"\n#define PRIXFAST64   \"I64X\"\n\n#define PRIoMAX     \"I64o\"\n#define PRIuMAX     \"I64u\"\n#define PRIxMAX     \"I64x\"\n#define PRIXMAX     \"I64X\"\n\n#define PRIoPTR     \"Io\"\n#define PRIuPTR     \"Iu\"\n#define PRIxPTR     \"Ix\"\n#define PRIXPTR     \"IX\"\n\n// The fscanf macros for signed integers are:\n#define SCNd8       \"d\"\n#define SCNi8       \"i\"\n#define SCNdLEAST8  \"d\"\n#define SCNiLEAST8  \"i\"\n#define SCNdFAST8   \"d\"\n#define SCNiFAST8   \"i\"\n\n#define SCNd16       \"hd\"\n#define SCNi16       \"hi\"\n#define SCNdLEAST16  \"hd\"\n#define SCNiLEAST16  \"hi\"\n#define SCNdFAST16   \"hd\"\n#define SCNiFAST16   \"hi\"\n\n#define SCNd32       \"ld\"\n#define SCNi32       \"li\"\n#define SCNdLEAST32  \"ld\"\n#define SCNiLEAST32  \"li\"\n#define SCNdFAST32   \"ld\"\n#define SCNiFAST32   \"li\"\n\n#define SCNd64       \"I64d\"\n#define SCNi64       \"I64i\"\n#define SCNdLEAST64  \"I64d\"\n#define SCNiLEAST64  \"I64i\"\n#define SCNdFAST64   \"I64d\"\n#define SCNiFAST64   \"I64i\"\n\n#define SCNdMAX     \"I64d\"\n#define SCNiMAX     \"I64i\"\n\n#ifdef _WIN64 // [\n#  define SCNdPTR     \"I64d\"\n#  define SCNiPTR     \"I64i\"\n#else  // _WIN64 ][\n#  define SCNdPTR     \"ld\"\n#  define SCNiPTR     \"li\"\n#endif  // _WIN64 ]\n\n// The fscanf macros for unsigned integers are:\n#define SCNo8       \"o\"\n#define SCNu8       \"u\"\n#define SCNx8       \"x\"\n#define SCNX8       \"X\"\n#define SCNoLEAST8  \"o\"\n#define SCNuLEAST8  \"u\"\n#define SCNxLEAST8  \"x\"\n#define SCNXLEAST8  \"X\"\n#define SCNoFAST8   \"o\"\n#define SCNuFAST8   \"u\"\n#define SCNxFAST8   \"x\"\n#define SCNXFAST8   \"X\"\n\n#define SCNo16       \"ho\"\n#define SCNu16       \"hu\"\n#define SCNx16       \"hx\"\n#define SCNX16       \"hX\"\n#define SCNoLEAST16  \"ho\"\n#define SCNuLEAST16  \"hu\"\n#define SCNxLEAST16  \"hx\"\n#define SCNXLEAST16  \"hX\"\n#define SCNoFAST16   \"ho\"\n#define SCNuFAST16   \"hu\"\n#define SCNxFAST16   \"hx\"\n#define SCNXFAST16   \"hX\"\n\n#define SCNo32       \"lo\"\n#define SCNu32       \"lu\"\n#define SCNx32       \"lx\"\n#define SCNX32       \"lX\"\n#define SCNoLEAST32  \"lo\"\n#define SCNuLEAST32  \"lu\"\n#define SCNxLEAST32  \"lx\"\n#define SCNXLEAST32  \"lX\"\n#define SCNoFAST32   \"lo\"\n#define SCNuFAST32   \"lu\"\n#define SCNxFAST32   \"lx\"\n#define SCNXFAST32   \"lX\"\n\n#define SCNo64       \"I64o\"\n#define SCNu64       \"I64u\"\n#define SCNx64       \"I64x\"\n#define SCNX64       \"I64X\"\n#define SCNoLEAST64  \"I64o\"\n#define SCNuLEAST64  \"I64u\"\n#define SCNxLEAST64  \"I64x\"\n#define SCNXLEAST64  \"I64X\"\n#define SCNoFAST64   \"I64o\"\n#define SCNuFAST64   \"I64u\"\n#define SCNxFAST64   \"I64x\"\n#define SCNXFAST64   \"I64X\"\n\n#define SCNoMAX     \"I64o\"\n#define SCNuMAX     \"I64u\"\n#define SCNxMAX     \"I64x\"\n#define SCNXMAX     \"I64X\"\n\n#ifdef _WIN64 // [\n#  define SCNoPTR     \"I64o\"\n#  define SCNuPTR     \"I64u\"\n#  define SCNxPTR     \"I64x\"\n#  define SCNXPTR     \"I64X\"\n#else  // _WIN64 ][\n#  define SCNoPTR     \"lo\"\n#  define SCNuPTR     \"lu\"\n#  define SCNxPTR     \"lx\"\n#  define SCNXPTR     \"lX\"\n#endif  // _WIN64 ]\n\n#endif // __STDC_FORMAT_MACROS ]\n\n// 7.8.2 Functions for greatest-width integer types\n\n// 7.8.2.1 The imaxabs function\n#define imaxabs _abs64\n\n// 7.8.2.2 The imaxdiv function\n\n// This is modified version of div() function from Microsoft's div.c found\n// in %MSVC.NET%\\crt\\src\\div.c\n#ifdef STATIC_IMAXDIV // [\nstatic\n#else // STATIC_IMAXDIV ][\n_inline\n#endif // STATIC_IMAXDIV ]\nimaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom)\n{\n   imaxdiv_t result;\n\n   result.quot = numer / denom;\n   result.rem = numer % denom;\n\n   if (numer < 0 && result.rem > 0) {\n      // did division wrong; must fix up\n      ++result.quot;\n      result.rem -= denom;\n   }\n\n   return result;\n}\n\n// 7.8.2.3 The strtoimax and strtoumax functions\n#define strtoimax _strtoi64\n#define strtoumax _strtoui64\n\n// 7.8.2.4 The wcstoimax and wcstoumax functions\n#define wcstoimax _wcstoi64\n#define wcstoumax _wcstoui64\n\n#endif // _MSC_VER >= 1800\n\n#endif // _MSC_INTTYPES_H_ ]\n"
  },
  {
    "path": "rapidjson/msinttypes/stdint.h",
    "content": "// ISO C9x  compliant stdint.h for Microsoft Visual Studio\n// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 \n// \n//  Copyright (c) 2006-2013 Alexander Chemeris\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are met:\n// \n//   1. Redistributions of source code must retain the above copyright notice,\n//      this list of conditions and the following disclaimer.\n// \n//   2. Redistributions in binary form must reproduce the above copyright\n//      notice, this list of conditions and the following disclaimer in the\n//      documentation and/or other materials provided with the distribution.\n// \n//   3. Neither the name of the product nor the names of its contributors may\n//      be used to endorse or promote products derived from this software\n//      without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\n// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO\n// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;\n// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \n// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\n// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n// \n///////////////////////////////////////////////////////////////////////////////\n\n// The above software in this distribution may have been modified by \n// THL A29 Limited (\"Tencent Modifications\"). \n// All Tencent Modifications are Copyright (C) 2015 THL A29 Limited.\n\n#ifndef _MSC_VER // [\n#error \"Use this header only with Microsoft Visual C++ compilers!\"\n#endif // _MSC_VER ]\n\n#ifndef _MSC_STDINT_H_ // [\n#define _MSC_STDINT_H_\n\n#if _MSC_VER > 1000\n#pragma once\n#endif\n\n// miloyip: Originally Visual Studio 2010 uses its own stdint.h. However it generates warning with INT64_C(), so change to use this file for vs2010.\n#if _MSC_VER >= 1600 // [\n#include <stdint.h>\n\n#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [   See footnote 224 at page 260\n\n#undef INT8_C\n#undef INT16_C\n#undef INT32_C\n#undef INT64_C\n#undef UINT8_C\n#undef UINT16_C\n#undef UINT32_C\n#undef UINT64_C\n\n// 7.18.4.1 Macros for minimum-width integer constants\n\n#define INT8_C(val)  val##i8\n#define INT16_C(val) val##i16\n#define INT32_C(val) val##i32\n#define INT64_C(val) val##i64\n\n#define UINT8_C(val)  val##ui8\n#define UINT16_C(val) val##ui16\n#define UINT32_C(val) val##ui32\n#define UINT64_C(val) val##ui64\n\n// 7.18.4.2 Macros for greatest-width integer constants\n// These #ifndef's are needed to prevent collisions with <boost/cstdint.hpp>.\n// Check out Issue 9 for the details.\n#ifndef INTMAX_C //   [\n#  define INTMAX_C   INT64_C\n#endif // INTMAX_C    ]\n#ifndef UINTMAX_C //  [\n#  define UINTMAX_C  UINT64_C\n#endif // UINTMAX_C   ]\n\n#endif // __STDC_CONSTANT_MACROS ]\n\n#else // ] _MSC_VER >= 1700 [\n\n#include <limits.h>\n\n// For Visual Studio 6 in C++ mode and for many Visual Studio versions when\n// compiling for ARM we have to wrap <wchar.h> include with 'extern \"C++\" {}'\n// or compiler would give many errors like this:\n//   error C2733: second C linkage of overloaded function 'wmemchr' not allowed\n#if defined(__cplusplus) && !defined(_M_ARM)\nextern \"C\" {\n#endif\n#  include <wchar.h>\n#if defined(__cplusplus) && !defined(_M_ARM)\n}\n#endif\n\n// Define _W64 macros to mark types changing their size, like intptr_t.\n#ifndef _W64\n#  if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300\n#     define _W64 __w64\n#  else\n#     define _W64\n#  endif\n#endif\n\n\n// 7.18.1 Integer types\n\n// 7.18.1.1 Exact-width integer types\n\n// Visual Studio 6 and Embedded Visual C++ 4 doesn't\n// realize that, e.g. char has the same size as __int8\n// so we give up on __intX for them.\n#if (_MSC_VER < 1300)\n   typedef signed char       int8_t;\n   typedef signed short      int16_t;\n   typedef signed int        int32_t;\n   typedef unsigned char     uint8_t;\n   typedef unsigned short    uint16_t;\n   typedef unsigned int      uint32_t;\n#else\n   typedef signed __int8     int8_t;\n   typedef signed __int16    int16_t;\n   typedef signed __int32    int32_t;\n   typedef unsigned __int8   uint8_t;\n   typedef unsigned __int16  uint16_t;\n   typedef unsigned __int32  uint32_t;\n#endif\ntypedef signed __int64       int64_t;\ntypedef unsigned __int64     uint64_t;\n\n\n// 7.18.1.2 Minimum-width integer types\ntypedef int8_t    int_least8_t;\ntypedef int16_t   int_least16_t;\ntypedef int32_t   int_least32_t;\ntypedef int64_t   int_least64_t;\ntypedef uint8_t   uint_least8_t;\ntypedef uint16_t  uint_least16_t;\ntypedef uint32_t  uint_least32_t;\ntypedef uint64_t  uint_least64_t;\n\n// 7.18.1.3 Fastest minimum-width integer types\ntypedef int8_t    int_fast8_t;\ntypedef int16_t   int_fast16_t;\ntypedef int32_t   int_fast32_t;\ntypedef int64_t   int_fast64_t;\ntypedef uint8_t   uint_fast8_t;\ntypedef uint16_t  uint_fast16_t;\ntypedef uint32_t  uint_fast32_t;\ntypedef uint64_t  uint_fast64_t;\n\n// 7.18.1.4 Integer types capable of holding object pointers\n#ifdef _WIN64 // [\n   typedef signed __int64    intptr_t;\n   typedef unsigned __int64  uintptr_t;\n#else // _WIN64 ][\n   typedef _W64 signed int   intptr_t;\n   typedef _W64 unsigned int uintptr_t;\n#endif // _WIN64 ]\n\n// 7.18.1.5 Greatest-width integer types\ntypedef int64_t   intmax_t;\ntypedef uint64_t  uintmax_t;\n\n\n// 7.18.2 Limits of specified-width integer types\n\n#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [   See footnote 220 at page 257 and footnote 221 at page 259\n\n// 7.18.2.1 Limits of exact-width integer types\n#define INT8_MIN     ((int8_t)_I8_MIN)\n#define INT8_MAX     _I8_MAX\n#define INT16_MIN    ((int16_t)_I16_MIN)\n#define INT16_MAX    _I16_MAX\n#define INT32_MIN    ((int32_t)_I32_MIN)\n#define INT32_MAX    _I32_MAX\n#define INT64_MIN    ((int64_t)_I64_MIN)\n#define INT64_MAX    _I64_MAX\n#define UINT8_MAX    _UI8_MAX\n#define UINT16_MAX   _UI16_MAX\n#define UINT32_MAX   _UI32_MAX\n#define UINT64_MAX   _UI64_MAX\n\n// 7.18.2.2 Limits of minimum-width integer types\n#define INT_LEAST8_MIN    INT8_MIN\n#define INT_LEAST8_MAX    INT8_MAX\n#define INT_LEAST16_MIN   INT16_MIN\n#define INT_LEAST16_MAX   INT16_MAX\n#define INT_LEAST32_MIN   INT32_MIN\n#define INT_LEAST32_MAX   INT32_MAX\n#define INT_LEAST64_MIN   INT64_MIN\n#define INT_LEAST64_MAX   INT64_MAX\n#define UINT_LEAST8_MAX   UINT8_MAX\n#define UINT_LEAST16_MAX  UINT16_MAX\n#define UINT_LEAST32_MAX  UINT32_MAX\n#define UINT_LEAST64_MAX  UINT64_MAX\n\n// 7.18.2.3 Limits of fastest minimum-width integer types\n#define INT_FAST8_MIN    INT8_MIN\n#define INT_FAST8_MAX    INT8_MAX\n#define INT_FAST16_MIN   INT16_MIN\n#define INT_FAST16_MAX   INT16_MAX\n#define INT_FAST32_MIN   INT32_MIN\n#define INT_FAST32_MAX   INT32_MAX\n#define INT_FAST64_MIN   INT64_MIN\n#define INT_FAST64_MAX   INT64_MAX\n#define UINT_FAST8_MAX   UINT8_MAX\n#define UINT_FAST16_MAX  UINT16_MAX\n#define UINT_FAST32_MAX  UINT32_MAX\n#define UINT_FAST64_MAX  UINT64_MAX\n\n// 7.18.2.4 Limits of integer types capable of holding object pointers\n#ifdef _WIN64 // [\n#  define INTPTR_MIN   INT64_MIN\n#  define INTPTR_MAX   INT64_MAX\n#  define UINTPTR_MAX  UINT64_MAX\n#else // _WIN64 ][\n#  define INTPTR_MIN   INT32_MIN\n#  define INTPTR_MAX   INT32_MAX\n#  define UINTPTR_MAX  UINT32_MAX\n#endif // _WIN64 ]\n\n// 7.18.2.5 Limits of greatest-width integer types\n#define INTMAX_MIN   INT64_MIN\n#define INTMAX_MAX   INT64_MAX\n#define UINTMAX_MAX  UINT64_MAX\n\n// 7.18.3 Limits of other integer types\n\n#ifdef _WIN64 // [\n#  define PTRDIFF_MIN  _I64_MIN\n#  define PTRDIFF_MAX  _I64_MAX\n#else  // _WIN64 ][\n#  define PTRDIFF_MIN  _I32_MIN\n#  define PTRDIFF_MAX  _I32_MAX\n#endif  // _WIN64 ]\n\n#define SIG_ATOMIC_MIN  INT_MIN\n#define SIG_ATOMIC_MAX  INT_MAX\n\n#ifndef SIZE_MAX // [\n#  ifdef _WIN64 // [\n#     define SIZE_MAX  _UI64_MAX\n#  else // _WIN64 ][\n#     define SIZE_MAX  _UI32_MAX\n#  endif // _WIN64 ]\n#endif // SIZE_MAX ]\n\n// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>\n#ifndef WCHAR_MIN // [\n#  define WCHAR_MIN  0\n#endif  // WCHAR_MIN ]\n#ifndef WCHAR_MAX // [\n#  define WCHAR_MAX  _UI16_MAX\n#endif  // WCHAR_MAX ]\n\n#define WINT_MIN  0\n#define WINT_MAX  _UI16_MAX\n\n#endif // __STDC_LIMIT_MACROS ]\n\n\n// 7.18.4 Limits of other integer types\n\n#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [   See footnote 224 at page 260\n\n// 7.18.4.1 Macros for minimum-width integer constants\n\n#define INT8_C(val)  val##i8\n#define INT16_C(val) val##i16\n#define INT32_C(val) val##i32\n#define INT64_C(val) val##i64\n\n#define UINT8_C(val)  val##ui8\n#define UINT16_C(val) val##ui16\n#define UINT32_C(val) val##ui32\n#define UINT64_C(val) val##ui64\n\n// 7.18.4.2 Macros for greatest-width integer constants\n// These #ifndef's are needed to prevent collisions with <boost/cstdint.hpp>.\n// Check out Issue 9 for the details.\n#ifndef INTMAX_C //   [\n#  define INTMAX_C   INT64_C\n#endif // INTMAX_C    ]\n#ifndef UINTMAX_C //  [\n#  define UINTMAX_C  UINT64_C\n#endif // UINTMAX_C   ]\n\n#endif // __STDC_CONSTANT_MACROS ]\n\n#endif // _MSC_VER >= 1600 ]\n\n#endif // _MSC_STDINT_H_ ]\n"
  },
  {
    "path": "rapidjson/ostreamwrapper.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_OSTREAMWRAPPER_H_\n#define RAPIDJSON_OSTREAMWRAPPER_H_\n\n#include \"stream.h\"\n#include <iosfwd>\n\n#ifdef __clang__\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(padded)\n#endif\n\nRAPIDJSON_NAMESPACE_BEGIN\n\n//! Wrapper of \\c std::basic_ostream into RapidJSON's Stream concept.\n/*!\n    The classes can be wrapped including but not limited to:\n\n    - \\c std::ostringstream\n    - \\c std::stringstream\n    - \\c std::wpstringstream\n    - \\c std::wstringstream\n    - \\c std::ifstream\n    - \\c std::fstream\n    - \\c std::wofstream\n    - \\c std::wfstream\n\n    \\tparam StreamType Class derived from \\c std::basic_ostream.\n*/\n   \ntemplate <typename StreamType>\nclass BasicOStreamWrapper {\npublic:\n    typedef typename StreamType::char_type Ch;\n    BasicOStreamWrapper(StreamType& stream) : stream_(stream) {}\n\n    void Put(Ch c) {\n        stream_.put(c);\n    }\n\n    void Flush() {\n        stream_.flush();\n    }\n\n    // Not implemented\n    char Peek() const { RAPIDJSON_ASSERT(false); return 0; }\n    char Take() { RAPIDJSON_ASSERT(false); return 0; }\n    size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }\n    char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }\n    size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; }\n\nprivate:\n    BasicOStreamWrapper(const BasicOStreamWrapper&);\n    BasicOStreamWrapper& operator=(const BasicOStreamWrapper&);\n\n    StreamType& stream_;\n};\n\ntypedef BasicOStreamWrapper<std::ostream> OStreamWrapper;\ntypedef BasicOStreamWrapper<std::wostream> WOStreamWrapper;\n\n#ifdef __clang__\nRAPIDJSON_DIAG_POP\n#endif\n\nRAPIDJSON_NAMESPACE_END\n\n#endif // RAPIDJSON_OSTREAMWRAPPER_H_\n"
  },
  {
    "path": "rapidjson/pointer.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_POINTER_H_\n#define RAPIDJSON_POINTER_H_\n\n#include \"document.h\"\n#include \"internal/itoa.h\"\n\n#ifdef __clang__\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(switch-enum)\n#endif\n\n#ifdef _MSC_VER\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated\n#endif\n\nRAPIDJSON_NAMESPACE_BEGIN\n\nstatic const SizeType kPointerInvalidIndex = ~SizeType(0);  //!< Represents an invalid index in GenericPointer::Token\n\n//! Error code of parsing.\n/*! \\ingroup RAPIDJSON_ERRORS\n    \\see GenericPointer::GenericPointer, GenericPointer::GetParseErrorCode\n*/\nenum PointerParseErrorCode {\n    kPointerParseErrorNone = 0,                     //!< The parse is successful\n\n    kPointerParseErrorTokenMustBeginWithSolidus,    //!< A token must begin with a '/'\n    kPointerParseErrorInvalidEscape,                //!< Invalid escape\n    kPointerParseErrorInvalidPercentEncoding,       //!< Invalid percent encoding in URI fragment\n    kPointerParseErrorCharacterMustPercentEncode    //!< A character must percent encoded in URI fragment\n};\n\n///////////////////////////////////////////////////////////////////////////////\n// GenericPointer\n\n//! Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator.\n/*!\n    This class implements RFC 6901 \"JavaScript Object Notation (JSON) Pointer\" \n    (https://tools.ietf.org/html/rfc6901).\n\n    A JSON pointer is for identifying a specific value in a JSON document\n    (GenericDocument). It can simplify coding of DOM tree manipulation, because it\n    can access multiple-level depth of DOM tree with single API call.\n\n    After it parses a string representation (e.g. \"/foo/0\" or URI fragment \n    representation (e.g. \"#/foo/0\") into its internal representation (tokens),\n    it can be used to resolve a specific value in multiple documents, or sub-tree \n    of documents.\n\n    Contrary to GenericValue, Pointer can be copy constructed and copy assigned.\n    Apart from assignment, a Pointer cannot be modified after construction.\n\n    Although Pointer is very convenient, please aware that constructing Pointer\n    involves parsing and dynamic memory allocation. A special constructor with user-\n    supplied tokens eliminates these.\n\n    GenericPointer depends on GenericDocument and GenericValue.\n    \n    \\tparam ValueType The value type of the DOM tree. E.g. GenericValue<UTF8<> >\n    \\tparam Allocator The allocator type for allocating memory for internal representation.\n    \n    \\note GenericPointer uses same encoding of ValueType.\n    However, Allocator of GenericPointer is independent of Allocator of Value.\n*/\ntemplate <typename ValueType, typename Allocator = CrtAllocator>\nclass GenericPointer {\npublic:\n    typedef typename ValueType::EncodingType EncodingType;  //!< Encoding type from Value\n    typedef typename ValueType::Ch Ch;                      //!< Character type from Value\n\n    //! A token is the basic units of internal representation.\n    /*!\n        A JSON pointer string representation \"/foo/123\" is parsed to two tokens: \n        \"foo\" and 123. 123 will be represented in both numeric form and string form.\n        They are resolved according to the actual value type (object or array).\n\n        For token that are not numbers, or the numeric value is out of bound\n        (greater than limits of SizeType), they are only treated as string form\n        (i.e. the token's index will be equal to kPointerInvalidIndex).\n\n        This struct is public so that user can create a Pointer without parsing and \n        allocation, using a special constructor.\n    */\n    struct Token {\n        const Ch* name;             //!< Name of the token. It has null character at the end but it can contain null character.\n        SizeType length;            //!< Length of the name.\n        SizeType index;             //!< A valid array index, if it is not equal to kPointerInvalidIndex.\n    };\n\n    //!@name Constructors and destructor.\n    //@{\n\n    //! Default constructor.\n    GenericPointer(Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {}\n\n    //! Constructor that parses a string or URI fragment representation.\n    /*!\n        \\param source A null-terminated, string or URI fragment representation of JSON pointer.\n        \\param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one.\n    */\n    explicit GenericPointer(const Ch* source, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {\n        Parse(source, internal::StrLen(source));\n    }\n\n#if RAPIDJSON_HAS_STDSTRING\n    //! Constructor that parses a string or URI fragment representation.\n    /*!\n        \\param source A string or URI fragment representation of JSON pointer.\n        \\param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one.\n        \\note Requires the definition of the preprocessor symbol \\ref RAPIDJSON_HAS_STDSTRING.\n    */\n    explicit GenericPointer(const std::basic_string<Ch>& source, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {\n        Parse(source.c_str(), source.size());\n    }\n#endif\n\n    //! Constructor that parses a string or URI fragment representation, with length of the source string.\n    /*!\n        \\param source A string or URI fragment representation of JSON pointer.\n        \\param length Length of source.\n        \\param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one.\n        \\note Slightly faster than the overload without length.\n    */\n    GenericPointer(const Ch* source, size_t length, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {\n        Parse(source, length);\n    }\n\n    //! Constructor with user-supplied tokens.\n    /*!\n        This constructor let user supplies const array of tokens.\n        This prevents the parsing process and eliminates allocation.\n        This is preferred for memory constrained environments.\n\n        \\param tokens An constant array of tokens representing the JSON pointer.\n        \\param tokenCount Number of tokens.\n\n        \\b Example\n        \\code\n        #define NAME(s) { s, sizeof(s) / sizeof(s[0]) - 1, kPointerInvalidIndex }\n        #define INDEX(i) { #i, sizeof(#i) - 1, i }\n\n        static const Pointer::Token kTokens[] = { NAME(\"foo\"), INDEX(123) };\n        static const Pointer p(kTokens, sizeof(kTokens) / sizeof(kTokens[0]));\n        // Equivalent to static const Pointer p(\"/foo/123\");\n\n        #undef NAME\n        #undef INDEX\n        \\endcode\n    */\n    GenericPointer(const Token* tokens, size_t tokenCount) : allocator_(), ownAllocator_(), nameBuffer_(), tokens_(const_cast<Token*>(tokens)), tokenCount_(tokenCount), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {}\n\n    //! Copy constructor.\n    GenericPointer(const GenericPointer& rhs, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {\n        *this = rhs;\n    }\n\n    //! Destructor.\n    ~GenericPointer() {\n        if (nameBuffer_)    // If user-supplied tokens constructor is used, nameBuffer_ is nullptr and tokens_ are not deallocated.\n            Allocator::Free(tokens_);\n        RAPIDJSON_DELETE(ownAllocator_);\n    }\n\n    //! Assignment operator.\n    GenericPointer& operator=(const GenericPointer& rhs) {\n        if (this != &rhs) {\n            // Do not delete ownAllcator\n            if (nameBuffer_)\n                Allocator::Free(tokens_);\n\n            tokenCount_ = rhs.tokenCount_;\n            parseErrorOffset_ = rhs.parseErrorOffset_;\n            parseErrorCode_ = rhs.parseErrorCode_;\n\n            if (rhs.nameBuffer_)\n                CopyFromRaw(rhs); // Normally parsed tokens.\n            else {\n                tokens_ = rhs.tokens_; // User supplied const tokens.\n                nameBuffer_ = 0;\n            }\n        }\n        return *this;\n    }\n\n    //@}\n\n    //!@name Append token\n    //@{\n\n    //! Append a token and return a new Pointer\n    /*!\n        \\param token Token to be appended.\n        \\param allocator Allocator for the newly return Pointer.\n        \\return A new Pointer with appended token.\n    */\n    GenericPointer Append(const Token& token, Allocator* allocator = 0) const {\n        GenericPointer r;\n        r.allocator_ = allocator;\n        Ch *p = r.CopyFromRaw(*this, 1, token.length + 1);\n        std::memcpy(p, token.name, (token.length + 1) * sizeof(Ch));\n        r.tokens_[tokenCount_].name = p;\n        r.tokens_[tokenCount_].length = token.length;\n        r.tokens_[tokenCount_].index = token.index;\n        return r;\n    }\n\n    //! Append a name token with length, and return a new Pointer\n    /*!\n        \\param name Name to be appended.\n        \\param length Length of name.\n        \\param allocator Allocator for the newly return Pointer.\n        \\return A new Pointer with appended token.\n    */\n    GenericPointer Append(const Ch* name, SizeType length, Allocator* allocator = 0) const {\n        Token token = { name, length, kPointerInvalidIndex };\n        return Append(token, allocator);\n    }\n\n    //! Append a name token without length, and return a new Pointer\n    /*!\n        \\param name Name (const Ch*) to be appended.\n        \\param allocator Allocator for the newly return Pointer.\n        \\return A new Pointer with appended token.\n    */\n    template <typename T>\n    RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >), (GenericPointer))\n    Append(T* name, Allocator* allocator = 0) const {\n        return Append(name, StrLen(name), allocator);\n    }\n\n#if RAPIDJSON_HAS_STDSTRING\n    //! Append a name token, and return a new Pointer\n    /*!\n        \\param name Name to be appended.\n        \\param allocator Allocator for the newly return Pointer.\n        \\return A new Pointer with appended token.\n    */\n    GenericPointer Append(const std::basic_string<Ch>& name, Allocator* allocator = 0) const {\n        return Append(name.c_str(), static_cast<SizeType>(name.size()), allocator);\n    }\n#endif\n\n    //! Append a index token, and return a new Pointer\n    /*!\n        \\param index Index to be appended.\n        \\param allocator Allocator for the newly return Pointer.\n        \\return A new Pointer with appended token.\n    */\n    GenericPointer Append(SizeType index, Allocator* allocator = 0) const {\n        char buffer[21];\n        char* end = sizeof(SizeType) == 4 ? internal::u32toa(index, buffer) : internal::u64toa(index, buffer);\n        SizeType length = static_cast<SizeType>(end - buffer);\n        buffer[length] = '\\0';\n\n        if (sizeof(Ch) == 1) {\n            Token token = { reinterpret_cast<Ch*>(buffer), length, index };\n            return Append(token, allocator);\n        }\n        else {\n            Ch name[21];\n            for (size_t i = 0; i <= length; i++)\n                name[i] = buffer[i];\n            Token token = { name, length, index };\n            return Append(token, allocator);\n        }\n    }\n\n    //! Append a token by value, and return a new Pointer\n    /*!\n        \\param token token to be appended.\n        \\param allocator Allocator for the newly return Pointer.\n        \\return A new Pointer with appended token.\n    */\n    GenericPointer Append(const ValueType& token, Allocator* allocator = 0) const {\n        if (token.IsString())\n            return Append(token.GetString(), token.GetStringLength(), allocator);\n        else {\n            RAPIDJSON_ASSERT(token.IsUint64());\n            RAPIDJSON_ASSERT(token.GetUint64() <= SizeType(~0));\n            return Append(static_cast<SizeType>(token.GetUint64()), allocator);\n        }\n    }\n\n    //!@name Handling Parse Error\n    //@{\n\n    //! Check whether this is a valid pointer.\n    bool IsValid() const { return parseErrorCode_ == kPointerParseErrorNone; }\n\n    //! Get the parsing error offset in code unit.\n    size_t GetParseErrorOffset() const { return parseErrorOffset_; }\n\n    //! Get the parsing error code.\n    PointerParseErrorCode GetParseErrorCode() const { return parseErrorCode_; }\n\n    //@}\n\n    //! Get the allocator of this pointer.\n    Allocator& GetAllocator() { return *allocator_; }\n\n    //!@name Tokens\n    //@{\n\n    //! Get the token array (const version only).\n    const Token* GetTokens() const { return tokens_; }\n\n    //! Get the number of tokens.\n    size_t GetTokenCount() const { return tokenCount_; }\n\n    //@}\n\n    //!@name Equality/inequality operators\n    //@{\n\n    //! Equality operator.\n    /*!\n        \\note When any pointers are invalid, always returns false.\n    */\n    bool operator==(const GenericPointer& rhs) const {\n        if (!IsValid() || !rhs.IsValid() || tokenCount_ != rhs.tokenCount_)\n            return false;\n\n        for (size_t i = 0; i < tokenCount_; i++) {\n            if (tokens_[i].index != rhs.tokens_[i].index ||\n                tokens_[i].length != rhs.tokens_[i].length || \n                (tokens_[i].length != 0 && std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch)* tokens_[i].length) != 0))\n            {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    //! Inequality operator.\n    /*!\n        \\note When any pointers are invalid, always returns true.\n    */\n    bool operator!=(const GenericPointer& rhs) const { return !(*this == rhs); }\n\n    //@}\n\n    //!@name Stringify\n    //@{\n\n    //! Stringify the pointer into string representation.\n    /*!\n        \\tparam OutputStream Type of output stream.\n        \\param os The output stream.\n    */\n    template<typename OutputStream>\n    bool Stringify(OutputStream& os) const {\n        return Stringify<false, OutputStream>(os);\n    }\n\n    //! Stringify the pointer into URI fragment representation.\n    /*!\n        \\tparam OutputStream Type of output stream.\n        \\param os The output stream.\n    */\n    template<typename OutputStream>\n    bool StringifyUriFragment(OutputStream& os) const {\n        return Stringify<true, OutputStream>(os);\n    }\n\n    //@}\n\n    //!@name Create value\n    //@{\n\n    //! Create a value in a subtree.\n    /*!\n        If the value is not exist, it creates all parent values and a JSON Null value.\n        So it always succeed and return the newly created or existing value.\n\n        Remind that it may change types of parents according to tokens, so it \n        potentially removes previously stored values. For example, if a document \n        was an array, and \"/foo\" is used to create a value, then the document \n        will be changed to an object, and all existing array elements are lost.\n\n        \\param root Root value of a DOM subtree to be resolved. It can be any value other than document root.\n        \\param allocator Allocator for creating the values if the specified value or its parents are not exist.\n        \\param alreadyExist If non-null, it stores whether the resolved value is already exist.\n        \\return The resolved newly created (a JSON Null value), or already exists value.\n    */\n    ValueType& Create(ValueType& root, typename ValueType::AllocatorType& allocator, bool* alreadyExist = 0) const {\n        RAPIDJSON_ASSERT(IsValid());\n        ValueType* v = &root;\n        bool exist = true;\n        for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {\n            if (v->IsArray() && t->name[0] == '-' && t->length == 1) {\n                v->PushBack(ValueType().Move(), allocator);\n                v = &((*v)[v->Size() - 1]);\n                exist = false;\n            }\n            else {\n                if (t->index == kPointerInvalidIndex) { // must be object name\n                    if (!v->IsObject())\n                        v->SetObject(); // Change to Object\n                }\n                else { // object name or array index\n                    if (!v->IsArray() && !v->IsObject())\n                        v->SetArray(); // Change to Array\n                }\n\n                if (v->IsArray()) {\n                    if (t->index >= v->Size()) {\n                        v->Reserve(t->index + 1, allocator);\n                        while (t->index >= v->Size())\n                            v->PushBack(ValueType().Move(), allocator);\n                        exist = false;\n                    }\n                    v = &((*v)[t->index]);\n                }\n                else {\n                    typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));\n                    if (m == v->MemberEnd()) {\n                        v->AddMember(ValueType(t->name, t->length, allocator).Move(), ValueType().Move(), allocator);\n                        v = &(--v->MemberEnd())->value; // Assumes AddMember() appends at the end\n                        exist = false;\n                    }\n                    else\n                        v = &m->value;\n                }\n            }\n        }\n\n        if (alreadyExist)\n            *alreadyExist = exist;\n\n        return *v;\n    }\n\n    //! Creates a value in a document.\n    /*!\n        \\param document A document to be resolved.\n        \\param alreadyExist If non-null, it stores whether the resolved value is already exist.\n        \\return The resolved newly created, or already exists value.\n    */\n    template <typename stackAllocator>\n    ValueType& Create(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, bool* alreadyExist = 0) const {\n        return Create(document, document.GetAllocator(), alreadyExist);\n    }\n\n    //@}\n\n    //!@name Query value\n    //@{\n\n    //! Query a value in a subtree.\n    /*!\n        \\param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.\n        \\param unresolvedTokenIndex If the pointer cannot resolve a token in the pointer, this parameter can obtain the index of unresolved token.\n        \\return Pointer to the value if it can be resolved. Otherwise null.\n\n        \\note\n        There are only 3 situations when a value cannot be resolved:\n        1. A value in the path is not an array nor object.\n        2. An object value does not contain the token.\n        3. A token is out of range of an array value.\n\n        Use unresolvedTokenIndex to retrieve the token index.\n    */\n    ValueType* Get(ValueType& root, size_t* unresolvedTokenIndex = 0) const {\n        RAPIDJSON_ASSERT(IsValid());\n        ValueType* v = &root;\n        for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {\n            switch (v->GetType()) {\n            case kObjectType:\n                {\n                    typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));\n                    if (m == v->MemberEnd())\n                        break;\n                    v = &m->value;\n                }\n                continue;\n            case kArrayType:\n                if (t->index == kPointerInvalidIndex || t->index >= v->Size())\n                    break;\n                v = &((*v)[t->index]);\n                continue;\n            default:\n                break;\n            }\n\n            // Error: unresolved token\n            if (unresolvedTokenIndex)\n                *unresolvedTokenIndex = static_cast<size_t>(t - tokens_);\n            return 0;\n        }\n        return v;\n    }\n\n    //! Query a const value in a const subtree.\n    /*!\n        \\param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.\n        \\return Pointer to the value if it can be resolved. Otherwise null.\n    */\n    const ValueType* Get(const ValueType& root, size_t* unresolvedTokenIndex = 0) const { \n        return Get(const_cast<ValueType&>(root), unresolvedTokenIndex);\n    }\n\n    //@}\n\n    //!@name Query a value with default\n    //@{\n\n    //! Query a value in a subtree with default value.\n    /*!\n        Similar to Get(), but if the specified value do not exists, it creates all parents and clone the default value.\n        So that this function always succeed.\n\n        \\param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.\n        \\param defaultValue Default value to be cloned if the value was not exists.\n        \\param allocator Allocator for creating the values if the specified value or its parents are not exist.\n        \\see Create()\n    */\n    ValueType& GetWithDefault(ValueType& root, const ValueType& defaultValue, typename ValueType::AllocatorType& allocator) const {\n        bool alreadyExist;\n        Value& v = Create(root, allocator, &alreadyExist);\n        return alreadyExist ? v : v.CopyFrom(defaultValue, allocator);\n    }\n\n    //! Query a value in a subtree with default null-terminated string.\n    ValueType& GetWithDefault(ValueType& root, const Ch* defaultValue, typename ValueType::AllocatorType& allocator) const {\n        bool alreadyExist;\n        Value& v = Create(root, allocator, &alreadyExist);\n        return alreadyExist ? v : v.SetString(defaultValue, allocator);\n    }\n\n#if RAPIDJSON_HAS_STDSTRING\n    //! Query a value in a subtree with default std::basic_string.\n    ValueType& GetWithDefault(ValueType& root, const std::basic_string<Ch>& defaultValue, typename ValueType::AllocatorType& allocator) const {\n        bool alreadyExist;\n        Value& v = Create(root, allocator, &alreadyExist);\n        return alreadyExist ? v : v.SetString(defaultValue, allocator);\n    }\n#endif\n\n    //! Query a value in a subtree with default primitive value.\n    /*!\n        \\tparam T Either \\ref Type, \\c int, \\c unsigned, \\c int64_t, \\c uint64_t, \\c bool\n    */\n    template <typename T>\n    RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))\n    GetWithDefault(ValueType& root, T defaultValue, typename ValueType::AllocatorType& allocator) const {\n        return GetWithDefault(root, ValueType(defaultValue).Move(), allocator);\n    }\n\n    //! Query a value in a document with default value.\n    template <typename stackAllocator>\n    ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const ValueType& defaultValue) const {\n        return GetWithDefault(document, defaultValue, document.GetAllocator());\n    }\n\n    //! Query a value in a document with default null-terminated string.\n    template <typename stackAllocator>\n    ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const Ch* defaultValue) const {\n        return GetWithDefault(document, defaultValue, document.GetAllocator());\n    }\n    \n#if RAPIDJSON_HAS_STDSTRING\n    //! Query a value in a document with default std::basic_string.\n    template <typename stackAllocator>\n    ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const std::basic_string<Ch>& defaultValue) const {\n        return GetWithDefault(document, defaultValue, document.GetAllocator());\n    }\n#endif\n\n    //! Query a value in a document with default primitive value.\n    /*!\n        \\tparam T Either \\ref Type, \\c int, \\c unsigned, \\c int64_t, \\c uint64_t, \\c bool\n    */\n    template <typename T, typename stackAllocator>\n    RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))\n    GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, T defaultValue) const {\n        return GetWithDefault(document, defaultValue, document.GetAllocator());\n    }\n\n    //@}\n\n    //!@name Set a value\n    //@{\n\n    //! Set a value in a subtree, with move semantics.\n    /*!\n        It creates all parents if they are not exist or types are different to the tokens.\n        So this function always succeeds but potentially remove existing values.\n\n        \\param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.\n        \\param value Value to be set.\n        \\param allocator Allocator for creating the values if the specified value or its parents are not exist.\n        \\see Create()\n    */\n    ValueType& Set(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const {\n        return Create(root, allocator) = value;\n    }\n\n    //! Set a value in a subtree, with copy semantics.\n    ValueType& Set(ValueType& root, const ValueType& value, typename ValueType::AllocatorType& allocator) const {\n        return Create(root, allocator).CopyFrom(value, allocator);\n    }\n\n    //! Set a null-terminated string in a subtree.\n    ValueType& Set(ValueType& root, const Ch* value, typename ValueType::AllocatorType& allocator) const {\n        return Create(root, allocator) = ValueType(value, allocator).Move();\n    }\n\n#if RAPIDJSON_HAS_STDSTRING\n    //! Set a std::basic_string in a subtree.\n    ValueType& Set(ValueType& root, const std::basic_string<Ch>& value, typename ValueType::AllocatorType& allocator) const {\n        return Create(root, allocator) = ValueType(value, allocator).Move();\n    }\n#endif\n\n    //! Set a primitive value in a subtree.\n    /*!\n        \\tparam T Either \\ref Type, \\c int, \\c unsigned, \\c int64_t, \\c uint64_t, \\c bool\n    */\n    template <typename T>\n    RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))\n    Set(ValueType& root, T value, typename ValueType::AllocatorType& allocator) const {\n        return Create(root, allocator) = ValueType(value).Move();\n    }\n\n    //! Set a value in a document, with move semantics.\n    template <typename stackAllocator>\n    ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, ValueType& value) const {\n        return Create(document) = value;\n    }\n\n    //! Set a value in a document, with copy semantics.\n    template <typename stackAllocator>\n    ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const ValueType& value) const {\n        return Create(document).CopyFrom(value, document.GetAllocator());\n    }\n\n    //! Set a null-terminated string in a document.\n    template <typename stackAllocator>\n    ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const Ch* value) const {\n        return Create(document) = ValueType(value, document.GetAllocator()).Move();\n    }\n\n#if RAPIDJSON_HAS_STDSTRING\n    //! Sets a std::basic_string in a document.\n    template <typename stackAllocator>\n    ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const std::basic_string<Ch>& value) const {\n        return Create(document) = ValueType(value, document.GetAllocator()).Move();\n    }\n#endif\n\n    //! Set a primitive value in a document.\n    /*!\n    \\tparam T Either \\ref Type, \\c int, \\c unsigned, \\c int64_t, \\c uint64_t, \\c bool\n    */\n    template <typename T, typename stackAllocator>\n    RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))\n        Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, T value) const {\n            return Create(document) = value;\n    }\n\n    //@}\n\n    //!@name Swap a value\n    //@{\n\n    //! Swap a value with a value in a subtree.\n    /*!\n        It creates all parents if they are not exist or types are different to the tokens.\n        So this function always succeeds but potentially remove existing values.\n\n        \\param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.\n        \\param value Value to be swapped.\n        \\param allocator Allocator for creating the values if the specified value or its parents are not exist.\n        \\see Create()\n    */\n    ValueType& Swap(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const {\n        return Create(root, allocator).Swap(value);\n    }\n\n    //! Swap a value with a value in a document.\n    template <typename stackAllocator>\n    ValueType& Swap(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, ValueType& value) const {\n        return Create(document).Swap(value);\n    }\n\n    //@}\n\n    //! Erase a value in a subtree.\n    /*!\n        \\param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.\n        \\return Whether the resolved value is found and erased.\n\n        \\note Erasing with an empty pointer \\c Pointer(\"\"), i.e. the root, always fail and return false.\n    */\n    bool Erase(ValueType& root) const {\n        RAPIDJSON_ASSERT(IsValid());\n        if (tokenCount_ == 0) // Cannot erase the root\n            return false;\n\n        ValueType* v = &root;\n        const Token* last = tokens_ + (tokenCount_ - 1);\n        for (const Token *t = tokens_; t != last; ++t) {\n            switch (v->GetType()) {\n            case kObjectType:\n                {\n                    typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));\n                    if (m == v->MemberEnd())\n                        return false;\n                    v = &m->value;\n                }\n                break;\n            case kArrayType:\n                if (t->index == kPointerInvalidIndex || t->index >= v->Size())\n                    return false;\n                v = &((*v)[t->index]);\n                break;\n            default:\n                return false;\n            }\n        }\n\n        switch (v->GetType()) {\n        case kObjectType:\n            return v->EraseMember(GenericStringRef<Ch>(last->name, last->length));\n        case kArrayType:\n            if (last->index == kPointerInvalidIndex || last->index >= v->Size())\n                return false;\n            v->Erase(v->Begin() + last->index);\n            return true;\n        default:\n            return false;\n        }\n    }\n\nprivate:\n    //! Clone the content from rhs to this.\n    /*!\n        \\param rhs Source pointer.\n        \\param extraToken Extra tokens to be allocated.\n        \\param extraNameBufferSize Extra name buffer size (in number of Ch) to be allocated.\n        \\return Start of non-occupied name buffer, for storing extra names.\n    */\n    Ch* CopyFromRaw(const GenericPointer& rhs, size_t extraToken = 0, size_t extraNameBufferSize = 0) {\n        if (!allocator_) // allocator is independently owned.\n            ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator());\n\n        size_t nameBufferSize = rhs.tokenCount_; // null terminators for tokens\n        for (Token *t = rhs.tokens_; t != rhs.tokens_ + rhs.tokenCount_; ++t)\n            nameBufferSize += t->length;\n\n        tokenCount_ = rhs.tokenCount_ + extraToken;\n        tokens_ = static_cast<Token *>(allocator_->Malloc(tokenCount_ * sizeof(Token) + (nameBufferSize + extraNameBufferSize) * sizeof(Ch)));\n        nameBuffer_ = reinterpret_cast<Ch *>(tokens_ + tokenCount_);\n        if (rhs.tokenCount_ > 0) {\n            std::memcpy(tokens_, rhs.tokens_, rhs.tokenCount_ * sizeof(Token));\n        }\n        if (nameBufferSize > 0) {\n            std::memcpy(nameBuffer_, rhs.nameBuffer_, nameBufferSize * sizeof(Ch));\n        }\n\n        // Adjust pointers to name buffer\n        std::ptrdiff_t diff = nameBuffer_ - rhs.nameBuffer_;\n        for (Token *t = tokens_; t != tokens_ + rhs.tokenCount_; ++t)\n            t->name += diff;\n\n        return nameBuffer_ + nameBufferSize;\n    }\n\n    //! Check whether a character should be percent-encoded.\n    /*!\n        According to RFC 3986 2.3 Unreserved Characters.\n        \\param c The character (code unit) to be tested.\n    */\n    bool NeedPercentEncode(Ch c) const {\n        return !((c >= '0' && c <= '9') || (c >= 'A' && c <='Z') || (c >= 'a' && c <= 'z') || c == '-' || c == '.' || c == '_' || c =='~');\n    }\n\n    //! Parse a JSON String or its URI fragment representation into tokens.\n#ifndef __clang__ // -Wdocumentation\n    /*!\n        \\param source Either a JSON Pointer string, or its URI fragment representation. Not need to be null terminated.\n        \\param length Length of the source string.\n        \\note Source cannot be JSON String Representation of JSON Pointer, e.g. In \"/\\u0000\", \\u0000 will not be unescaped.\n    */\n#endif\n    void Parse(const Ch* source, size_t length) {\n        RAPIDJSON_ASSERT(source != NULL);\n        RAPIDJSON_ASSERT(nameBuffer_ == 0);\n        RAPIDJSON_ASSERT(tokens_ == 0);\n\n        // Create own allocator if user did not supply.\n        if (!allocator_)\n            ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator());\n\n        // Count number of '/' as tokenCount\n        tokenCount_ = 0;\n        for (const Ch* s = source; s != source + length; s++) \n            if (*s == '/')\n                tokenCount_++;\n\n        Token* token = tokens_ = static_cast<Token *>(allocator_->Malloc(tokenCount_ * sizeof(Token) + length * sizeof(Ch)));\n        Ch* name = nameBuffer_ = reinterpret_cast<Ch *>(tokens_ + tokenCount_);\n        size_t i = 0;\n\n        // Detect if it is a URI fragment\n        bool uriFragment = false;\n        if (source[i] == '#') {\n            uriFragment = true;\n            i++;\n        }\n\n        if (i != length && source[i] != '/') {\n            parseErrorCode_ = kPointerParseErrorTokenMustBeginWithSolidus;\n            goto error;\n        }\n\n        while (i < length) {\n            RAPIDJSON_ASSERT(source[i] == '/');\n            i++; // consumes '/'\n\n            token->name = name;\n            bool isNumber = true;\n\n            while (i < length && source[i] != '/') {\n                Ch c = source[i];\n                if (uriFragment) {\n                    // Decoding percent-encoding for URI fragment\n                    if (c == '%') {\n                        PercentDecodeStream is(&source[i], source + length);\n                        GenericInsituStringStream<EncodingType> os(name);\n                        Ch* begin = os.PutBegin();\n                        if (!Transcoder<UTF8<>, EncodingType>().Validate(is, os) || !is.IsValid()) {\n                            parseErrorCode_ = kPointerParseErrorInvalidPercentEncoding;\n                            goto error;\n                        }\n                        size_t len = os.PutEnd(begin);\n                        i += is.Tell() - 1;\n                        if (len == 1)\n                            c = *name;\n                        else {\n                            name += len;\n                            isNumber = false;\n                            i++;\n                            continue;\n                        }\n                    }\n                    else if (NeedPercentEncode(c)) {\n                        parseErrorCode_ = kPointerParseErrorCharacterMustPercentEncode;\n                        goto error;\n                    }\n                }\n\n                i++;\n                \n                // Escaping \"~0\" -> '~', \"~1\" -> '/'\n                if (c == '~') {\n                    if (i < length) {\n                        c = source[i];\n                        if (c == '0')       c = '~';\n                        else if (c == '1')  c = '/';\n                        else {\n                            parseErrorCode_ = kPointerParseErrorInvalidEscape;\n                            goto error;\n                        }\n                        i++;\n                    }\n                    else {\n                        parseErrorCode_ = kPointerParseErrorInvalidEscape;\n                        goto error;\n                    }\n                }\n\n                // First check for index: all of characters are digit\n                if (c < '0' || c > '9')\n                    isNumber = false;\n\n                *name++ = c;\n            }\n            token->length = static_cast<SizeType>(name - token->name);\n            if (token->length == 0)\n                isNumber = false;\n            *name++ = '\\0'; // Null terminator\n\n            // Second check for index: more than one digit cannot have leading zero\n            if (isNumber && token->length > 1 && token->name[0] == '0')\n                isNumber = false;\n\n            // String to SizeType conversion\n            SizeType n = 0;\n            if (isNumber) {\n                for (size_t j = 0; j < token->length; j++) {\n                    SizeType m = n * 10 + static_cast<SizeType>(token->name[j] - '0');\n                    if (m < n) {   // overflow detection\n                        isNumber = false;\n                        break;\n                    }\n                    n = m;\n                }\n            }\n\n            token->index = isNumber ? n : kPointerInvalidIndex;\n            token++;\n        }\n\n        RAPIDJSON_ASSERT(name <= nameBuffer_ + length); // Should not overflow buffer\n        parseErrorCode_ = kPointerParseErrorNone;\n        return;\n\n    error:\n        Allocator::Free(tokens_);\n        nameBuffer_ = 0;\n        tokens_ = 0;\n        tokenCount_ = 0;\n        parseErrorOffset_ = i;\n        return;\n    }\n\n    //! Stringify to string or URI fragment representation.\n    /*!\n        \\tparam uriFragment True for stringifying to URI fragment representation. False for string representation.\n        \\tparam OutputStream type of output stream.\n        \\param os The output stream.\n    */\n    template<bool uriFragment, typename OutputStream>\n    bool Stringify(OutputStream& os) const {\n        RAPIDJSON_ASSERT(IsValid());\n\n        if (uriFragment)\n            os.Put('#');\n\n        for (Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {\n            os.Put('/');\n            for (size_t j = 0; j < t->length; j++) {\n                Ch c = t->name[j];\n                if (c == '~') {\n                    os.Put('~');\n                    os.Put('0');\n                }\n                else if (c == '/') {\n                    os.Put('~');\n                    os.Put('1');\n                }\n                else if (uriFragment && NeedPercentEncode(c)) { \n                    // Transcode to UTF8 sequence\n                    GenericStringStream<typename ValueType::EncodingType> source(&t->name[j]);\n                    PercentEncodeStream<OutputStream> target(os);\n                    if (!Transcoder<EncodingType, UTF8<> >().Validate(source, target))\n                        return false;\n                    j += source.Tell() - 1;\n                }\n                else\n                    os.Put(c);\n            }\n        }\n        return true;\n    }\n\n    //! A helper stream for decoding a percent-encoded sequence into code unit.\n    /*!\n        This stream decodes %XY triplet into code unit (0-255).\n        If it encounters invalid characters, it sets output code unit as 0 and \n        mark invalid, and to be checked by IsValid().\n    */\n    class PercentDecodeStream {\n    public:\n        typedef typename ValueType::Ch Ch;\n\n        //! Constructor\n        /*!\n            \\param source Start of the stream\n            \\param end Past-the-end of the stream.\n        */\n        PercentDecodeStream(const Ch* source, const Ch* end) : src_(source), head_(source), end_(end), valid_(true) {}\n\n        Ch Take() {\n            if (*src_ != '%' || src_ + 3 > end_) { // %XY triplet\n                valid_ = false;\n                return 0;\n            }\n            src_++;\n            Ch c = 0;\n            for (int j = 0; j < 2; j++) {\n                c = static_cast<Ch>(c << 4);\n                Ch h = *src_;\n                if      (h >= '0' && h <= '9') c = static_cast<Ch>(c + h - '0');\n                else if (h >= 'A' && h <= 'F') c = static_cast<Ch>(c + h - 'A' + 10);\n                else if (h >= 'a' && h <= 'f') c = static_cast<Ch>(c + h - 'a' + 10);\n                else {\n                    valid_ = false;\n                    return 0;\n                }\n                src_++;\n            }\n            return c;\n        }\n\n        size_t Tell() const { return static_cast<size_t>(src_ - head_); }\n        bool IsValid() const { return valid_; }\n\n    private:\n        const Ch* src_;     //!< Current read position.\n        const Ch* head_;    //!< Original head of the string.\n        const Ch* end_;     //!< Past-the-end position.\n        bool valid_;        //!< Whether the parsing is valid.\n    };\n\n    //! A helper stream to encode character (UTF-8 code unit) into percent-encoded sequence.\n    template <typename OutputStream>\n    class PercentEncodeStream {\n    public:\n        PercentEncodeStream(OutputStream& os) : os_(os) {}\n        void Put(char c) { // UTF-8 must be byte\n            unsigned char u = static_cast<unsigned char>(c);\n            static const char hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };\n            os_.Put('%');\n            os_.Put(hexDigits[u >> 4]);\n            os_.Put(hexDigits[u & 15]);\n        }\n    private:\n        OutputStream& os_;\n    };\n\n    Allocator* allocator_;                  //!< The current allocator. It is either user-supplied or equal to ownAllocator_.\n    Allocator* ownAllocator_;               //!< Allocator owned by this Pointer.\n    Ch* nameBuffer_;                        //!< A buffer containing all names in tokens.\n    Token* tokens_;                         //!< A list of tokens.\n    size_t tokenCount_;                     //!< Number of tokens in tokens_.\n    size_t parseErrorOffset_;               //!< Offset in code unit when parsing fail.\n    PointerParseErrorCode parseErrorCode_;  //!< Parsing error code.\n};\n\n//! GenericPointer for Value (UTF-8, default allocator).\ntypedef GenericPointer<Value> Pointer;\n\n//!@name Helper functions for GenericPointer\n//@{\n\n//////////////////////////////////////////////////////////////////////////////\n\ntemplate <typename T>\ntypename T::ValueType& CreateValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::AllocatorType& a) {\n    return pointer.Create(root, a);\n}\n\ntemplate <typename T, typename CharType, size_t N>\ntypename T::ValueType& CreateValueByPointer(T& root, const CharType(&source)[N], typename T::AllocatorType& a) {\n    return GenericPointer<typename T::ValueType>(source, N - 1).Create(root, a);\n}\n\n// No allocator parameter\n\ntemplate <typename DocumentType>\ntypename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer) {\n    return pointer.Create(document);\n}\n\ntemplate <typename DocumentType, typename CharType, size_t N>\ntypename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const CharType(&source)[N]) {\n    return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Create(document);\n}\n\n//////////////////////////////////////////////////////////////////////////////\n\ntemplate <typename T>\ntypename T::ValueType* GetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, size_t* unresolvedTokenIndex = 0) {\n    return pointer.Get(root, unresolvedTokenIndex);\n}\n\ntemplate <typename T>\nconst typename T::ValueType* GetValueByPointer(const T& root, const GenericPointer<typename T::ValueType>& pointer, size_t* unresolvedTokenIndex = 0) {\n    return pointer.Get(root, unresolvedTokenIndex);\n}\n\ntemplate <typename T, typename CharType, size_t N>\ntypename T::ValueType* GetValueByPointer(T& root, const CharType (&source)[N], size_t* unresolvedTokenIndex = 0) {\n    return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);\n}\n\ntemplate <typename T, typename CharType, size_t N>\nconst typename T::ValueType* GetValueByPointer(const T& root, const CharType(&source)[N], size_t* unresolvedTokenIndex = 0) {\n    return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);\n}\n\n//////////////////////////////////////////////////////////////////////////////\n\ntemplate <typename T>\ntypename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::ValueType& defaultValue, typename T::AllocatorType& a) {\n    return pointer.GetWithDefault(root, defaultValue, a);\n}\n\ntemplate <typename T>\ntypename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::Ch* defaultValue, typename T::AllocatorType& a) {\n    return pointer.GetWithDefault(root, defaultValue, a);\n}\n\n#if RAPIDJSON_HAS_STDSTRING\ntemplate <typename T>\ntypename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const std::basic_string<typename T::Ch>& defaultValue, typename T::AllocatorType& a) {\n    return pointer.GetWithDefault(root, defaultValue, a);\n}\n#endif\n\ntemplate <typename T, typename T2>\nRAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))\nGetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, T2 defaultValue, typename T::AllocatorType& a) {\n    return pointer.GetWithDefault(root, defaultValue, a);\n}\n\ntemplate <typename T, typename CharType, size_t N>\ntypename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::ValueType& defaultValue, typename T::AllocatorType& a) {\n    return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);\n}\n\ntemplate <typename T, typename CharType, size_t N>\ntypename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::Ch* defaultValue, typename T::AllocatorType& a) {\n    return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);\n}\n\n#if RAPIDJSON_HAS_STDSTRING\ntemplate <typename T, typename CharType, size_t N>\ntypename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const std::basic_string<typename T::Ch>& defaultValue, typename T::AllocatorType& a) {\n    return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);\n}\n#endif\n\ntemplate <typename T, typename CharType, size_t N, typename T2>\nRAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))\nGetValueByPointerWithDefault(T& root, const CharType(&source)[N], T2 defaultValue, typename T::AllocatorType& a) {\n    return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);\n}\n\n// No allocator parameter\n\ntemplate <typename DocumentType>\ntypename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::ValueType& defaultValue) {\n    return pointer.GetWithDefault(document, defaultValue);\n}\n\ntemplate <typename DocumentType>\ntypename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::Ch* defaultValue) {\n    return pointer.GetWithDefault(document, defaultValue);\n}\n\n#if RAPIDJSON_HAS_STDSTRING\ntemplate <typename DocumentType>\ntypename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const std::basic_string<typename DocumentType::Ch>& defaultValue) {\n    return pointer.GetWithDefault(document, defaultValue);\n}\n#endif\n\ntemplate <typename DocumentType, typename T2>\nRAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))\nGetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, T2 defaultValue) {\n    return pointer.GetWithDefault(document, defaultValue);\n}\n\ntemplate <typename DocumentType, typename CharType, size_t N>\ntypename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const typename DocumentType::ValueType& defaultValue) {\n    return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);\n}\n\ntemplate <typename DocumentType, typename CharType, size_t N>\ntypename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const typename DocumentType::Ch* defaultValue) {\n    return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);\n}\n\n#if RAPIDJSON_HAS_STDSTRING\ntemplate <typename DocumentType, typename CharType, size_t N>\ntypename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const std::basic_string<typename DocumentType::Ch>& defaultValue) {\n    return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);\n}\n#endif\n\ntemplate <typename DocumentType, typename CharType, size_t N, typename T2>\nRAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))\nGetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], T2 defaultValue) {\n    return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);\n}\n\n//////////////////////////////////////////////////////////////////////////////\n\ntemplate <typename T>\ntypename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::ValueType& value, typename T::AllocatorType& a) {\n    return pointer.Set(root, value, a);\n}\n\ntemplate <typename T>\ntypename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::ValueType& value, typename T::AllocatorType& a) {\n    return pointer.Set(root, value, a);\n}\n\ntemplate <typename T>\ntypename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::Ch* value, typename T::AllocatorType& a) {\n    return pointer.Set(root, value, a);\n}\n\n#if RAPIDJSON_HAS_STDSTRING\ntemplate <typename T>\ntypename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const std::basic_string<typename T::Ch>& value, typename T::AllocatorType& a) {\n    return pointer.Set(root, value, a);\n}\n#endif\n\ntemplate <typename T, typename T2>\nRAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))\nSetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, T2 value, typename T::AllocatorType& a) {\n    return pointer.Set(root, value, a);\n}\n\ntemplate <typename T, typename CharType, size_t N>\ntypename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) {\n    return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);\n}\n\ntemplate <typename T, typename CharType, size_t N>\ntypename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::ValueType& value, typename T::AllocatorType& a) {\n    return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);\n}\n\ntemplate <typename T, typename CharType, size_t N>\ntypename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::Ch* value, typename T::AllocatorType& a) {\n    return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);\n}\n\n#if RAPIDJSON_HAS_STDSTRING\ntemplate <typename T, typename CharType, size_t N>\ntypename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const std::basic_string<typename T::Ch>& value, typename T::AllocatorType& a) {\n    return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);\n}\n#endif\n\ntemplate <typename T, typename CharType, size_t N, typename T2>\nRAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))\nSetValueByPointer(T& root, const CharType(&source)[N], T2 value, typename T::AllocatorType& a) {\n    return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);\n}\n\n// No allocator parameter\n\ntemplate <typename DocumentType>\ntypename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, typename DocumentType::ValueType& value) {\n    return pointer.Set(document, value);\n}\n\ntemplate <typename DocumentType>\ntypename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::ValueType& value) {\n    return pointer.Set(document, value);\n}\n\ntemplate <typename DocumentType>\ntypename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::Ch* value) {\n    return pointer.Set(document, value);\n}\n\n#if RAPIDJSON_HAS_STDSTRING\ntemplate <typename DocumentType>\ntypename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const std::basic_string<typename DocumentType::Ch>& value) {\n    return pointer.Set(document, value);\n}\n#endif\n\ntemplate <typename DocumentType, typename T2>\nRAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))\nSetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, T2 value) {\n    return pointer.Set(document, value);\n}\n\ntemplate <typename DocumentType, typename CharType, size_t N>\ntypename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) {\n    return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);\n}\n\ntemplate <typename DocumentType, typename CharType, size_t N>\ntypename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const typename DocumentType::ValueType& value) {\n    return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);\n}\n\ntemplate <typename DocumentType, typename CharType, size_t N>\ntypename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const typename DocumentType::Ch* value) {\n    return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);\n}\n\n#if RAPIDJSON_HAS_STDSTRING\ntemplate <typename DocumentType, typename CharType, size_t N>\ntypename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const std::basic_string<typename DocumentType::Ch>& value) {\n    return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);\n}\n#endif\n\ntemplate <typename DocumentType, typename CharType, size_t N, typename T2>\nRAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))\nSetValueByPointer(DocumentType& document, const CharType(&source)[N], T2 value) {\n    return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);\n}\n\n//////////////////////////////////////////////////////////////////////////////\n\ntemplate <typename T>\ntypename T::ValueType& SwapValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::ValueType& value, typename T::AllocatorType& a) {\n    return pointer.Swap(root, value, a);\n}\n\ntemplate <typename T, typename CharType, size_t N>\ntypename T::ValueType& SwapValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) {\n    return GenericPointer<typename T::ValueType>(source, N - 1).Swap(root, value, a);\n}\n\ntemplate <typename DocumentType>\ntypename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, typename DocumentType::ValueType& value) {\n    return pointer.Swap(document, value);\n}\n\ntemplate <typename DocumentType, typename CharType, size_t N>\ntypename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) {\n    return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Swap(document, value);\n}\n\n//////////////////////////////////////////////////////////////////////////////\n\ntemplate <typename T>\nbool EraseValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer) {\n    return pointer.Erase(root);\n}\n\ntemplate <typename T, typename CharType, size_t N>\nbool EraseValueByPointer(T& root, const CharType(&source)[N]) {\n    return GenericPointer<typename T::ValueType>(source, N - 1).Erase(root);\n}\n\n//@}\n\nRAPIDJSON_NAMESPACE_END\n\n#ifdef __clang__\nRAPIDJSON_DIAG_POP\n#endif\n\n#ifdef _MSC_VER\nRAPIDJSON_DIAG_POP\n#endif\n\n#endif // RAPIDJSON_POINTER_H_\n"
  },
  {
    "path": "rapidjson/prettywriter.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_PRETTYWRITER_H_\n#define RAPIDJSON_PRETTYWRITER_H_\n\n#include \"writer.h\"\n\n#ifdef __GNUC__\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(effc++)\n#endif\n\n#if defined(__clang__)\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(c++98-compat)\n#endif\n\nRAPIDJSON_NAMESPACE_BEGIN\n\n//! Combination of PrettyWriter format flags.\n/*! \\see PrettyWriter::SetFormatOptions\n */\nenum PrettyFormatOptions {\n    kFormatDefault = 0,         //!< Default pretty formatting.\n    kFormatSingleLineArray = 1  //!< Format arrays on a single line.\n};\n\n//! Writer with indentation and spacing.\n/*!\n    \\tparam OutputStream Type of ouptut os.\n    \\tparam SourceEncoding Encoding of source string.\n    \\tparam TargetEncoding Encoding of output stream.\n    \\tparam StackAllocator Type of allocator for allocating memory of stack.\n*/\ntemplate<typename OutputStream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator, unsigned writeFlags = kWriteDefaultFlags>\nclass PrettyWriter : public Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator, writeFlags> {\npublic:\n    typedef Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator> Base;\n    typedef typename Base::Ch Ch;\n\n    //! Constructor\n    /*! \\param os Output stream.\n        \\param allocator User supplied allocator. If it is null, it will create a private one.\n        \\param levelDepth Initial capacity of stack.\n    */\n    explicit PrettyWriter(OutputStream& os, StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) : \n        Base(os, allocator, levelDepth), indentChar_(' '), indentCharCount_(4), formatOptions_(kFormatDefault) {}\n\n\n    explicit PrettyWriter(StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) : \n        Base(allocator, levelDepth), indentChar_(' '), indentCharCount_(4) {}\n\n#if RAPIDJSON_HAS_CXX11_RVALUE_REFS\n    PrettyWriter(PrettyWriter&& rhs) :\n        Base(std::forward<PrettyWriter>(rhs)), indentChar_(rhs.indentChar_), indentCharCount_(rhs.indentCharCount_), formatOptions_(rhs.formatOptions_) {}\n#endif\n\n    //! Set custom indentation.\n    /*! \\param indentChar       Character for indentation. Must be whitespace character (' ', '\\\\t', '\\\\n', '\\\\r').\n        \\param indentCharCount  Number of indent characters for each indentation level.\n        \\note The default indentation is 4 spaces.\n    */\n    PrettyWriter& SetIndent(Ch indentChar, unsigned indentCharCount) {\n        RAPIDJSON_ASSERT(indentChar == ' ' || indentChar == '\\t' || indentChar == '\\n' || indentChar == '\\r');\n        indentChar_ = indentChar;\n        indentCharCount_ = indentCharCount;\n        return *this;\n    }\n\n    //! Set pretty writer formatting options.\n    /*! \\param options Formatting options.\n    */\n    PrettyWriter& SetFormatOptions(PrettyFormatOptions options) {\n        formatOptions_ = options;\n        return *this;\n    }\n\n    /*! @name Implementation of Handler\n        \\see Handler\n    */\n    //@{\n\n    bool Null()                 { PrettyPrefix(kNullType);   return Base::WriteNull(); }\n    bool Bool(bool b)           { PrettyPrefix(b ? kTrueType : kFalseType); return Base::WriteBool(b); }\n    bool Int(int i)             { PrettyPrefix(kNumberType); return Base::WriteInt(i); }\n    bool Uint(unsigned u)       { PrettyPrefix(kNumberType); return Base::WriteUint(u); }\n    bool Int64(int64_t i64)     { PrettyPrefix(kNumberType); return Base::WriteInt64(i64); }\n    bool Uint64(uint64_t u64)   { PrettyPrefix(kNumberType); return Base::WriteUint64(u64);  }\n    bool Double(double d)       { PrettyPrefix(kNumberType); return Base::WriteDouble(d); }\n\n    bool RawNumber(const Ch* str, SizeType length, bool copy = false) {\n        RAPIDJSON_ASSERT(str != 0);\n        (void)copy;\n        PrettyPrefix(kNumberType);\n        return Base::WriteString(str, length);\n    }\n\n    bool String(const Ch* str, SizeType length, bool copy = false) {\n        RAPIDJSON_ASSERT(str != 0);\n        (void)copy;\n        PrettyPrefix(kStringType);\n        return Base::WriteString(str, length);\n    }\n\n#if RAPIDJSON_HAS_STDSTRING\n    bool String(const std::basic_string<Ch>& str) {\n        return String(str.data(), SizeType(str.size()));\n    }\n#endif\n\n    bool StartObject() {\n        PrettyPrefix(kObjectType);\n        new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(false);\n        return Base::WriteStartObject();\n    }\n\n    bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); }\n\n#if RAPIDJSON_HAS_STDSTRING\n    bool Key(const std::basic_string<Ch>& str) {\n        return Key(str.data(), SizeType(str.size()));\n    }\n#endif\n\t\n    bool EndObject(SizeType memberCount = 0) {\n        (void)memberCount;\n        RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level));\n        RAPIDJSON_ASSERT(!Base::level_stack_.template Top<typename Base::Level>()->inArray);\n        bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0;\n\n        if (!empty) {\n            Base::os_->Put('\\n');\n            WriteIndent();\n        }\n        bool ret = Base::WriteEndObject();\n        (void)ret;\n        RAPIDJSON_ASSERT(ret == true);\n        if (Base::level_stack_.Empty()) // end of json text\n            Base::os_->Flush();\n        return true;\n    }\n\n    bool StartArray() {\n        PrettyPrefix(kArrayType);\n        new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(true);\n        return Base::WriteStartArray();\n    }\n\n    bool EndArray(SizeType memberCount = 0) {\n        (void)memberCount;\n        RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level));\n        RAPIDJSON_ASSERT(Base::level_stack_.template Top<typename Base::Level>()->inArray);\n        bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0;\n\n        if (!empty && !(formatOptions_ & kFormatSingleLineArray)) {\n            Base::os_->Put('\\n');\n            WriteIndent();\n        }\n        bool ret = Base::WriteEndArray();\n        (void)ret;\n        RAPIDJSON_ASSERT(ret == true);\n        if (Base::level_stack_.Empty()) // end of json text\n            Base::os_->Flush();\n        return true;\n    }\n\n    //@}\n\n    /*! @name Convenience extensions */\n    //@{\n\n    //! Simpler but slower overload.\n    bool String(const Ch* str) { return String(str, internal::StrLen(str)); }\n    bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); }\n\n    //@}\n\n    //! Write a raw JSON value.\n    /*!\n        For user to write a stringified JSON as a value.\n\n        \\param json A well-formed JSON value. It should not contain null character within [0, length - 1] range.\n        \\param length Length of the json.\n        \\param type Type of the root of json.\n        \\note When using PrettyWriter::RawValue(), the result json may not be indented correctly.\n    */\n    bool RawValue(const Ch* json, size_t length, Type type) {\n        RAPIDJSON_ASSERT(json != 0);\n        PrettyPrefix(type);\n        return Base::WriteRawValue(json, length);\n    }\n\nprotected:\n    void PrettyPrefix(Type type) {\n        (void)type;\n        if (Base::level_stack_.GetSize() != 0) { // this value is not at root\n            typename Base::Level* level = Base::level_stack_.template Top<typename Base::Level>();\n\n            if (level->inArray) {\n                if (level->valueCount > 0) {\n                    Base::os_->Put(','); // add comma if it is not the first element in array\n                    if (formatOptions_ & kFormatSingleLineArray)\n                        Base::os_->Put(' ');\n                }\n\n                if (!(formatOptions_ & kFormatSingleLineArray)) {\n                    Base::os_->Put('\\n');\n                    WriteIndent();\n                }\n            }\n            else {  // in object\n                if (level->valueCount > 0) {\n                    if (level->valueCount % 2 == 0) {\n                        Base::os_->Put(',');\n                        Base::os_->Put('\\n');\n                    }\n                    else {\n                        Base::os_->Put(':');\n                        Base::os_->Put(' ');\n                    }\n                }\n                else\n                    Base::os_->Put('\\n');\n\n                if (level->valueCount % 2 == 0)\n                    WriteIndent();\n            }\n            if (!level->inArray && level->valueCount % 2 == 0)\n                RAPIDJSON_ASSERT(type == kStringType);  // if it's in object, then even number should be a name\n            level->valueCount++;\n        }\n        else {\n            RAPIDJSON_ASSERT(!Base::hasRoot_);  // Should only has one and only one root.\n            Base::hasRoot_ = true;\n        }\n    }\n\n    void WriteIndent()  {\n        size_t count = (Base::level_stack_.GetSize() / sizeof(typename Base::Level)) * indentCharCount_;\n        PutN(*Base::os_, static_cast<typename TargetEncoding::Ch>(indentChar_), count);\n    }\n\n    Ch indentChar_;\n    unsigned indentCharCount_;\n    PrettyFormatOptions formatOptions_;\n\nprivate:\n    // Prohibit copy constructor & assignment operator.\n    PrettyWriter(const PrettyWriter&);\n    PrettyWriter& operator=(const PrettyWriter&);\n};\n\nRAPIDJSON_NAMESPACE_END\n\n#if defined(__clang__)\nRAPIDJSON_DIAG_POP\n#endif\n\n#ifdef __GNUC__\nRAPIDJSON_DIAG_POP\n#endif\n\n#endif // RAPIDJSON_RAPIDJSON_H_\n"
  },
  {
    "path": "rapidjson/rapidjson.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_RAPIDJSON_H_\n#define RAPIDJSON_RAPIDJSON_H_\n\n/*!\\file rapidjson.h\n    \\brief common definitions and configuration\n    \n    \\see RAPIDJSON_CONFIG\n */\n\n/*! \\defgroup RAPIDJSON_CONFIG RapidJSON configuration\n    \\brief Configuration macros for library features\n\n    Some RapidJSON features are configurable to adapt the library to a wide\n    variety of platforms, environments and usage scenarios.  Most of the\n    features can be configured in terms of overriden or predefined\n    preprocessor macros at compile-time.\n\n    Some additional customization is available in the \\ref RAPIDJSON_ERRORS APIs.\n\n    \\note These macros should be given on the compiler command-line\n          (where applicable)  to avoid inconsistent values when compiling\n          different translation units of a single application.\n */\n\n#include <cstdlib>  // malloc(), realloc(), free(), size_t\n#include <cstring>  // memset(), memcpy(), memmove(), memcmp()\n\n///////////////////////////////////////////////////////////////////////////////\n// RAPIDJSON_VERSION_STRING\n//\n// ALWAYS synchronize the following 3 macros with corresponding variables in /CMakeLists.txt.\n//\n\n//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN\n// token stringification\n#define RAPIDJSON_STRINGIFY(x) RAPIDJSON_DO_STRINGIFY(x)\n#define RAPIDJSON_DO_STRINGIFY(x) #x\n//!@endcond\n\n/*! \\def RAPIDJSON_MAJOR_VERSION\n    \\ingroup RAPIDJSON_CONFIG\n    \\brief Major version of RapidJSON in integer.\n*/\n/*! \\def RAPIDJSON_MINOR_VERSION\n    \\ingroup RAPIDJSON_CONFIG\n    \\brief Minor version of RapidJSON in integer.\n*/\n/*! \\def RAPIDJSON_PATCH_VERSION\n    \\ingroup RAPIDJSON_CONFIG\n    \\brief Patch version of RapidJSON in integer.\n*/\n/*! \\def RAPIDJSON_VERSION_STRING\n    \\ingroup RAPIDJSON_CONFIG\n    \\brief Version of RapidJSON in \"<major>.<minor>.<patch>\" string format.\n*/\n#define RAPIDJSON_MAJOR_VERSION 1\n#define RAPIDJSON_MINOR_VERSION 1\n#define RAPIDJSON_PATCH_VERSION 0\n#define RAPIDJSON_VERSION_STRING \\\n    RAPIDJSON_STRINGIFY(RAPIDJSON_MAJOR_VERSION.RAPIDJSON_MINOR_VERSION.RAPIDJSON_PATCH_VERSION)\n\n///////////////////////////////////////////////////////////////////////////////\n// RAPIDJSON_NAMESPACE_(BEGIN|END)\n/*! \\def RAPIDJSON_NAMESPACE\n    \\ingroup RAPIDJSON_CONFIG\n    \\brief   provide custom rapidjson namespace\n\n    In order to avoid symbol clashes and/or \"One Definition Rule\" errors\n    between multiple inclusions of (different versions of) RapidJSON in\n    a single binary, users can customize the name of the main RapidJSON\n    namespace.\n\n    In case of a single nesting level, defining \\c RAPIDJSON_NAMESPACE\n    to a custom name (e.g. \\c MyRapidJSON) is sufficient.  If multiple\n    levels are needed, both \\ref RAPIDJSON_NAMESPACE_BEGIN and \\ref\n    RAPIDJSON_NAMESPACE_END need to be defined as well:\n\n    \\code\n    // in some .cpp file\n    #define RAPIDJSON_NAMESPACE my::rapidjson\n    #define RAPIDJSON_NAMESPACE_BEGIN namespace my { namespace rapidjson {\n    #define RAPIDJSON_NAMESPACE_END   } }\n    #include \"rapidjson/...\"\n    \\endcode\n\n    \\see rapidjson\n */\n/*! \\def RAPIDJSON_NAMESPACE_BEGIN\n    \\ingroup RAPIDJSON_CONFIG\n    \\brief   provide custom rapidjson namespace (opening expression)\n    \\see RAPIDJSON_NAMESPACE\n*/\n/*! \\def RAPIDJSON_NAMESPACE_END\n    \\ingroup RAPIDJSON_CONFIG\n    \\brief   provide custom rapidjson namespace (closing expression)\n    \\see RAPIDJSON_NAMESPACE\n*/\n#ifndef RAPIDJSON_NAMESPACE\n#define RAPIDJSON_NAMESPACE rapidjson\n#endif\n#ifndef RAPIDJSON_NAMESPACE_BEGIN\n#define RAPIDJSON_NAMESPACE_BEGIN namespace RAPIDJSON_NAMESPACE {\n#endif\n#ifndef RAPIDJSON_NAMESPACE_END\n#define RAPIDJSON_NAMESPACE_END }\n#endif\n\n///////////////////////////////////////////////////////////////////////////////\n// RAPIDJSON_HAS_STDSTRING\n\n#ifndef RAPIDJSON_HAS_STDSTRING\n#ifdef RAPIDJSON_DOXYGEN_RUNNING\n#define RAPIDJSON_HAS_STDSTRING 1 // force generation of documentation\n#else\n#define RAPIDJSON_HAS_STDSTRING 0 // no std::string support by default\n#endif\n/*! \\def RAPIDJSON_HAS_STDSTRING\n    \\ingroup RAPIDJSON_CONFIG\n    \\brief Enable RapidJSON support for \\c std::string\n\n    By defining this preprocessor symbol to \\c 1, several convenience functions for using\n    \\ref rapidjson::GenericValue with \\c std::string are enabled, especially\n    for construction and comparison.\n\n    \\hideinitializer\n*/\n#endif // !defined(RAPIDJSON_HAS_STDSTRING)\n\n#if RAPIDJSON_HAS_STDSTRING\n#include <string>\n#endif // RAPIDJSON_HAS_STDSTRING\n\n///////////////////////////////////////////////////////////////////////////////\n// RAPIDJSON_NO_INT64DEFINE\n\n/*! \\def RAPIDJSON_NO_INT64DEFINE\n    \\ingroup RAPIDJSON_CONFIG\n    \\brief Use external 64-bit integer types.\n\n    RapidJSON requires the 64-bit integer types \\c int64_t and  \\c uint64_t types\n    to be available at global scope.\n\n    If users have their own definition, define RAPIDJSON_NO_INT64DEFINE to\n    prevent RapidJSON from defining its own types.\n*/\n#ifndef RAPIDJSON_NO_INT64DEFINE\n//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN\n#if defined(_MSC_VER) && (_MSC_VER < 1800)\t// Visual Studio 2013\n#include \"msinttypes/stdint.h\"\n#include \"msinttypes/inttypes.h\"\n#else\n// Other compilers should have this.\n#include <stdint.h>\n#include <inttypes.h>\n#endif\n//!@endcond\n#ifdef RAPIDJSON_DOXYGEN_RUNNING\n#define RAPIDJSON_NO_INT64DEFINE\n#endif\n#endif // RAPIDJSON_NO_INT64TYPEDEF\n\n///////////////////////////////////////////////////////////////////////////////\n// RAPIDJSON_FORCEINLINE\n\n#ifndef RAPIDJSON_FORCEINLINE\n//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN\n#if defined(_MSC_VER) && defined(NDEBUG)\n#define RAPIDJSON_FORCEINLINE __forceinline\n#elif defined(__GNUC__) && __GNUC__ >= 4 && defined(NDEBUG)\n#define RAPIDJSON_FORCEINLINE __attribute__((always_inline))\n#else\n#define RAPIDJSON_FORCEINLINE\n#endif\n//!@endcond\n#endif // RAPIDJSON_FORCEINLINE\n\n///////////////////////////////////////////////////////////////////////////////\n// RAPIDJSON_ENDIAN\n#define RAPIDJSON_LITTLEENDIAN  0   //!< Little endian machine\n#define RAPIDJSON_BIGENDIAN     1   //!< Big endian machine\n\n//! Endianness of the machine.\n/*!\n    \\def RAPIDJSON_ENDIAN\n    \\ingroup RAPIDJSON_CONFIG\n\n    GCC 4.6 provided macro for detecting endianness of the target machine. But other\n    compilers may not have this. User can define RAPIDJSON_ENDIAN to either\n    \\ref RAPIDJSON_LITTLEENDIAN or \\ref RAPIDJSON_BIGENDIAN.\n\n    Default detection implemented with reference to\n    \\li https://gcc.gnu.org/onlinedocs/gcc-4.6.0/cpp/Common-Predefined-Macros.html\n    \\li http://www.boost.org/doc/libs/1_42_0/boost/detail/endian.hpp\n*/\n#ifndef RAPIDJSON_ENDIAN\n// Detect with GCC 4.6's macro\n#  ifdef __BYTE_ORDER__\n#    if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__\n#      define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN\n#    elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__\n#      define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN\n#    else\n#      error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN.\n#    endif // __BYTE_ORDER__\n// Detect with GLIBC's endian.h\n#  elif defined(__GLIBC__)\n#    include <endian.h>\n#    if (__BYTE_ORDER == __LITTLE_ENDIAN)\n#      define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN\n#    elif (__BYTE_ORDER == __BIG_ENDIAN)\n#      define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN\n#    else\n#      error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN.\n#   endif // __GLIBC__\n// Detect with _LITTLE_ENDIAN and _BIG_ENDIAN macro\n#  elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)\n#    define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN\n#  elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)\n#    define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN\n// Detect with architecture macros\n#  elif defined(__sparc) || defined(__sparc__) || defined(_POWER) || defined(__powerpc__) || defined(__ppc__) || defined(__hpux) || defined(__hppa) || defined(_MIPSEB) || defined(_POWER) || defined(__s390__)\n#    define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN\n#  elif defined(__i386__) || defined(__alpha__) || defined(__ia64) || defined(__ia64__) || defined(_M_IX86) || defined(_M_IA64) || defined(_M_ALPHA) || defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || defined(__bfin__)\n#    define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN\n#  elif defined(_MSC_VER) && defined(_M_ARM)\n#    define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN\n#  elif defined(RAPIDJSON_DOXYGEN_RUNNING)\n#    define RAPIDJSON_ENDIAN\n#  else\n#    error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN.   \n#  endif\n#endif // RAPIDJSON_ENDIAN\n\n///////////////////////////////////////////////////////////////////////////////\n// RAPIDJSON_64BIT\n\n//! Whether using 64-bit architecture\n#ifndef RAPIDJSON_64BIT\n#if defined(__LP64__) || (defined(__x86_64__) && defined(__ILP32__)) || defined(_WIN64) || defined(__EMSCRIPTEN__)\n#define RAPIDJSON_64BIT 1\n#else\n#define RAPIDJSON_64BIT 0\n#endif\n#endif // RAPIDJSON_64BIT\n\n///////////////////////////////////////////////////////////////////////////////\n// RAPIDJSON_ALIGN\n\n//! Data alignment of the machine.\n/*! \\ingroup RAPIDJSON_CONFIG\n    \\param x pointer to align\n\n    Some machines require strict data alignment. Currently the default uses 4 bytes\n    alignment on 32-bit platforms and 8 bytes alignment for 64-bit platforms.\n    User can customize by defining the RAPIDJSON_ALIGN function macro.\n*/\n#ifndef RAPIDJSON_ALIGN\n#if RAPIDJSON_64BIT == 1\n#define RAPIDJSON_ALIGN(x) (((x) + static_cast<uint64_t>(7u)) & ~static_cast<uint64_t>(7u))\n#else\n#define RAPIDJSON_ALIGN(x) (((x) + 3u) & ~3u)\n#endif\n#endif\n\n///////////////////////////////////////////////////////////////////////////////\n// RAPIDJSON_UINT64_C2\n\n//! Construct a 64-bit literal by a pair of 32-bit integer.\n/*!\n    64-bit literal with or without ULL suffix is prone to compiler warnings.\n    UINT64_C() is C macro which cause compilation problems.\n    Use this macro to define 64-bit constants by a pair of 32-bit integer.\n*/\n#ifndef RAPIDJSON_UINT64_C2\n#define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast<uint64_t>(high32) << 32) | static_cast<uint64_t>(low32))\n#endif\n\n///////////////////////////////////////////////////////////////////////////////\n// RAPIDJSON_48BITPOINTER_OPTIMIZATION\n\n//! Use only lower 48-bit address for some pointers.\n/*!\n    \\ingroup RAPIDJSON_CONFIG\n\n    This optimization uses the fact that current X86-64 architecture only implement lower 48-bit virtual address.\n    The higher 16-bit can be used for storing other data.\n    \\c GenericValue uses this optimization to reduce its size form 24 bytes to 16 bytes in 64-bit architecture.\n*/\n#ifndef RAPIDJSON_48BITPOINTER_OPTIMIZATION\n#if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64)\n#define RAPIDJSON_48BITPOINTER_OPTIMIZATION 1\n#else\n#define RAPIDJSON_48BITPOINTER_OPTIMIZATION 0\n#endif\n#endif // RAPIDJSON_48BITPOINTER_OPTIMIZATION\n\n#if RAPIDJSON_48BITPOINTER_OPTIMIZATION == 1\n#if RAPIDJSON_64BIT != 1\n#error RAPIDJSON_48BITPOINTER_OPTIMIZATION can only be set to 1 when RAPIDJSON_64BIT=1\n#endif\n#define RAPIDJSON_SETPOINTER(type, p, x) (p = reinterpret_cast<type *>((reinterpret_cast<uintptr_t>(p) & static_cast<uintptr_t>(RAPIDJSON_UINT64_C2(0xFFFF0000, 0x00000000))) | reinterpret_cast<uintptr_t>(reinterpret_cast<const void*>(x))))\n#define RAPIDJSON_GETPOINTER(type, p) (reinterpret_cast<type *>(reinterpret_cast<uintptr_t>(p) & static_cast<uintptr_t>(RAPIDJSON_UINT64_C2(0x0000FFFF, 0xFFFFFFFF))))\n#else\n#define RAPIDJSON_SETPOINTER(type, p, x) (p = (x))\n#define RAPIDJSON_GETPOINTER(type, p) (p)\n#endif\n\n///////////////////////////////////////////////////////////////////////////////\n// RAPIDJSON_SSE2/RAPIDJSON_SSE42/RAPIDJSON_SIMD\n\n/*! \\def RAPIDJSON_SIMD\n    \\ingroup RAPIDJSON_CONFIG\n    \\brief Enable SSE2/SSE4.2 optimization.\n\n    RapidJSON supports optimized implementations for some parsing operations\n    based on the SSE2 or SSE4.2 SIMD extensions on modern Intel-compatible\n    processors.\n\n    To enable these optimizations, two different symbols can be defined;\n    \\code\n    // Enable SSE2 optimization.\n    #define RAPIDJSON_SSE2\n\n    // Enable SSE4.2 optimization.\n    #define RAPIDJSON_SSE42\n    \\endcode\n\n    \\c RAPIDJSON_SSE42 takes precedence, if both are defined.\n\n    If any of these symbols is defined, RapidJSON defines the macro\n    \\c RAPIDJSON_SIMD to indicate the availability of the optimized code.\n*/\n#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) \\\n    || defined(RAPIDJSON_DOXYGEN_RUNNING)\n#define RAPIDJSON_SIMD\n#endif\n\n///////////////////////////////////////////////////////////////////////////////\n// RAPIDJSON_NO_SIZETYPEDEFINE\n\n#ifndef RAPIDJSON_NO_SIZETYPEDEFINE\n/*! \\def RAPIDJSON_NO_SIZETYPEDEFINE\n    \\ingroup RAPIDJSON_CONFIG\n    \\brief User-provided \\c SizeType definition.\n\n    In order to avoid using 32-bit size types for indexing strings and arrays,\n    define this preprocessor symbol and provide the type rapidjson::SizeType\n    before including RapidJSON:\n    \\code\n    #define RAPIDJSON_NO_SIZETYPEDEFINE\n    namespace rapidjson { typedef ::std::size_t SizeType; }\n    #include \"rapidjson/...\"\n    \\endcode\n\n    \\see rapidjson::SizeType\n*/\n#ifdef RAPIDJSON_DOXYGEN_RUNNING\n#define RAPIDJSON_NO_SIZETYPEDEFINE\n#endif\nRAPIDJSON_NAMESPACE_BEGIN\n//! Size type (for string lengths, array sizes, etc.)\n/*! RapidJSON uses 32-bit array/string indices even on 64-bit platforms,\n    instead of using \\c size_t. Users may override the SizeType by defining\n    \\ref RAPIDJSON_NO_SIZETYPEDEFINE.\n*/\ntypedef unsigned SizeType;\nRAPIDJSON_NAMESPACE_END\n#endif\n\n// always import std::size_t to rapidjson namespace\nRAPIDJSON_NAMESPACE_BEGIN\nusing std::size_t;\nRAPIDJSON_NAMESPACE_END\n\n///////////////////////////////////////////////////////////////////////////////\n// RAPIDJSON_ASSERT\n\n//! Assertion.\n/*! \\ingroup RAPIDJSON_CONFIG\n    By default, rapidjson uses C \\c assert() for internal assertions.\n    User can override it by defining RAPIDJSON_ASSERT(x) macro.\n\n    \\note Parsing errors are handled and can be customized by the\n          \\ref RAPIDJSON_ERRORS APIs.\n*/\n#ifndef RAPIDJSON_ASSERT\n#include <cassert>\n#define RAPIDJSON_ASSERT(x) assert(x)\n#endif // RAPIDJSON_ASSERT\n\n///////////////////////////////////////////////////////////////////////////////\n// RAPIDJSON_STATIC_ASSERT\n\n// Adopt from boost\n#ifndef RAPIDJSON_STATIC_ASSERT\n#ifndef __clang__\n//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN\n#endif\nRAPIDJSON_NAMESPACE_BEGIN\ntemplate <bool x> struct STATIC_ASSERTION_FAILURE;\ntemplate <> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; };\ntemplate<int x> struct StaticAssertTest {};\nRAPIDJSON_NAMESPACE_END\n\n#define RAPIDJSON_JOIN(X, Y) RAPIDJSON_DO_JOIN(X, Y)\n#define RAPIDJSON_DO_JOIN(X, Y) RAPIDJSON_DO_JOIN2(X, Y)\n#define RAPIDJSON_DO_JOIN2(X, Y) X##Y\n\n#if defined(__GNUC__)\n#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE __attribute__((unused))\n#else\n#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE \n#endif\n#ifndef __clang__\n//!@endcond\n#endif\n\n/*! \\def RAPIDJSON_STATIC_ASSERT\n    \\brief (Internal) macro to check for conditions at compile-time\n    \\param x compile-time condition\n    \\hideinitializer\n */\n#define RAPIDJSON_STATIC_ASSERT(x) \\\n    typedef ::RAPIDJSON_NAMESPACE::StaticAssertTest< \\\n      sizeof(::RAPIDJSON_NAMESPACE::STATIC_ASSERTION_FAILURE<bool(x) >)> \\\n    RAPIDJSON_JOIN(StaticAssertTypedef, __LINE__) RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE\n#endif\n\n///////////////////////////////////////////////////////////////////////////////\n// RAPIDJSON_LIKELY, RAPIDJSON_UNLIKELY\n\n//! Compiler branching hint for expression with high probability to be true.\n/*!\n    \\ingroup RAPIDJSON_CONFIG\n    \\param x Boolean expression likely to be true.\n*/\n#ifndef RAPIDJSON_LIKELY\n#if defined(__GNUC__) || defined(__clang__)\n#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)\n#else\n#define RAPIDJSON_LIKELY(x) (x)\n#endif\n#endif\n\n//! Compiler branching hint for expression with low probability to be true.\n/*!\n    \\ingroup RAPIDJSON_CONFIG\n    \\param x Boolean expression unlikely to be true.\n*/\n#ifndef RAPIDJSON_UNLIKELY\n#if defined(__GNUC__) || defined(__clang__)\n#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)\n#else\n#define RAPIDJSON_UNLIKELY(x) (x)\n#endif\n#endif\n\n///////////////////////////////////////////////////////////////////////////////\n// Helpers\n\n//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN\n\n#define RAPIDJSON_MULTILINEMACRO_BEGIN do {  \n#define RAPIDJSON_MULTILINEMACRO_END \\\n} while((void)0, 0)\n\n// adopted from Boost\n#define RAPIDJSON_VERSION_CODE(x,y,z) \\\n  (((x)*100000) + ((y)*100) + (z))\n\n///////////////////////////////////////////////////////////////////////////////\n// RAPIDJSON_DIAG_PUSH/POP, RAPIDJSON_DIAG_OFF\n\n#if defined(__GNUC__)\n#define RAPIDJSON_GNUC \\\n    RAPIDJSON_VERSION_CODE(__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__)\n#endif\n\n#if defined(__clang__) || (defined(RAPIDJSON_GNUC) && RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,2,0))\n\n#define RAPIDJSON_PRAGMA(x) _Pragma(RAPIDJSON_STRINGIFY(x))\n#define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(GCC diagnostic x)\n#define RAPIDJSON_DIAG_OFF(x) \\\n    RAPIDJSON_DIAG_PRAGMA(ignored RAPIDJSON_STRINGIFY(RAPIDJSON_JOIN(-W,x)))\n\n// push/pop support in Clang and GCC>=4.6\n#if defined(__clang__) || (defined(RAPIDJSON_GNUC) && RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0))\n#define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push)\n#define RAPIDJSON_DIAG_POP  RAPIDJSON_DIAG_PRAGMA(pop)\n#else // GCC >= 4.2, < 4.6\n#define RAPIDJSON_DIAG_PUSH /* ignored */\n#define RAPIDJSON_DIAG_POP /* ignored */\n#endif\n\n#elif defined(_MSC_VER)\n\n// pragma (MSVC specific)\n#define RAPIDJSON_PRAGMA(x) __pragma(x)\n#define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(warning(x))\n\n#define RAPIDJSON_DIAG_OFF(x) RAPIDJSON_DIAG_PRAGMA(disable: x)\n#define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push)\n#define RAPIDJSON_DIAG_POP  RAPIDJSON_DIAG_PRAGMA(pop)\n\n#else\n\n#define RAPIDJSON_DIAG_OFF(x) /* ignored */\n#define RAPIDJSON_DIAG_PUSH   /* ignored */\n#define RAPIDJSON_DIAG_POP    /* ignored */\n\n#endif // RAPIDJSON_DIAG_*\n\n///////////////////////////////////////////////////////////////////////////////\n// C++11 features\n\n#ifndef RAPIDJSON_HAS_CXX11_RVALUE_REFS\n#if defined(__clang__)\n#if __has_feature(cxx_rvalue_references) && \\\n    (defined(_LIBCPP_VERSION) || defined(__GLIBCXX__) && __GLIBCXX__ >= 20080306)\n#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1\n#else\n#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 0\n#endif\n#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,3,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \\\n      (defined(_MSC_VER) && _MSC_VER >= 1600)\n\n#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1\n#else\n#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 0\n#endif\n#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS\n\n#ifndef RAPIDJSON_HAS_CXX11_NOEXCEPT\n#if defined(__clang__)\n#define RAPIDJSON_HAS_CXX11_NOEXCEPT __has_feature(cxx_noexcept)\n#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__))\n//    (defined(_MSC_VER) && _MSC_VER >= ????) // not yet supported\n#define RAPIDJSON_HAS_CXX11_NOEXCEPT 1\n#else\n#define RAPIDJSON_HAS_CXX11_NOEXCEPT 0\n#endif\n#endif\n#if RAPIDJSON_HAS_CXX11_NOEXCEPT\n#define RAPIDJSON_NOEXCEPT noexcept\n#else\n#define RAPIDJSON_NOEXCEPT /* noexcept */\n#endif // RAPIDJSON_HAS_CXX11_NOEXCEPT\n\n// no automatic detection, yet\n#ifndef RAPIDJSON_HAS_CXX11_TYPETRAITS\n#define RAPIDJSON_HAS_CXX11_TYPETRAITS 0\n#endif\n\n#ifndef RAPIDJSON_HAS_CXX11_RANGE_FOR\n#if defined(__clang__)\n#define RAPIDJSON_HAS_CXX11_RANGE_FOR __has_feature(cxx_range_for)\n#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,3,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \\\n      (defined(_MSC_VER) && _MSC_VER >= 1700)\n#define RAPIDJSON_HAS_CXX11_RANGE_FOR 1\n#else\n#define RAPIDJSON_HAS_CXX11_RANGE_FOR 0\n#endif\n#endif // RAPIDJSON_HAS_CXX11_RANGE_FOR\n\n//!@endcond\n\n///////////////////////////////////////////////////////////////////////////////\n// new/delete\n\n#ifndef RAPIDJSON_NEW\n///! customization point for global \\c new\n#define RAPIDJSON_NEW(x) new x\n#endif\n#ifndef RAPIDJSON_DELETE\n///! customization point for global \\c delete\n#define RAPIDJSON_DELETE(x) delete x\n#endif\n\n///////////////////////////////////////////////////////////////////////////////\n// Type\n\n/*! \\namespace rapidjson\n    \\brief main RapidJSON namespace\n    \\see RAPIDJSON_NAMESPACE\n*/\nRAPIDJSON_NAMESPACE_BEGIN\n\n//! Type of JSON value\nenum Type {\n    kNullType = 0,      //!< null\n    kFalseType = 1,     //!< false\n    kTrueType = 2,      //!< true\n    kObjectType = 3,    //!< object\n    kArrayType = 4,     //!< array \n    kStringType = 5,    //!< string\n    kNumberType = 6     //!< number\n};\n\nRAPIDJSON_NAMESPACE_END\n\n#endif // RAPIDJSON_RAPIDJSON_H_\n"
  },
  {
    "path": "rapidjson/reader.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n//\n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_READER_H_\n#define RAPIDJSON_READER_H_\n\n/*! \\file reader.h */\n\n#include \"allocators.h\"\n#include \"stream.h\"\n#include \"encodedstream.h\"\n#include \"internal/meta.h\"\n#include \"internal/stack.h\"\n#include \"internal/strtod.h\"\n#include <limits>\n\n#if defined(RAPIDJSON_SIMD) && defined(_MSC_VER)\n#include <intrin.h>\n#pragma intrinsic(_BitScanForward)\n#endif\n#ifdef RAPIDJSON_SSE42\n#include <nmmintrin.h>\n#elif defined(RAPIDJSON_SSE2)\n#include <emmintrin.h>\n#endif\n\n#ifdef _MSC_VER\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(4127)  // conditional expression is constant\nRAPIDJSON_DIAG_OFF(4702)  // unreachable code\n#endif\n\n#ifdef __clang__\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(old-style-cast)\nRAPIDJSON_DIAG_OFF(padded)\nRAPIDJSON_DIAG_OFF(switch-enum)\n#endif\n\n#ifdef __GNUC__\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(effc++)\n#endif\n\n//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN\n#define RAPIDJSON_NOTHING /* deliberately empty */\n#ifndef RAPIDJSON_PARSE_ERROR_EARLY_RETURN\n#define RAPIDJSON_PARSE_ERROR_EARLY_RETURN(value) \\\n    RAPIDJSON_MULTILINEMACRO_BEGIN \\\n    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \\\n    RAPIDJSON_MULTILINEMACRO_END\n#endif\n#define RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID \\\n    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)\n//!@endcond\n\n/*! \\def RAPIDJSON_PARSE_ERROR_NORETURN\n    \\ingroup RAPIDJSON_ERRORS\n    \\brief Macro to indicate a parse error.\n    \\param parseErrorCode \\ref rapidjson::ParseErrorCode of the error\n    \\param offset  position of the error in JSON input (\\c size_t)\n\n    This macros can be used as a customization point for the internal\n    error handling mechanism of RapidJSON.\n\n    A common usage model is to throw an exception instead of requiring the\n    caller to explicitly check the \\ref rapidjson::GenericReader::Parse's\n    return value:\n\n    \\code\n    #define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode,offset) \\\n       throw ParseException(parseErrorCode, #parseErrorCode, offset)\n\n    #include <stdexcept>               // std::runtime_error\n    #include \"rapidjson/error/error.h\" // rapidjson::ParseResult\n\n    struct ParseException : std::runtime_error, rapidjson::ParseResult {\n      ParseException(rapidjson::ParseErrorCode code, const char* msg, size_t offset)\n        : std::runtime_error(msg), ParseResult(code, offset) {}\n    };\n\n    #include \"rapidjson/reader.h\"\n    \\endcode\n\n    \\see RAPIDJSON_PARSE_ERROR, rapidjson::GenericReader::Parse\n */\n#ifndef RAPIDJSON_PARSE_ERROR_NORETURN\n#define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset) \\\n    RAPIDJSON_MULTILINEMACRO_BEGIN \\\n    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \\\n    SetParseError(parseErrorCode, offset); \\\n    RAPIDJSON_MULTILINEMACRO_END\n#endif\n\n/*! \\def RAPIDJSON_PARSE_ERROR\n    \\ingroup RAPIDJSON_ERRORS\n    \\brief (Internal) macro to indicate and handle a parse error.\n    \\param parseErrorCode \\ref rapidjson::ParseErrorCode of the error\n    \\param offset  position of the error in JSON input (\\c size_t)\n\n    Invokes RAPIDJSON_PARSE_ERROR_NORETURN and stops the parsing.\n\n    \\see RAPIDJSON_PARSE_ERROR_NORETURN\n    \\hideinitializer\n */\n#ifndef RAPIDJSON_PARSE_ERROR\n#define RAPIDJSON_PARSE_ERROR(parseErrorCode, offset) \\\n    RAPIDJSON_MULTILINEMACRO_BEGIN \\\n    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \\\n    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \\\n    RAPIDJSON_MULTILINEMACRO_END\n#endif\n\n#include \"error/error.h\" // ParseErrorCode, ParseResult\n\nRAPIDJSON_NAMESPACE_BEGIN\n\n///////////////////////////////////////////////////////////////////////////////\n// ParseFlag\n\n/*! \\def RAPIDJSON_PARSE_DEFAULT_FLAGS\n    \\ingroup RAPIDJSON_CONFIG\n    \\brief User-defined kParseDefaultFlags definition.\n\n    User can define this as any \\c ParseFlag combinations.\n*/\n#ifndef RAPIDJSON_PARSE_DEFAULT_FLAGS\n#define RAPIDJSON_PARSE_DEFAULT_FLAGS kParseNoFlags\n#endif\n\n//! Combination of parseFlags\n/*! \\see Reader::Parse, Document::Parse, Document::ParseInsitu, Document::ParseStream\n */\nenum ParseFlag {\n    kParseNoFlags = 0,              //!< No flags are set.\n    kParseInsituFlag = 1,           //!< In-situ(destructive) parsing.\n    kParseValidateEncodingFlag = 2, //!< Validate encoding of JSON strings.\n    kParseIterativeFlag = 4,        //!< Iterative(constant complexity in terms of function call stack size) parsing.\n    kParseStopWhenDoneFlag = 8,     //!< After parsing a complete JSON root from stream, stop further processing the rest of stream. When this flag is used, parser will not generate kParseErrorDocumentRootNotSingular error.\n    kParseFullPrecisionFlag = 16,   //!< Parse number in full precision (but slower).\n    kParseCommentsFlag = 32,        //!< Allow one-line (//) and multi-line (/**/) comments.\n    kParseNumbersAsStringsFlag = 64,    //!< Parse all numbers (ints/doubles) as strings.\n    kParseTrailingCommasFlag = 128, //!< Allow trailing commas at the end of objects and arrays.\n    kParseNanAndInfFlag = 256,      //!< Allow parsing NaN, Inf, Infinity, -Inf and -Infinity as doubles.\n    kParseDefaultFlags = RAPIDJSON_PARSE_DEFAULT_FLAGS  //!< Default parse flags. Can be customized by defining RAPIDJSON_PARSE_DEFAULT_FLAGS\n};\n\n///////////////////////////////////////////////////////////////////////////////\n// Handler\n\n/*! \\class rapidjson::Handler\n    \\brief Concept for receiving events from GenericReader upon parsing.\n    The functions return true if no error occurs. If they return false,\n    the event publisher should terminate the process.\n\\code\nconcept Handler {\n    typename Ch;\n\n    bool Null();\n    bool Bool(bool b);\n    bool Int(int i);\n    bool Uint(unsigned i);\n    bool Int64(int64_t i);\n    bool Uint64(uint64_t i);\n    bool Double(double d);\n    /// enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use length)\n    bool RawNumber(const Ch* str, SizeType length, bool copy);\n    bool String(const Ch* str, SizeType length, bool copy);\n    bool StartObject();\n    bool Key(const Ch* str, SizeType length, bool copy);\n    bool EndObject(SizeType memberCount);\n    bool StartArray();\n    bool EndArray(SizeType elementCount);\n};\n\\endcode\n*/\n///////////////////////////////////////////////////////////////////////////////\n// BaseReaderHandler\n\n//! Default implementation of Handler.\n/*! This can be used as base class of any reader handler.\n    \\note implements Handler concept\n*/\ntemplate<typename Encoding = UTF8<>, typename Derived = void>\nstruct BaseReaderHandler {\n    typedef typename Encoding::Ch Ch;\n\n    typedef typename internal::SelectIf<internal::IsSame<Derived, void>, BaseReaderHandler, Derived>::Type Override;\n\n    bool Default() { return true; }\n    bool Null() { return static_cast<Override&>(*this).Default(); }\n    bool Bool(bool) { return static_cast<Override&>(*this).Default(); }\n    bool Int(int) { return static_cast<Override&>(*this).Default(); }\n    bool Uint(unsigned) { return static_cast<Override&>(*this).Default(); }\n    bool Int64(int64_t) { return static_cast<Override&>(*this).Default(); }\n    bool Uint64(uint64_t) { return static_cast<Override&>(*this).Default(); }\n    bool Double(double) { return static_cast<Override&>(*this).Default(); }\n    /// enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use length)\n    bool RawNumber(const Ch* str, SizeType len, bool copy) { return static_cast<Override&>(*this).String(str, len, copy); }\n    bool String(const Ch*, SizeType, bool) { return static_cast<Override&>(*this).Default(); }\n    bool StartObject() { return static_cast<Override&>(*this).Default(); }\n    bool Key(const Ch* str, SizeType len, bool copy) { return static_cast<Override&>(*this).String(str, len, copy); }\n    bool EndObject(SizeType) { return static_cast<Override&>(*this).Default(); }\n    bool StartArray() { return static_cast<Override&>(*this).Default(); }\n    bool EndArray(SizeType) { return static_cast<Override&>(*this).Default(); }\n};\n\n///////////////////////////////////////////////////////////////////////////////\n// StreamLocalCopy\n\nnamespace internal {\n\ntemplate<typename Stream, int = StreamTraits<Stream>::copyOptimization>\nclass StreamLocalCopy;\n\n//! Do copy optimization.\ntemplate<typename Stream>\nclass StreamLocalCopy<Stream, 1> {\npublic:\n    StreamLocalCopy(Stream& original) : s(original), original_(original) {}\n    ~StreamLocalCopy() { original_ = s; }\n\n    Stream s;\n\nprivate:\n    StreamLocalCopy& operator=(const StreamLocalCopy&) /* = delete */;\n\n    Stream& original_;\n};\n\n//! Keep reference.\ntemplate<typename Stream>\nclass StreamLocalCopy<Stream, 0> {\npublic:\n    StreamLocalCopy(Stream& original) : s(original) {}\n\n    Stream& s;\n\nprivate:\n    StreamLocalCopy& operator=(const StreamLocalCopy&) /* = delete */;\n};\n\n} // namespace internal\n\n///////////////////////////////////////////////////////////////////////////////\n// SkipWhitespace\n\n//! Skip the JSON white spaces in a stream.\n/*! \\param is A input stream for skipping white spaces.\n    \\note This function has SSE2/SSE4.2 specialization.\n*/\ntemplate<typename InputStream>\nvoid SkipWhitespace(InputStream& is) {\n    internal::StreamLocalCopy<InputStream> copy(is);\n    InputStream& s(copy.s);\n\n    typename InputStream::Ch c;\n    while ((c = s.Peek()) == ' ' || c == '\\n' || c == '\\r' || c == '\\t')\n        s.Take();\n}\n\ninline const char* SkipWhitespace(const char* p, const char* end) {\n    while (p != end && (*p == ' ' || *p == '\\n' || *p == '\\r' || *p == '\\t'))\n        ++p;\n    return p;\n}\n\n#ifdef RAPIDJSON_SSE42\n//! Skip whitespace with SSE 4.2 pcmpistrm instruction, testing 16 8-byte characters at once.\ninline const char *SkipWhitespace_SIMD(const char* p) {\n    // Fast return for single non-whitespace\n    if (*p == ' ' || *p == '\\n' || *p == '\\r' || *p == '\\t')\n        ++p;\n    else\n        return p;\n\n    // 16-byte align to the next boundary\n    const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));\n    while (p != nextAligned)\n        if (*p == ' ' || *p == '\\n' || *p == '\\r' || *p == '\\t')\n            ++p;\n        else\n            return p;\n\n    // The rest of string using SIMD\n    static const char whitespace[16] = \" \\n\\r\\t\";\n    const __m128i w = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespace[0]));\n\n    for (;; p += 16) {\n        const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));\n        const int r = _mm_cmpistri(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_LEAST_SIGNIFICANT | _SIDD_NEGATIVE_POLARITY);\n        if (r != 16)    // some of characters is non-whitespace\n            return p + r;\n    }\n}\n\ninline const char *SkipWhitespace_SIMD(const char* p, const char* end) {\n    // Fast return for single non-whitespace\n    if (p != end && (*p == ' ' || *p == '\\n' || *p == '\\r' || *p == '\\t'))\n        ++p;\n    else\n        return p;\n\n    // The middle of string using SIMD\n    static const char whitespace[16] = \" \\n\\r\\t\";\n    const __m128i w = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespace[0]));\n\n    for (; p <= end - 16; p += 16) {\n        const __m128i s = _mm_loadu_si128(reinterpret_cast<const __m128i *>(p));\n        const int r = _mm_cmpistri(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_LEAST_SIGNIFICANT | _SIDD_NEGATIVE_POLARITY);\n        if (r != 16)    // some of characters is non-whitespace\n            return p + r;\n    }\n\n    return SkipWhitespace(p, end);\n}\n\n#elif defined(RAPIDJSON_SSE2)\n\n//! Skip whitespace with SSE2 instructions, testing 16 8-byte characters at once.\ninline const char *SkipWhitespace_SIMD(const char* p) {\n    // Fast return for single non-whitespace\n    if (*p == ' ' || *p == '\\n' || *p == '\\r' || *p == '\\t')\n        ++p;\n    else\n        return p;\n\n    // 16-byte align to the next boundary\n    const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));\n    while (p != nextAligned)\n        if (*p == ' ' || *p == '\\n' || *p == '\\r' || *p == '\\t')\n            ++p;\n        else\n            return p;\n\n    // The rest of string\n    #define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c }\n    static const char whitespaces[4][16] = { C16(' '), C16('\\n'), C16('\\r'), C16('\\t') };\n    #undef C16\n\n    const __m128i w0 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[0][0]));\n    const __m128i w1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[1][0]));\n    const __m128i w2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[2][0]));\n    const __m128i w3 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[3][0]));\n\n    for (;; p += 16) {\n        const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));\n        __m128i x = _mm_cmpeq_epi8(s, w0);\n        x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1));\n        x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2));\n        x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3));\n        unsigned short r = static_cast<unsigned short>(~_mm_movemask_epi8(x));\n        if (r != 0) {   // some of characters may be non-whitespace\n#ifdef _MSC_VER         // Find the index of first non-whitespace\n            unsigned long offset;\n            _BitScanForward(&offset, r);\n            return p + offset;\n#else\n            return p + __builtin_ffs(r) - 1;\n#endif\n        }\n    }\n}\n\ninline const char *SkipWhitespace_SIMD(const char* p, const char* end) {\n    // Fast return for single non-whitespace\n    if (p != end && (*p == ' ' || *p == '\\n' || *p == '\\r' || *p == '\\t'))\n        ++p;\n    else\n        return p;\n\n    // The rest of string\n    #define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c }\n    static const char whitespaces[4][16] = { C16(' '), C16('\\n'), C16('\\r'), C16('\\t') };\n    #undef C16\n\n    const __m128i w0 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[0][0]));\n    const __m128i w1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[1][0]));\n    const __m128i w2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[2][0]));\n    const __m128i w3 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[3][0]));\n\n    for (; p <= end - 16; p += 16) {\n        const __m128i s = _mm_loadu_si128(reinterpret_cast<const __m128i *>(p));\n        __m128i x = _mm_cmpeq_epi8(s, w0);\n        x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1));\n        x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2));\n        x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3));\n        unsigned short r = static_cast<unsigned short>(~_mm_movemask_epi8(x));\n        if (r != 0) {   // some of characters may be non-whitespace\n#ifdef _MSC_VER         // Find the index of first non-whitespace\n            unsigned long offset;\n            _BitScanForward(&offset, r);\n            return p + offset;\n#else\n            return p + __builtin_ffs(r) - 1;\n#endif\n        }\n    }\n\n    return SkipWhitespace(p, end);\n}\n\n#endif // RAPIDJSON_SSE2\n\n#ifdef RAPIDJSON_SIMD\n//! Template function specialization for InsituStringStream\ntemplate<> inline void SkipWhitespace(InsituStringStream& is) {\n    is.src_ = const_cast<char*>(SkipWhitespace_SIMD(is.src_));\n}\n\n//! Template function specialization for StringStream\ntemplate<> inline void SkipWhitespace(StringStream& is) {\n    is.src_ = SkipWhitespace_SIMD(is.src_);\n}\n\ntemplate<> inline void SkipWhitespace(EncodedInputStream<UTF8<>, MemoryStream>& is) {\n    is.is_.src_ = SkipWhitespace_SIMD(is.is_.src_, is.is_.end_);\n}\n#endif // RAPIDJSON_SIMD\n\n///////////////////////////////////////////////////////////////////////////////\n// GenericReader\n\n//! SAX-style JSON parser. Use \\ref Reader for UTF8 encoding and default allocator.\n/*! GenericReader parses JSON text from a stream, and send events synchronously to an\n    object implementing Handler concept.\n\n    It needs to allocate a stack for storing a single decoded string during\n    non-destructive parsing.\n\n    For in-situ parsing, the decoded string is directly written to the source\n    text string, no temporary buffer is required.\n\n    A GenericReader object can be reused for parsing multiple JSON text.\n\n    \\tparam SourceEncoding Encoding of the input stream.\n    \\tparam TargetEncoding Encoding of the parse output.\n    \\tparam StackAllocator Allocator type for stack.\n*/\ntemplate <typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>\nclass GenericReader {\npublic:\n    typedef typename SourceEncoding::Ch Ch; //!< SourceEncoding character type\n\n    //! Constructor.\n    /*! \\param stackAllocator Optional allocator for allocating stack memory. (Only use for non-destructive parsing)\n        \\param stackCapacity stack capacity in bytes for storing a single decoded string.  (Only use for non-destructive parsing)\n    */\n    GenericReader(StackAllocator* stackAllocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(stackAllocator, stackCapacity), parseResult_() {}\n\n    //! Parse JSON text.\n    /*! \\tparam parseFlags Combination of \\ref ParseFlag.\n        \\tparam InputStream Type of input stream, implementing Stream concept.\n        \\tparam Handler Type of handler, implementing Handler concept.\n        \\param is Input stream to be parsed.\n        \\param handler The handler to receive events.\n        \\return Whether the parsing is successful.\n    */\n    template <unsigned parseFlags, typename InputStream, typename Handler>\n    ParseResult Parse(InputStream& is, Handler& handler) {\n        if (parseFlags & kParseIterativeFlag)\n            return IterativeParse<parseFlags>(is, handler);\n\n        parseResult_.Clear();\n\n        ClearStackOnExit scope(*this);\n\n        SkipWhitespaceAndComments<parseFlags>(is);\n        RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);\n\n        if (RAPIDJSON_UNLIKELY(is.Peek() == '\\0')) {\n            RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentEmpty, is.Tell());\n            RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);\n        }\n        else {\n            ParseValue<parseFlags>(is, handler);\n            RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);\n\n            if (!(parseFlags & kParseStopWhenDoneFlag)) {\n                SkipWhitespaceAndComments<parseFlags>(is);\n                RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);\n\n                if (RAPIDJSON_UNLIKELY(is.Peek() != '\\0')) {\n                    RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentRootNotSingular, is.Tell());\n                    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);\n                }\n            }\n        }\n\n        return parseResult_;\n    }\n\n    //! Parse JSON text (with \\ref kParseDefaultFlags)\n    /*! \\tparam InputStream Type of input stream, implementing Stream concept\n        \\tparam Handler Type of handler, implementing Handler concept.\n        \\param is Input stream to be parsed.\n        \\param handler The handler to receive events.\n        \\return Whether the parsing is successful.\n    */\n    template <typename InputStream, typename Handler>\n    ParseResult Parse(InputStream& is, Handler& handler) {\n        return Parse<kParseDefaultFlags>(is, handler);\n    }\n\n    //! Whether a parse error has occured in the last parsing.\n    bool HasParseError() const { return parseResult_.IsError(); }\n\n    //! Get the \\ref ParseErrorCode of last parsing.\n    ParseErrorCode GetParseErrorCode() const { return parseResult_.Code(); }\n\n    //! Get the position of last parsing error in input, 0 otherwise.\n    size_t GetErrorOffset() const { return parseResult_.Offset(); }\n\nprotected:\n    void SetParseError(ParseErrorCode code, size_t offset) { parseResult_.Set(code, offset); }\n\nprivate:\n    // Prohibit copy constructor & assignment operator.\n    GenericReader(const GenericReader&);\n    GenericReader& operator=(const GenericReader&);\n\n    void ClearStack() { stack_.Clear(); }\n\n    // clear stack on any exit from ParseStream, e.g. due to exception\n    struct ClearStackOnExit {\n        explicit ClearStackOnExit(GenericReader& r) : r_(r) {}\n        ~ClearStackOnExit() { r_.ClearStack(); }\n    private:\n        GenericReader& r_;\n        ClearStackOnExit(const ClearStackOnExit&);\n        ClearStackOnExit& operator=(const ClearStackOnExit&);\n    };\n\n    template<unsigned parseFlags, typename InputStream>\n    void SkipWhitespaceAndComments(InputStream& is) {\n        SkipWhitespace(is);\n\n        if (parseFlags & kParseCommentsFlag) {\n            while (RAPIDJSON_UNLIKELY(Consume(is, '/'))) {\n                if (Consume(is, '*')) {\n                    while (true) {\n                        if (RAPIDJSON_UNLIKELY(is.Peek() == '\\0'))\n                            RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell());\n                        else if (Consume(is, '*')) {\n                            if (Consume(is, '/'))\n                                break;\n                        }\n                        else\n                            is.Take();\n                    }\n                }\n                else if (RAPIDJSON_LIKELY(Consume(is, '/')))\n                    while (is.Peek() != '\\0' && is.Take() != '\\n') {}\n                else\n                    RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell());\n\n                SkipWhitespace(is);\n            }\n        }\n    }\n\n    // Parse object: { string : value, ... }\n    template<unsigned parseFlags, typename InputStream, typename Handler>\n    void ParseObject(InputStream& is, Handler& handler) {\n        RAPIDJSON_ASSERT(is.Peek() == '{');\n        is.Take();  // Skip '{'\n\n        if (RAPIDJSON_UNLIKELY(!handler.StartObject()))\n            RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());\n\n        SkipWhitespaceAndComments<parseFlags>(is);\n        RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;\n\n        if (Consume(is, '}')) {\n            if (RAPIDJSON_UNLIKELY(!handler.EndObject(0)))  // empty object\n                RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());\n            return;\n        }\n\n        for (SizeType memberCount = 0;;) {\n            if (RAPIDJSON_UNLIKELY(is.Peek() != '\"'))\n                RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell());\n\n            ParseString<parseFlags>(is, handler, true);\n            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;\n\n            SkipWhitespaceAndComments<parseFlags>(is);\n            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;\n\n            if (RAPIDJSON_UNLIKELY(!Consume(is, ':')))\n                RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell());\n\n            SkipWhitespaceAndComments<parseFlags>(is);\n            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;\n\n            ParseValue<parseFlags>(is, handler);\n            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;\n\n            SkipWhitespaceAndComments<parseFlags>(is);\n            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;\n\n            ++memberCount;\n\n            switch (is.Peek()) {\n                case ',':\n                    is.Take();\n                    SkipWhitespaceAndComments<parseFlags>(is);\n                    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;\n                    break;\n                case '}':\n                    is.Take();\n                    if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount)))\n                        RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());\n                    return;\n                default:\n                    RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); break; // This useless break is only for making warning and coverage happy\n            }\n\n            if (parseFlags & kParseTrailingCommasFlag) {\n                if (is.Peek() == '}') {\n                    if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount)))\n                        RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());\n                    is.Take();\n                    return;\n                }\n            }\n        }\n    }\n\n    // Parse array: [ value, ... ]\n    template<unsigned parseFlags, typename InputStream, typename Handler>\n    void ParseArray(InputStream& is, Handler& handler) {\n        RAPIDJSON_ASSERT(is.Peek() == '[');\n        is.Take();  // Skip '['\n\n        if (RAPIDJSON_UNLIKELY(!handler.StartArray()))\n            RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());\n\n        SkipWhitespaceAndComments<parseFlags>(is);\n        RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;\n\n        if (Consume(is, ']')) {\n            if (RAPIDJSON_UNLIKELY(!handler.EndArray(0))) // empty array\n                RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());\n            return;\n        }\n\n        for (SizeType elementCount = 0;;) {\n            ParseValue<parseFlags>(is, handler);\n            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;\n\n            ++elementCount;\n            SkipWhitespaceAndComments<parseFlags>(is);\n            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;\n\n            if (Consume(is, ',')) {\n                SkipWhitespaceAndComments<parseFlags>(is);\n                RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;\n            }\n            else if (Consume(is, ']')) {\n                if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount)))\n                    RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());\n                return;\n            }\n            else\n                RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell());\n\n            if (parseFlags & kParseTrailingCommasFlag) {\n                if (is.Peek() == ']') {\n                    if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount)))\n                        RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());\n                    is.Take();\n                    return;\n                }\n            }\n        }\n    }\n\n    template<unsigned parseFlags, typename InputStream, typename Handler>\n    void ParseNull(InputStream& is, Handler& handler) {\n        RAPIDJSON_ASSERT(is.Peek() == 'n');\n        is.Take();\n\n        if (RAPIDJSON_LIKELY(Consume(is, 'u') && Consume(is, 'l') && Consume(is, 'l'))) {\n            if (RAPIDJSON_UNLIKELY(!handler.Null()))\n                RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());\n        }\n        else\n            RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell());\n    }\n\n    template<unsigned parseFlags, typename InputStream, typename Handler>\n    void ParseTrue(InputStream& is, Handler& handler) {\n        RAPIDJSON_ASSERT(is.Peek() == 't');\n        is.Take();\n\n        if (RAPIDJSON_LIKELY(Consume(is, 'r') && Consume(is, 'u') && Consume(is, 'e'))) {\n            if (RAPIDJSON_UNLIKELY(!handler.Bool(true)))\n                RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());\n        }\n        else\n            RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell());\n    }\n\n    template<unsigned parseFlags, typename InputStream, typename Handler>\n    void ParseFalse(InputStream& is, Handler& handler) {\n        RAPIDJSON_ASSERT(is.Peek() == 'f');\n        is.Take();\n\n        if (RAPIDJSON_LIKELY(Consume(is, 'a') && Consume(is, 'l') && Consume(is, 's') && Consume(is, 'e'))) {\n            if (RAPIDJSON_UNLIKELY(!handler.Bool(false)))\n                RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());\n        }\n        else\n            RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell());\n    }\n\n    template<typename InputStream>\n    RAPIDJSON_FORCEINLINE static bool Consume(InputStream& is, typename InputStream::Ch expect) {\n        if (RAPIDJSON_LIKELY(is.Peek() == expect)) {\n            is.Take();\n            return true;\n        }\n        else\n            return false;\n    }\n\n    // Helper function to parse four hexidecimal digits in \\uXXXX in ParseString().\n    template<typename InputStream>\n    unsigned ParseHex4(InputStream& is, size_t escapeOffset) {\n        unsigned codepoint = 0;\n        for (int i = 0; i < 4; i++) {\n            Ch c = is.Peek();\n            codepoint <<= 4;\n            codepoint += static_cast<unsigned>(c);\n            if (c >= '0' && c <= '9')\n                codepoint -= '0';\n            else if (c >= 'A' && c <= 'F')\n                codepoint -= 'A' - 10;\n            else if (c >= 'a' && c <= 'f')\n                codepoint -= 'a' - 10;\n            else {\n                RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorStringUnicodeEscapeInvalidHex, escapeOffset);\n                RAPIDJSON_PARSE_ERROR_EARLY_RETURN(0);\n            }\n            is.Take();\n        }\n        return codepoint;\n    }\n\n    template <typename CharType>\n    class StackStream {\n    public:\n        typedef CharType Ch;\n\n        StackStream(internal::Stack<StackAllocator>& stack) : stack_(stack), length_(0) {}\n        RAPIDJSON_FORCEINLINE void Put(Ch c) {\n            *stack_.template Push<Ch>() = c;\n            ++length_;\n        }\n\n        RAPIDJSON_FORCEINLINE void* Push(SizeType count) {\n            length_ += count;\n            return stack_.template Push<Ch>(count);\n        }\n\n        size_t Length() const { return length_; }\n\n        Ch* Pop() {\n            return stack_.template Pop<Ch>(length_);\n        }\n\n    private:\n        StackStream(const StackStream&);\n        StackStream& operator=(const StackStream&);\n\n        internal::Stack<StackAllocator>& stack_;\n        SizeType length_;\n    };\n\n    // Parse string and generate String event. Different code paths for kParseInsituFlag.\n    template<unsigned parseFlags, typename InputStream, typename Handler>\n    void ParseString(InputStream& is, Handler& handler, bool isKey = false) {\n        internal::StreamLocalCopy<InputStream> copy(is);\n        InputStream& s(copy.s);\n\n        RAPIDJSON_ASSERT(s.Peek() == '\\\"');\n        s.Take();  // Skip '\\\"'\n\n        bool success = false;\n        if (parseFlags & kParseInsituFlag) {\n            typename InputStream::Ch *head = s.PutBegin();\n            ParseStringToStream<parseFlags, SourceEncoding, SourceEncoding>(s, s);\n            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;\n            size_t length = s.PutEnd(head) - 1;\n            RAPIDJSON_ASSERT(length <= 0xFFFFFFFF);\n            const typename TargetEncoding::Ch* const str = reinterpret_cast<typename TargetEncoding::Ch*>(head);\n            success = (isKey ? handler.Key(str, SizeType(length), false) : handler.String(str, SizeType(length), false));\n        }\n        else {\n            StackStream<typename TargetEncoding::Ch> stackStream(stack_);\n            ParseStringToStream<parseFlags, SourceEncoding, TargetEncoding>(s, stackStream);\n            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;\n            SizeType length = static_cast<SizeType>(stackStream.Length()) - 1;\n            const typename TargetEncoding::Ch* const str = stackStream.Pop();\n            success = (isKey ? handler.Key(str, length, true) : handler.String(str, length, true));\n        }\n        if (RAPIDJSON_UNLIKELY(!success))\n            RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell());\n    }\n\n    // Parse string to an output is\n    // This function handles the prefix/suffix double quotes, escaping, and optional encoding validation.\n    template<unsigned parseFlags, typename SEncoding, typename TEncoding, typename InputStream, typename OutputStream>\n    RAPIDJSON_FORCEINLINE void ParseStringToStream(InputStream& is, OutputStream& os) {\n//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN\n#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n        static const char escape[256] = {\n            Z16, Z16, 0, 0,'\\\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'/',\n            Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\\\', 0, 0, 0,\n            0, 0,'\\b', 0, 0, 0,'\\f', 0, 0, 0, 0, 0, 0, 0,'\\n', 0,\n            0, 0,'\\r', 0,'\\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n            Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16\n        };\n#undef Z16\n//!@endcond\n\n        for (;;) {\n            // Scan and copy string before \"\\\\\\\"\" or < 0x20. This is an optional optimzation.\n            if (!(parseFlags & kParseValidateEncodingFlag))\n                ScanCopyUnescapedString(is, os);\n\n            Ch c = is.Peek();\n            if (RAPIDJSON_UNLIKELY(c == '\\\\')) {    // Escape\n                size_t escapeOffset = is.Tell();    // For invalid escaping, report the inital '\\\\' as error offset\n                is.Take();\n                Ch e = is.Peek();\n                if ((sizeof(Ch) == 1 || unsigned(e) < 256) && RAPIDJSON_LIKELY(escape[static_cast<unsigned char>(e)])) {\n                    is.Take();\n                    os.Put(static_cast<typename TEncoding::Ch>(escape[static_cast<unsigned char>(e)]));\n                }\n                else if (RAPIDJSON_LIKELY(e == 'u')) {    // Unicode\n                    is.Take();\n                    unsigned codepoint = ParseHex4(is, escapeOffset);\n                    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;\n                    if (RAPIDJSON_UNLIKELY(codepoint >= 0xD800 && codepoint <= 0xDBFF)) {\n                        // Handle UTF-16 surrogate pair\n                        if (RAPIDJSON_UNLIKELY(!Consume(is, '\\\\') || !Consume(is, 'u')))\n                            RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset);\n                        unsigned codepoint2 = ParseHex4(is, escapeOffset);\n                        RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;\n                        if (RAPIDJSON_UNLIKELY(codepoint2 < 0xDC00 || codepoint2 > 0xDFFF))\n                            RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset);\n                        codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000;\n                    }\n                    TEncoding::Encode(os, codepoint);\n                }\n                else\n                    RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, escapeOffset);\n            }\n            else if (RAPIDJSON_UNLIKELY(c == '\"')) {    // Closing double quote\n                is.Take();\n                os.Put('\\0');   // null-terminate the string\n                return;\n            }\n            else if (RAPIDJSON_UNLIKELY(static_cast<unsigned>(c) < 0x20)) { // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF\n                if (c == '\\0')\n                    RAPIDJSON_PARSE_ERROR(kParseErrorStringMissQuotationMark, is.Tell());\n                else\n                    RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, is.Tell());\n            }\n            else {\n                size_t offset = is.Tell();\n                if (RAPIDJSON_UNLIKELY((parseFlags & kParseValidateEncodingFlag ?\n                    !Transcoder<SEncoding, TEncoding>::Validate(is, os) :\n                    !Transcoder<SEncoding, TEncoding>::Transcode(is, os))))\n                    RAPIDJSON_PARSE_ERROR(kParseErrorStringInvalidEncoding, offset);\n            }\n        }\n    }\n\n    template<typename InputStream, typename OutputStream>\n    static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InputStream&, OutputStream&) {\n            // Do nothing for generic version\n    }\n\n#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42)\n    // StringStream -> StackStream<char>\n    static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(StringStream& is, StackStream<char>& os) {\n        const char* p = is.src_;\n\n        // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)\n        const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));\n        while (p != nextAligned)\n            if (RAPIDJSON_UNLIKELY(*p == '\\\"') || RAPIDJSON_UNLIKELY(*p == '\\\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {\n                is.src_ = p;\n                return;\n            }\n            else\n                os.Put(*p++);\n\n        // The rest of string using SIMD\n        static const char dquote[16] = { '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"' };\n        static const char bslash[16] = { '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\' };\n        static const char space[16]  = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 };\n        const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));\n        const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));\n        const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));\n\n        for (;; p += 16) {\n            const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));\n            const __m128i t1 = _mm_cmpeq_epi8(s, dq);\n            const __m128i t2 = _mm_cmpeq_epi8(s, bs);\n            const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x19) == 0x19\n            const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);\n            unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x));\n            if (RAPIDJSON_UNLIKELY(r != 0)) {   // some of characters is escaped\n                SizeType length;\n    #ifdef _MSC_VER         // Find the index of first escaped\n                unsigned long offset;\n                _BitScanForward(&offset, r);\n                length = offset;\n    #else\n                length = static_cast<SizeType>(__builtin_ffs(r) - 1);\n    #endif\n                char* q = reinterpret_cast<char*>(os.Push(length));\n                for (size_t i = 0; i < length; i++)\n                    q[i] = p[i];\n\n                p += length;\n                break;\n            }\n            _mm_storeu_si128(reinterpret_cast<__m128i *>(os.Push(16)), s);\n        }\n\n        is.src_ = p;\n    }\n\n    // InsituStringStream -> InsituStringStream\n    static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InsituStringStream& is, InsituStringStream& os) {\n        RAPIDJSON_ASSERT(&is == &os);\n        (void)os;\n\n        if (is.src_ == is.dst_) {\n            SkipUnescapedString(is);\n            return;\n        }\n\n        char* p = is.src_;\n        char *q = is.dst_;\n\n        // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)\n        const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));\n        while (p != nextAligned)\n            if (RAPIDJSON_UNLIKELY(*p == '\\\"') || RAPIDJSON_UNLIKELY(*p == '\\\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {\n                is.src_ = p;\n                is.dst_ = q;\n                return;\n            }\n            else\n                *q++ = *p++;\n\n        // The rest of string using SIMD\n        static const char dquote[16] = { '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"' };\n        static const char bslash[16] = { '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\' };\n        static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 };\n        const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));\n        const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));\n        const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));\n\n        for (;; p += 16, q += 16) {\n            const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));\n            const __m128i t1 = _mm_cmpeq_epi8(s, dq);\n            const __m128i t2 = _mm_cmpeq_epi8(s, bs);\n            const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x19) == 0x19\n            const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);\n            unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x));\n            if (RAPIDJSON_UNLIKELY(r != 0)) {   // some of characters is escaped\n                size_t length;\n#ifdef _MSC_VER         // Find the index of first escaped\n                unsigned long offset;\n                _BitScanForward(&offset, r);\n                length = offset;\n#else\n                length = static_cast<size_t>(__builtin_ffs(r) - 1);\n#endif\n                for (const char* pend = p + length; p != pend; )\n                    *q++ = *p++;\n                break;\n            }\n            _mm_storeu_si128(reinterpret_cast<__m128i *>(q), s);\n        }\n\n        is.src_ = p;\n        is.dst_ = q;\n    }\n\n    // When read/write pointers are the same for insitu stream, just skip unescaped characters\n    static RAPIDJSON_FORCEINLINE void SkipUnescapedString(InsituStringStream& is) {\n        RAPIDJSON_ASSERT(is.src_ == is.dst_);\n        char* p = is.src_;\n\n        // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)\n        const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));\n        for (; p != nextAligned; p++)\n            if (RAPIDJSON_UNLIKELY(*p == '\\\"') || RAPIDJSON_UNLIKELY(*p == '\\\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {\n                is.src_ = is.dst_ = p;\n                return;\n            }\n\n        // The rest of string using SIMD\n        static const char dquote[16] = { '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"' };\n        static const char bslash[16] = { '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\' };\n        static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 };\n        const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));\n        const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));\n        const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));\n\n        for (;; p += 16) {\n            const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));\n            const __m128i t1 = _mm_cmpeq_epi8(s, dq);\n            const __m128i t2 = _mm_cmpeq_epi8(s, bs);\n            const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x19) == 0x19\n            const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);\n            unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x));\n            if (RAPIDJSON_UNLIKELY(r != 0)) {   // some of characters is escaped\n                size_t length;\n#ifdef _MSC_VER         // Find the index of first escaped\n                unsigned long offset;\n                _BitScanForward(&offset, r);\n                length = offset;\n#else\n                length = static_cast<size_t>(__builtin_ffs(r) - 1);\n#endif\n                p += length;\n                break;\n            }\n        }\n\n        is.src_ = is.dst_ = p;\n    }\n#endif\n\n    template<typename InputStream, bool backup, bool pushOnTake>\n    class NumberStream;\n\n    template<typename InputStream>\n    class NumberStream<InputStream, false, false> {\n    public:\n        typedef typename InputStream::Ch Ch;\n\n        NumberStream(GenericReader& reader, InputStream& s) : is(s) { (void)reader;  }\n\n        RAPIDJSON_FORCEINLINE Ch Peek() const { return is.Peek(); }\n        RAPIDJSON_FORCEINLINE Ch TakePush() { return is.Take(); }\n        RAPIDJSON_FORCEINLINE Ch Take() { return is.Take(); }\n\t\t  RAPIDJSON_FORCEINLINE void Push(char) {}\n\n        size_t Tell() { return is.Tell(); }\n        size_t Length() { return 0; }\n        const char* Pop() { return 0; }\n\n    protected:\n        NumberStream& operator=(const NumberStream&);\n\n        InputStream& is;\n    };\n\n    template<typename InputStream>\n    class NumberStream<InputStream, true, false> : public NumberStream<InputStream, false, false> {\n        typedef NumberStream<InputStream, false, false> Base;\n    public:\n        NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is), stackStream(reader.stack_) {}\n\n        RAPIDJSON_FORCEINLINE Ch TakePush() {\n            stackStream.Put(static_cast<char>(Base::is.Peek()));\n            return Base::is.Take();\n        }\n\n        RAPIDJSON_FORCEINLINE void Push(char c) {\n            stackStream.Put(c);\n        }\n\n        size_t Length() { return stackStream.Length(); }\n\n        const char* Pop() {\n            stackStream.Put('\\0');\n            return stackStream.Pop();\n        }\n\n    private:\n        StackStream<char> stackStream;\n    };\n\n    template<typename InputStream>\n    class NumberStream<InputStream, true, true> : public NumberStream<InputStream, true, false> {\n        typedef NumberStream<InputStream, true, false> Base;\n    public:\n        NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is) {}\n\n        RAPIDJSON_FORCEINLINE Ch Take() { return Base::TakePush(); }\n    };\n\n    template<unsigned parseFlags, typename InputStream, typename Handler>\n    void ParseNumber(InputStream& is, Handler& handler) {\n        internal::StreamLocalCopy<InputStream> copy(is);\n        NumberStream<InputStream,\n            ((parseFlags & kParseNumbersAsStringsFlag) != 0) ?\n                ((parseFlags & kParseInsituFlag) == 0) :\n                ((parseFlags & kParseFullPrecisionFlag) != 0),\n            (parseFlags & kParseNumbersAsStringsFlag) != 0 &&\n                (parseFlags & kParseInsituFlag) == 0> s(*this, copy.s);\n\n        size_t startOffset = s.Tell();\n        double d = 0.0;\n        bool useNanOrInf = false;\n\n        // Parse minus\n        bool minus = Consume(s, '-');\n\n        // Parse int: zero / ( digit1-9 *DIGIT )\n        unsigned i = 0;\n        uint64_t i64 = 0;\n        bool use64bit = false;\n        int significandDigit = 0;\n        if (RAPIDJSON_UNLIKELY(s.Peek() == '0')) {\n            i = 0;\n            s.TakePush();\n        }\n        else if (RAPIDJSON_LIKELY(s.Peek() >= '1' && s.Peek() <= '9')) {\n            i = static_cast<unsigned>(s.TakePush() - '0');\n\n            if (minus)\n                while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {\n                    if (RAPIDJSON_UNLIKELY(i >= 214748364)) { // 2^31 = 2147483648\n                        if (RAPIDJSON_LIKELY(i != 214748364 || s.Peek() > '8')) {\n                            i64 = i;\n                            use64bit = true;\n                            break;\n                        }\n                    }\n                    i = i * 10 + static_cast<unsigned>(s.TakePush() - '0');\n                    significandDigit++;\n                }\n            else\n                while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {\n                    if (RAPIDJSON_UNLIKELY(i >= 429496729)) { // 2^32 - 1 = 4294967295\n                        if (RAPIDJSON_LIKELY(i != 429496729 || s.Peek() > '5')) {\n                            i64 = i;\n                            use64bit = true;\n                            break;\n                        }\n                    }\n                    i = i * 10 + static_cast<unsigned>(s.TakePush() - '0');\n                    significandDigit++;\n                }\n        }\n        // Parse NaN or Infinity here\n        else if ((parseFlags & kParseNanAndInfFlag) && RAPIDJSON_LIKELY((s.Peek() == 'I' || s.Peek() == 'N'))) {\n            useNanOrInf = true;\n            if (RAPIDJSON_LIKELY(Consume(s, 'N') && Consume(s, 'a') && Consume(s, 'N'))) {\n                d = std::numeric_limits<double>::quiet_NaN();\n            }\n            else if (RAPIDJSON_LIKELY(Consume(s, 'I') && Consume(s, 'n') && Consume(s, 'f'))) {\n                d = (minus ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity());\n                if (RAPIDJSON_UNLIKELY(s.Peek() == 'i' && !(Consume(s, 'i') && Consume(s, 'n')\n                                                            && Consume(s, 'i') && Consume(s, 't') && Consume(s, 'y'))))\n                    RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell());\n            }\n            else\n                RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell());\n        }\n        else\n            RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell());\n\n        // Parse 64bit int\n        bool useDouble = false;\n        if (use64bit) {\n            if (minus)\n                while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {\n                     if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC))) // 2^63 = 9223372036854775808\n                        if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC) || s.Peek() > '8')) {\n                            d = static_cast<double>(i64);\n                            useDouble = true;\n                            break;\n                        }\n                    i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');\n                    significandDigit++;\n                }\n            else\n                while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {\n                    if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x19999999, 0x99999999))) // 2^64 - 1 = 18446744073709551615\n                        if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) || s.Peek() > '5')) {\n                            d = static_cast<double>(i64);\n                            useDouble = true;\n                            break;\n                        }\n                    i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');\n                    significandDigit++;\n                }\n        }\n\n        // Force double for big integer\n        if (useDouble) {\n            while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {\n                if (RAPIDJSON_UNLIKELY(d >= 1.7976931348623157e307)) // DBL_MAX / 10.0\n                    RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, startOffset);\n                d = d * 10 + (s.TakePush() - '0');\n            }\n        }\n\n        // Parse frac = decimal-point 1*DIGIT\n        int expFrac = 0;\n        size_t decimalPosition;\n        if (Consume(s, '.')) {\n            decimalPosition = s.Length();\n\n            if (RAPIDJSON_UNLIKELY(!(s.Peek() >= '0' && s.Peek() <= '9')))\n                RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissFraction, s.Tell());\n\n            if (!useDouble) {\n#if RAPIDJSON_64BIT\n                // Use i64 to store significand in 64-bit architecture\n                if (!use64bit)\n                    i64 = i;\n\n                while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {\n                    if (i64 > RAPIDJSON_UINT64_C2(0x1FFFFF, 0xFFFFFFFF)) // 2^53 - 1 for fast path\n                        break;\n                    else {\n                        i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');\n                        --expFrac;\n                        if (i64 != 0)\n                            significandDigit++;\n                    }\n                }\n\n                d = static_cast<double>(i64);\n#else\n                // Use double to store significand in 32-bit architecture\n                d = static_cast<double>(use64bit ? i64 : i);\n#endif\n                useDouble = true;\n            }\n\n            while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {\n                if (significandDigit < 17) {\n                    d = d * 10.0 + (s.TakePush() - '0');\n                    --expFrac;\n                    if (RAPIDJSON_LIKELY(d > 0.0))\n                        significandDigit++;\n                }\n                else\n                    s.TakePush();\n            }\n        }\n        else\n            decimalPosition = s.Length(); // decimal position at the end of integer.\n\n        // Parse exp = e [ minus / plus ] 1*DIGIT\n        int exp = 0;\n        if (Consume(s, 'e') || Consume(s, 'E')) {\n            if (!useDouble) {\n                d = static_cast<double>(use64bit ? i64 : i);\n                useDouble = true;\n            }\n\n            bool expMinus = false;\n            if (Consume(s, '+'))\n                ;\n            else if (Consume(s, '-'))\n                expMinus = true;\n\n            if (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {\n                exp = static_cast<int>(s.Take() - '0');\n                if (expMinus) {\n                    while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {\n                        exp = exp * 10 + static_cast<int>(s.Take() - '0');\n                        if (exp >= 214748364) {                         // Issue #313: prevent overflow exponent\n                            while (RAPIDJSON_UNLIKELY(s.Peek() >= '0' && s.Peek() <= '9'))  // Consume the rest of exponent\n                                s.Take();\n                        }\n                    }\n                }\n                else {  // positive exp\n                    int maxExp = 308 - expFrac;\n                    while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {\n                        exp = exp * 10 + static_cast<int>(s.Take() - '0');\n                        if (RAPIDJSON_UNLIKELY(exp > maxExp))\n                            RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, startOffset);\n                    }\n                }\n            }\n            else\n                RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissExponent, s.Tell());\n\n            if (expMinus)\n                exp = -exp;\n        }\n\n        // Finish parsing, call event according to the type of number.\n        bool cont = true;\n\n        if (parseFlags & kParseNumbersAsStringsFlag) {\n            if (parseFlags & kParseInsituFlag) {\n                s.Pop();  // Pop stack no matter if it will be used or not.\n                typename InputStream::Ch* head = is.PutBegin();\n                const size_t length = s.Tell() - startOffset;\n                RAPIDJSON_ASSERT(length <= 0xFFFFFFFF);\n                // unable to insert the \\0 character here, it will erase the comma after this number\n                const typename TargetEncoding::Ch* const str = reinterpret_cast<typename TargetEncoding::Ch*>(head);\n                cont = handler.RawNumber(str, SizeType(length), false);\n            }\n            else {\n                SizeType numCharsToCopy = static_cast<SizeType>(s.Length());\n                StringStream srcStream(s.Pop());\n                StackStream<typename TargetEncoding::Ch> dstStream(stack_);\n                while (numCharsToCopy--) {\n                    Transcoder<UTF8<>, TargetEncoding>::Transcode(srcStream, dstStream);\n                }\n                dstStream.Put('\\0');\n                const typename TargetEncoding::Ch* str = dstStream.Pop();\n                const SizeType length = static_cast<SizeType>(dstStream.Length()) - 1;\n                cont = handler.RawNumber(str, SizeType(length), true);\n            }\n        }\n        else {\n           size_t length = s.Length();\n           const char* decimal = s.Pop();  // Pop stack no matter if it will be used or not.\n\n           if (useDouble) {\n               int p = exp + expFrac;\n               if (parseFlags & kParseFullPrecisionFlag)\n                   d = internal::StrtodFullPrecision(d, p, decimal, length, decimalPosition, exp);\n               else\n                   d = internal::StrtodNormalPrecision(d, p);\n\n               cont = handler.Double(minus ? -d : d);\n           }\n           else if (useNanOrInf) {\n               cont = handler.Double(d);\n           }\n           else {\n               if (use64bit) {\n                   if (minus)\n                       cont = handler.Int64(static_cast<int64_t>(~i64 + 1));\n                   else\n                       cont = handler.Uint64(i64);\n               }\n               else {\n                   if (minus)\n                       cont = handler.Int(static_cast<int32_t>(~i + 1));\n                   else\n                       cont = handler.Uint(i);\n               }\n           }\n        }\n        if (RAPIDJSON_UNLIKELY(!cont))\n            RAPIDJSON_PARSE_ERROR(kParseErrorTermination, startOffset);\n    }\n\n    // Parse any JSON value\n    template<unsigned parseFlags, typename InputStream, typename Handler>\n    void ParseValue(InputStream& is, Handler& handler) {\n        switch (is.Peek()) {\n            case 'n': ParseNull  <parseFlags>(is, handler); break;\n            case 't': ParseTrue  <parseFlags>(is, handler); break;\n            case 'f': ParseFalse <parseFlags>(is, handler); break;\n            case '\"': ParseString<parseFlags>(is, handler); break;\n            case '{': ParseObject<parseFlags>(is, handler); break;\n            case '[': ParseArray <parseFlags>(is, handler); break;\n            default :\n                      ParseNumber<parseFlags>(is, handler);\n                      break;\n\n        }\n    }\n\n    // Iterative Parsing\n\n    // States\n    enum IterativeParsingState {\n        IterativeParsingStartState = 0,\n        IterativeParsingFinishState,\n        IterativeParsingErrorState,\n\n        // Object states\n        IterativeParsingObjectInitialState,\n        IterativeParsingMemberKeyState,\n        IterativeParsingKeyValueDelimiterState,\n        IterativeParsingMemberValueState,\n        IterativeParsingMemberDelimiterState,\n        IterativeParsingObjectFinishState,\n\n        // Array states\n        IterativeParsingArrayInitialState,\n        IterativeParsingElementState,\n        IterativeParsingElementDelimiterState,\n        IterativeParsingArrayFinishState,\n\n        // Single value state\n        IterativeParsingValueState\n    };\n\n    enum { cIterativeParsingStateCount = IterativeParsingValueState + 1 };\n\n    // Tokens\n    enum Token {\n        LeftBracketToken = 0,\n        RightBracketToken,\n\n        LeftCurlyBracketToken,\n        RightCurlyBracketToken,\n\n        CommaToken,\n        ColonToken,\n\n        StringToken,\n        FalseToken,\n        TrueToken,\n        NullToken,\n        NumberToken,\n\n        kTokenCount\n    };\n\n    RAPIDJSON_FORCEINLINE Token Tokenize(Ch c) {\n\n//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN\n#define N NumberToken\n#define N16 N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N\n        // Maps from ASCII to Token\n        static const unsigned char tokenMap[256] = {\n            N16, // 00~0F\n            N16, // 10~1F\n            N, N, StringToken, N, N, N, N, N, N, N, N, N, CommaToken, N, N, N, // 20~2F\n            N, N, N, N, N, N, N, N, N, N, ColonToken, N, N, N, N, N, // 30~3F\n            N16, // 40~4F\n            N, N, N, N, N, N, N, N, N, N, N, LeftBracketToken, N, RightBracketToken, N, N, // 50~5F\n            N, N, N, N, N, N, FalseToken, N, N, N, N, N, N, N, NullToken, N, // 60~6F\n            N, N, N, N, TrueToken, N, N, N, N, N, N, LeftCurlyBracketToken, N, RightCurlyBracketToken, N, N, // 70~7F\n            N16, N16, N16, N16, N16, N16, N16, N16 // 80~FF\n        };\n#undef N\n#undef N16\n//!@endcond\n\n        if (sizeof(Ch) == 1 || static_cast<unsigned>(c) < 256)\n            return static_cast<Token>(tokenMap[static_cast<unsigned char>(c)]);\n        else\n            return NumberToken;\n    }\n\n    RAPIDJSON_FORCEINLINE IterativeParsingState Predict(IterativeParsingState state, Token token) {\n        // current state x one lookahead token -> new state\n        static const char G[cIterativeParsingStateCount][kTokenCount] = {\n            // Start\n            {\n                IterativeParsingArrayInitialState,  // Left bracket\n                IterativeParsingErrorState,         // Right bracket\n                IterativeParsingObjectInitialState, // Left curly bracket\n                IterativeParsingErrorState,         // Right curly bracket\n                IterativeParsingErrorState,         // Comma\n                IterativeParsingErrorState,         // Colon\n                IterativeParsingValueState,         // String\n                IterativeParsingValueState,         // False\n                IterativeParsingValueState,         // True\n                IterativeParsingValueState,         // Null\n                IterativeParsingValueState          // Number\n            },\n            // Finish(sink state)\n            {\n                IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,\n                IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,\n                IterativeParsingErrorState\n            },\n            // Error(sink state)\n            {\n                IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,\n                IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,\n                IterativeParsingErrorState\n            },\n            // ObjectInitial\n            {\n                IterativeParsingErrorState,         // Left bracket\n                IterativeParsingErrorState,         // Right bracket\n                IterativeParsingErrorState,         // Left curly bracket\n                IterativeParsingObjectFinishState,  // Right curly bracket\n                IterativeParsingErrorState,         // Comma\n                IterativeParsingErrorState,         // Colon\n                IterativeParsingMemberKeyState,     // String\n                IterativeParsingErrorState,         // False\n                IterativeParsingErrorState,         // True\n                IterativeParsingErrorState,         // Null\n                IterativeParsingErrorState          // Number\n            },\n            // MemberKey\n            {\n                IterativeParsingErrorState,             // Left bracket\n                IterativeParsingErrorState,             // Right bracket\n                IterativeParsingErrorState,             // Left curly bracket\n                IterativeParsingErrorState,             // Right curly bracket\n                IterativeParsingErrorState,             // Comma\n                IterativeParsingKeyValueDelimiterState, // Colon\n                IterativeParsingErrorState,             // String\n                IterativeParsingErrorState,             // False\n                IterativeParsingErrorState,             // True\n                IterativeParsingErrorState,             // Null\n                IterativeParsingErrorState              // Number\n            },\n            // KeyValueDelimiter\n            {\n                IterativeParsingArrayInitialState,      // Left bracket(push MemberValue state)\n                IterativeParsingErrorState,             // Right bracket\n                IterativeParsingObjectInitialState,     // Left curly bracket(push MemberValue state)\n                IterativeParsingErrorState,             // Right curly bracket\n                IterativeParsingErrorState,             // Comma\n                IterativeParsingErrorState,             // Colon\n                IterativeParsingMemberValueState,       // String\n                IterativeParsingMemberValueState,       // False\n                IterativeParsingMemberValueState,       // True\n                IterativeParsingMemberValueState,       // Null\n                IterativeParsingMemberValueState        // Number\n            },\n            // MemberValue\n            {\n                IterativeParsingErrorState,             // Left bracket\n                IterativeParsingErrorState,             // Right bracket\n                IterativeParsingErrorState,             // Left curly bracket\n                IterativeParsingObjectFinishState,      // Right curly bracket\n                IterativeParsingMemberDelimiterState,   // Comma\n                IterativeParsingErrorState,             // Colon\n                IterativeParsingErrorState,             // String\n                IterativeParsingErrorState,             // False\n                IterativeParsingErrorState,             // True\n                IterativeParsingErrorState,             // Null\n                IterativeParsingErrorState              // Number\n            },\n            // MemberDelimiter\n            {\n                IterativeParsingErrorState,         // Left bracket\n                IterativeParsingErrorState,         // Right bracket\n                IterativeParsingErrorState,         // Left curly bracket\n                IterativeParsingObjectFinishState,  // Right curly bracket\n                IterativeParsingErrorState,         // Comma\n                IterativeParsingErrorState,         // Colon\n                IterativeParsingMemberKeyState,     // String\n                IterativeParsingErrorState,         // False\n                IterativeParsingErrorState,         // True\n                IterativeParsingErrorState,         // Null\n                IterativeParsingErrorState          // Number\n            },\n            // ObjectFinish(sink state)\n            {\n                IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,\n                IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,\n                IterativeParsingErrorState\n            },\n            // ArrayInitial\n            {\n                IterativeParsingArrayInitialState,      // Left bracket(push Element state)\n                IterativeParsingArrayFinishState,       // Right bracket\n                IterativeParsingObjectInitialState,     // Left curly bracket(push Element state)\n                IterativeParsingErrorState,             // Right curly bracket\n                IterativeParsingErrorState,             // Comma\n                IterativeParsingErrorState,             // Colon\n                IterativeParsingElementState,           // String\n                IterativeParsingElementState,           // False\n                IterativeParsingElementState,           // True\n                IterativeParsingElementState,           // Null\n                IterativeParsingElementState            // Number\n            },\n            // Element\n            {\n                IterativeParsingErrorState,             // Left bracket\n                IterativeParsingArrayFinishState,       // Right bracket\n                IterativeParsingErrorState,             // Left curly bracket\n                IterativeParsingErrorState,             // Right curly bracket\n                IterativeParsingElementDelimiterState,  // Comma\n                IterativeParsingErrorState,             // Colon\n                IterativeParsingErrorState,             // String\n                IterativeParsingErrorState,             // False\n                IterativeParsingErrorState,             // True\n                IterativeParsingErrorState,             // Null\n                IterativeParsingErrorState              // Number\n            },\n            // ElementDelimiter\n            {\n                IterativeParsingArrayInitialState,      // Left bracket(push Element state)\n                IterativeParsingArrayFinishState,       // Right bracket\n                IterativeParsingObjectInitialState,     // Left curly bracket(push Element state)\n                IterativeParsingErrorState,             // Right curly bracket\n                IterativeParsingErrorState,             // Comma\n                IterativeParsingErrorState,             // Colon\n                IterativeParsingElementState,           // String\n                IterativeParsingElementState,           // False\n                IterativeParsingElementState,           // True\n                IterativeParsingElementState,           // Null\n                IterativeParsingElementState            // Number\n            },\n            // ArrayFinish(sink state)\n            {\n                IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,\n                IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,\n                IterativeParsingErrorState\n            },\n            // Single Value (sink state)\n            {\n                IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,\n                IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,\n                IterativeParsingErrorState\n            }\n        }; // End of G\n\n        return static_cast<IterativeParsingState>(G[state][token]);\n    }\n\n    // Make an advance in the token stream and state based on the candidate destination state which was returned by Transit().\n    // May return a new state on state pop.\n    template <unsigned parseFlags, typename InputStream, typename Handler>\n    RAPIDJSON_FORCEINLINE IterativeParsingState Transit(IterativeParsingState src, Token token, IterativeParsingState dst, InputStream& is, Handler& handler) {\n        (void)token;\n\n        switch (dst) {\n        case IterativeParsingErrorState:\n            return dst;\n\n        case IterativeParsingObjectInitialState:\n        case IterativeParsingArrayInitialState:\n        {\n            // Push the state(Element or MemeberValue) if we are nested in another array or value of member.\n            // In this way we can get the correct state on ObjectFinish or ArrayFinish by frame pop.\n            IterativeParsingState n = src;\n            if (src == IterativeParsingArrayInitialState || src == IterativeParsingElementDelimiterState)\n                n = IterativeParsingElementState;\n            else if (src == IterativeParsingKeyValueDelimiterState)\n                n = IterativeParsingMemberValueState;\n            // Push current state.\n            *stack_.template Push<SizeType>(1) = n;\n            // Initialize and push the member/element count.\n            *stack_.template Push<SizeType>(1) = 0;\n            // Call handler\n            bool hr = (dst == IterativeParsingObjectInitialState) ? handler.StartObject() : handler.StartArray();\n            // On handler short circuits the parsing.\n            if (!hr) {\n                RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell());\n                return IterativeParsingErrorState;\n            }\n            else {\n                is.Take();\n                return dst;\n            }\n        }\n\n        case IterativeParsingMemberKeyState:\n            ParseString<parseFlags>(is, handler, true);\n            if (HasParseError())\n                return IterativeParsingErrorState;\n            else\n                return dst;\n\n        case IterativeParsingKeyValueDelimiterState:\n            RAPIDJSON_ASSERT(token == ColonToken);\n            is.Take();\n            return dst;\n\n        case IterativeParsingMemberValueState:\n            // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.\n            ParseValue<parseFlags>(is, handler);\n            if (HasParseError()) {\n                return IterativeParsingErrorState;\n            }\n            return dst;\n\n        case IterativeParsingElementState:\n            // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.\n            ParseValue<parseFlags>(is, handler);\n            if (HasParseError()) {\n                return IterativeParsingErrorState;\n            }\n            return dst;\n\n        case IterativeParsingMemberDelimiterState:\n        case IterativeParsingElementDelimiterState:\n            is.Take();\n            // Update member/element count.\n            *stack_.template Top<SizeType>() = *stack_.template Top<SizeType>() + 1;\n            return dst;\n\n        case IterativeParsingObjectFinishState:\n        {\n            // Transit from delimiter is only allowed when trailing commas are enabled\n            if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingMemberDelimiterState) {\n                RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorObjectMissName, is.Tell());\n                return IterativeParsingErrorState;\n            }\n            // Get member count.\n            SizeType c = *stack_.template Pop<SizeType>(1);\n            // If the object is not empty, count the last member.\n            if (src == IterativeParsingMemberValueState)\n                ++c;\n            // Restore the state.\n            IterativeParsingState n = static_cast<IterativeParsingState>(*stack_.template Pop<SizeType>(1));\n            // Transit to Finish state if this is the topmost scope.\n            if (n == IterativeParsingStartState)\n                n = IterativeParsingFinishState;\n            // Call handler\n            bool hr = handler.EndObject(c);\n            // On handler short circuits the parsing.\n            if (!hr) {\n                RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell());\n                return IterativeParsingErrorState;\n            }\n            else {\n                is.Take();\n                return n;\n            }\n        }\n\n        case IterativeParsingArrayFinishState:\n        {\n            // Transit from delimiter is only allowed when trailing commas are enabled\n            if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingElementDelimiterState) {\n                RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorValueInvalid, is.Tell());\n                return IterativeParsingErrorState;\n            }\n            // Get element count.\n            SizeType c = *stack_.template Pop<SizeType>(1);\n            // If the array is not empty, count the last element.\n            if (src == IterativeParsingElementState)\n                ++c;\n            // Restore the state.\n            IterativeParsingState n = static_cast<IterativeParsingState>(*stack_.template Pop<SizeType>(1));\n            // Transit to Finish state if this is the topmost scope.\n            if (n == IterativeParsingStartState)\n                n = IterativeParsingFinishState;\n            // Call handler\n            bool hr = handler.EndArray(c);\n            // On handler short circuits the parsing.\n            if (!hr) {\n                RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell());\n                return IterativeParsingErrorState;\n            }\n            else {\n                is.Take();\n                return n;\n            }\n        }\n\n        default:\n            // This branch is for IterativeParsingValueState actually.\n            // Use `default:` rather than\n            // `case IterativeParsingValueState:` is for code coverage.\n\n            // The IterativeParsingStartState is not enumerated in this switch-case.\n            // It is impossible for that case. And it can be caught by following assertion.\n\n            // The IterativeParsingFinishState is not enumerated in this switch-case either.\n            // It is a \"derivative\" state which cannot triggered from Predict() directly.\n            // Therefore it cannot happen here. And it can be caught by following assertion.\n            RAPIDJSON_ASSERT(dst == IterativeParsingValueState);\n\n            // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.\n            ParseValue<parseFlags>(is, handler);\n            if (HasParseError()) {\n                return IterativeParsingErrorState;\n            }\n            return IterativeParsingFinishState;\n        }\n    }\n\n    template <typename InputStream>\n    void HandleError(IterativeParsingState src, InputStream& is) {\n        if (HasParseError()) {\n            // Error flag has been set.\n            return;\n        }\n\n        switch (src) {\n        case IterativeParsingStartState:            RAPIDJSON_PARSE_ERROR(kParseErrorDocumentEmpty, is.Tell()); return;\n        case IterativeParsingFinishState:           RAPIDJSON_PARSE_ERROR(kParseErrorDocumentRootNotSingular, is.Tell()); return;\n        case IterativeParsingObjectInitialState:\n        case IterativeParsingMemberDelimiterState:  RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell()); return;\n        case IterativeParsingMemberKeyState:        RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell()); return;\n        case IterativeParsingMemberValueState:      RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); return;\n        case IterativeParsingKeyValueDelimiterState:\n        case IterativeParsingArrayInitialState:\n        case IterativeParsingElementDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); return;\n        default: RAPIDJSON_ASSERT(src == IterativeParsingElementState); RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell()); return;\n        }\n    }\n\n    template <unsigned parseFlags, typename InputStream, typename Handler>\n    ParseResult IterativeParse(InputStream& is, Handler& handler) {\n        parseResult_.Clear();\n        ClearStackOnExit scope(*this);\n        IterativeParsingState state = IterativeParsingStartState;\n\n        SkipWhitespaceAndComments<parseFlags>(is);\n        RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);\n        while (is.Peek() != '\\0') {\n            Token t = Tokenize(is.Peek());\n            IterativeParsingState n = Predict(state, t);\n            IterativeParsingState d = Transit<parseFlags>(state, t, n, is, handler);\n\n            if (d == IterativeParsingErrorState) {\n                HandleError(state, is);\n                break;\n            }\n\n            state = d;\n\n            // Do not further consume streams if a root JSON has been parsed.\n            if ((parseFlags & kParseStopWhenDoneFlag) && state == IterativeParsingFinishState)\n                break;\n\n            SkipWhitespaceAndComments<parseFlags>(is);\n            RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);\n        }\n\n        // Handle the end of file.\n        if (state != IterativeParsingFinishState)\n            HandleError(state, is);\n\n        return parseResult_;\n    }\n\n    static const size_t kDefaultStackCapacity = 256;    //!< Default stack capacity in bytes for storing a single decoded string.\n    internal::Stack<StackAllocator> stack_;  //!< A stack for storing decoded string temporarily during non-destructive parsing.\n    ParseResult parseResult_;\n}; // class GenericReader\n\n//! Reader with UTF8 encoding and default allocator.\ntypedef GenericReader<UTF8<>, UTF8<> > Reader;\n\nRAPIDJSON_NAMESPACE_END\n\n#ifdef __clang__\nRAPIDJSON_DIAG_POP\n#endif\n\n\n#ifdef __GNUC__\nRAPIDJSON_DIAG_POP\n#endif\n\n#ifdef _MSC_VER\nRAPIDJSON_DIAG_POP\n#endif\n\n#endif // RAPIDJSON_READER_H_\n"
  },
  {
    "path": "rapidjson/schema.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available->\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip-> All rights reserved->\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License-> You may obtain a copy of the License at\n//\n// http://opensource->org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied-> See the License for the \n// specific language governing permissions and limitations under the License->\n\n#ifndef RAPIDJSON_SCHEMA_H_\n#define RAPIDJSON_SCHEMA_H_\n\n#include \"document.h\"\n#include \"pointer.h\"\n#include <cmath> // abs, floor\n\n#if !defined(RAPIDJSON_SCHEMA_USE_INTERNALREGEX)\n#define RAPIDJSON_SCHEMA_USE_INTERNALREGEX 1\n#else\n#define RAPIDJSON_SCHEMA_USE_INTERNALREGEX 0\n#endif\n\n#if !RAPIDJSON_SCHEMA_USE_INTERNALREGEX && !defined(RAPIDJSON_SCHEMA_USE_STDREGEX) && (__cplusplus >=201103L || (defined(_MSC_VER) && _MSC_VER >= 1800))\n#define RAPIDJSON_SCHEMA_USE_STDREGEX 1\n#else\n#define RAPIDJSON_SCHEMA_USE_STDREGEX 0\n#endif\n\n#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX\n#include \"internal/regex.h\"\n#elif RAPIDJSON_SCHEMA_USE_STDREGEX\n#include <regex>\n#endif\n\n#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX || RAPIDJSON_SCHEMA_USE_STDREGEX\n#define RAPIDJSON_SCHEMA_HAS_REGEX 1\n#else\n#define RAPIDJSON_SCHEMA_HAS_REGEX 0\n#endif\n\n#ifndef RAPIDJSON_SCHEMA_VERBOSE\n#define RAPIDJSON_SCHEMA_VERBOSE 0\n#endif\n\n#if RAPIDJSON_SCHEMA_VERBOSE\n#include \"stringbuffer.h\"\n#endif\n\nRAPIDJSON_DIAG_PUSH\n\n#if defined(__GNUC__)\nRAPIDJSON_DIAG_OFF(effc++)\n#endif\n\n#ifdef __clang__\nRAPIDJSON_DIAG_OFF(weak-vtables)\nRAPIDJSON_DIAG_OFF(exit-time-destructors)\nRAPIDJSON_DIAG_OFF(c++98-compat-pedantic)\nRAPIDJSON_DIAG_OFF(variadic-macros)\n#endif\n\n#ifdef _MSC_VER\nRAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated\n#endif\n\nRAPIDJSON_NAMESPACE_BEGIN\n\n///////////////////////////////////////////////////////////////////////////////\n// Verbose Utilities\n\n#if RAPIDJSON_SCHEMA_VERBOSE\n\nnamespace internal {\n\ninline void PrintInvalidKeyword(const char* keyword) {\n    printf(\"Fail keyword: %s\\n\", keyword);\n}\n\ninline void PrintInvalidKeyword(const wchar_t* keyword) {\n    wprintf(L\"Fail keyword: %ls\\n\", keyword);\n}\n\ninline void PrintInvalidDocument(const char* document) {\n    printf(\"Fail document: %s\\n\\n\", document);\n}\n\ninline void PrintInvalidDocument(const wchar_t* document) {\n    wprintf(L\"Fail document: %ls\\n\\n\", document);\n}\n\ninline void PrintValidatorPointers(unsigned depth, const char* s, const char* d) {\n    printf(\"S: %*s%s\\nD: %*s%s\\n\\n\", depth * 4, \" \", s, depth * 4, \" \", d);\n}\n\ninline void PrintValidatorPointers(unsigned depth, const wchar_t* s, const wchar_t* d) {\n    wprintf(L\"S: %*ls%ls\\nD: %*ls%ls\\n\\n\", depth * 4, L\" \", s, depth * 4, L\" \", d);\n}\n\n} // namespace internal\n\n#endif // RAPIDJSON_SCHEMA_VERBOSE\n\n///////////////////////////////////////////////////////////////////////////////\n// RAPIDJSON_INVALID_KEYWORD_RETURN\n\n#if RAPIDJSON_SCHEMA_VERBOSE\n#define RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword) internal::PrintInvalidKeyword(keyword)\n#else\n#define RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword)\n#endif\n\n#define RAPIDJSON_INVALID_KEYWORD_RETURN(keyword)\\\nRAPIDJSON_MULTILINEMACRO_BEGIN\\\n    context.invalidKeyword = keyword.GetString();\\\n    RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword.GetString());\\\n    return false;\\\nRAPIDJSON_MULTILINEMACRO_END\n\n///////////////////////////////////////////////////////////////////////////////\n// Forward declarations\n\ntemplate <typename ValueType, typename Allocator>\nclass GenericSchemaDocument;\n\nnamespace internal {\n\ntemplate <typename SchemaDocumentType>\nclass Schema;\n\n///////////////////////////////////////////////////////////////////////////////\n// ISchemaValidator\n\nclass ISchemaValidator {\npublic:\n    virtual ~ISchemaValidator() {}\n    virtual bool IsValid() const = 0;\n};\n\n///////////////////////////////////////////////////////////////////////////////\n// ISchemaStateFactory\n\ntemplate <typename SchemaType>\nclass ISchemaStateFactory {\npublic:\n    virtual ~ISchemaStateFactory() {}\n    virtual ISchemaValidator* CreateSchemaValidator(const SchemaType&) = 0;\n    virtual void DestroySchemaValidator(ISchemaValidator* validator) = 0;\n    virtual void* CreateHasher() = 0;\n    virtual uint64_t GetHashCode(void* hasher) = 0;\n    virtual void DestroryHasher(void* hasher) = 0;\n    virtual void* MallocState(size_t size) = 0;\n    virtual void FreeState(void* p) = 0;\n};\n\n///////////////////////////////////////////////////////////////////////////////\n// Hasher\n\n// For comparison of compound value\ntemplate<typename Encoding, typename Allocator>\nclass Hasher {\npublic:\n    typedef typename Encoding::Ch Ch;\n\n    Hasher(Allocator* allocator = 0, size_t stackCapacity = kDefaultSize) : stack_(allocator, stackCapacity) {}\n\n    bool Null() { return WriteType(kNullType); }\n    bool Bool(bool b) { return WriteType(b ? kTrueType : kFalseType); }\n    bool Int(int i) { Number n; n.u.i = i; n.d = static_cast<double>(i); return WriteNumber(n); }\n    bool Uint(unsigned u) { Number n; n.u.u = u; n.d = static_cast<double>(u); return WriteNumber(n); }\n    bool Int64(int64_t i) { Number n; n.u.i = i; n.d = static_cast<double>(i); return WriteNumber(n); }\n    bool Uint64(uint64_t u) { Number n; n.u.u = u; n.d = static_cast<double>(u); return WriteNumber(n); }\n    bool Double(double d) { \n        Number n; \n        if (d < 0) n.u.i = static_cast<int64_t>(d);\n        else       n.u.u = static_cast<uint64_t>(d); \n        n.d = d;\n        return WriteNumber(n);\n    }\n\n    bool RawNumber(const Ch* str, SizeType len, bool) {\n        WriteBuffer(kNumberType, str, len * sizeof(Ch));\n        return true;\n    }\n\n    bool String(const Ch* str, SizeType len, bool) {\n        WriteBuffer(kStringType, str, len * sizeof(Ch));\n        return true;\n    }\n\n    bool StartObject() { return true; }\n    bool Key(const Ch* str, SizeType len, bool copy) { return String(str, len, copy); }\n    bool EndObject(SizeType memberCount) { \n        uint64_t h = Hash(0, kObjectType);\n        uint64_t* kv = stack_.template Pop<uint64_t>(memberCount * 2);\n        for (SizeType i = 0; i < memberCount; i++)\n            h ^= Hash(kv[i * 2], kv[i * 2 + 1]);  // Use xor to achieve member order insensitive\n        *stack_.template Push<uint64_t>() = h;\n        return true;\n    }\n    \n    bool StartArray() { return true; }\n    bool EndArray(SizeType elementCount) { \n        uint64_t h = Hash(0, kArrayType);\n        uint64_t* e = stack_.template Pop<uint64_t>(elementCount);\n        for (SizeType i = 0; i < elementCount; i++)\n            h = Hash(h, e[i]); // Use hash to achieve element order sensitive\n        *stack_.template Push<uint64_t>() = h;\n        return true;\n    }\n\n    bool IsValid() const { return stack_.GetSize() == sizeof(uint64_t); }\n\n    uint64_t GetHashCode() const {\n        RAPIDJSON_ASSERT(IsValid());\n        return *stack_.template Top<uint64_t>();\n    }\n\nprivate:\n    static const size_t kDefaultSize = 256;\n    struct Number {\n        union U {\n            uint64_t u;\n            int64_t i;\n        }u;\n        double d;\n    };\n\n    bool WriteType(Type type) { return WriteBuffer(type, 0, 0); }\n    \n    bool WriteNumber(const Number& n) { return WriteBuffer(kNumberType, &n, sizeof(n)); }\n    \n    bool WriteBuffer(Type type, const void* data, size_t len) {\n        // FNV-1a from http://isthe.com/chongo/tech/comp/fnv/\n        uint64_t h = Hash(RAPIDJSON_UINT64_C2(0x84222325, 0xcbf29ce4), type);\n        const unsigned char* d = static_cast<const unsigned char*>(data);\n        for (size_t i = 0; i < len; i++)\n            h = Hash(h, d[i]);\n        *stack_.template Push<uint64_t>() = h;\n        return true;\n    }\n\n    static uint64_t Hash(uint64_t h, uint64_t d) {\n        static const uint64_t kPrime = RAPIDJSON_UINT64_C2(0x00000100, 0x000001b3);\n        h ^= d;\n        h *= kPrime;\n        return h;\n    }\n\n    Stack<Allocator> stack_;\n};\n\n///////////////////////////////////////////////////////////////////////////////\n// SchemaValidationContext\n\ntemplate <typename SchemaDocumentType>\nstruct SchemaValidationContext {\n    typedef Schema<SchemaDocumentType> SchemaType;\n    typedef ISchemaStateFactory<SchemaType> SchemaValidatorFactoryType;\n    typedef typename SchemaType::ValueType ValueType;\n    typedef typename ValueType::Ch Ch;\n\n    enum PatternValidatorType {\n        kPatternValidatorOnly,\n        kPatternValidatorWithProperty,\n        kPatternValidatorWithAdditionalProperty\n    };\n\n    SchemaValidationContext(SchemaValidatorFactoryType& f, const SchemaType* s) :\n        factory(f),\n        schema(s),\n        valueSchema(),\n        invalidKeyword(),\n        hasher(),\n        arrayElementHashCodes(),\n        validators(),\n        validatorCount(),\n        patternPropertiesValidators(),\n        patternPropertiesValidatorCount(),\n        patternPropertiesSchemas(),\n        patternPropertiesSchemaCount(),\n        valuePatternValidatorType(kPatternValidatorOnly),\n        propertyExist(),\n        inArray(false),\n        valueUniqueness(false),\n        arrayUniqueness(false)\n    {\n    }\n\n    ~SchemaValidationContext() {\n        if (hasher)\n            factory.DestroryHasher(hasher);\n        if (validators) {\n            for (SizeType i = 0; i < validatorCount; i++)\n                factory.DestroySchemaValidator(validators[i]);\n            factory.FreeState(validators);\n        }\n        if (patternPropertiesValidators) {\n            for (SizeType i = 0; i < patternPropertiesValidatorCount; i++)\n                factory.DestroySchemaValidator(patternPropertiesValidators[i]);\n            factory.FreeState(patternPropertiesValidators);\n        }\n        if (patternPropertiesSchemas)\n            factory.FreeState(patternPropertiesSchemas);\n        if (propertyExist)\n            factory.FreeState(propertyExist);\n    }\n\n    SchemaValidatorFactoryType& factory;\n    const SchemaType* schema;\n    const SchemaType* valueSchema;\n    const Ch* invalidKeyword;\n    void* hasher; // Only validator access\n    void* arrayElementHashCodes; // Only validator access this\n    ISchemaValidator** validators;\n    SizeType validatorCount;\n    ISchemaValidator** patternPropertiesValidators;\n    SizeType patternPropertiesValidatorCount;\n    const SchemaType** patternPropertiesSchemas;\n    SizeType patternPropertiesSchemaCount;\n    PatternValidatorType valuePatternValidatorType;\n    PatternValidatorType objectPatternValidatorType;\n    SizeType arrayElementIndex;\n    bool* propertyExist;\n    bool inArray;\n    bool valueUniqueness;\n    bool arrayUniqueness;\n};\n\n///////////////////////////////////////////////////////////////////////////////\n// Schema\n\ntemplate <typename SchemaDocumentType>\nclass Schema {\npublic:\n    typedef typename SchemaDocumentType::ValueType ValueType;\n    typedef typename SchemaDocumentType::AllocatorType AllocatorType;\n    typedef typename SchemaDocumentType::PointerType PointerType;\n    typedef typename ValueType::EncodingType EncodingType;\n    typedef typename EncodingType::Ch Ch;\n    typedef SchemaValidationContext<SchemaDocumentType> Context;\n    typedef Schema<SchemaDocumentType> SchemaType;\n    typedef GenericValue<EncodingType, AllocatorType> SValue;\n    friend class GenericSchemaDocument<ValueType, AllocatorType>;\n\n    Schema(SchemaDocumentType* schemaDocument, const PointerType& p, const ValueType& value, const ValueType& document, AllocatorType* allocator) :\n        allocator_(allocator),\n        typeless_(schemaDocument->GetTypeless()),\n        enum_(),\n        enumCount_(),\n        not_(),\n        type_((1 << kTotalSchemaType) - 1), // typeless\n        validatorCount_(),\n        properties_(),\n        additionalPropertiesSchema_(),\n        patternProperties_(),\n        patternPropertyCount_(),\n        propertyCount_(),\n        minProperties_(),\n        maxProperties_(SizeType(~0)),\n        additionalProperties_(true),\n        hasDependencies_(),\n        hasRequired_(),\n        hasSchemaDependencies_(),\n        additionalItemsSchema_(),\n        itemsList_(),\n        itemsTuple_(),\n        itemsTupleCount_(),\n        minItems_(),\n        maxItems_(SizeType(~0)),\n        additionalItems_(true),\n        uniqueItems_(false),\n        pattern_(),\n        minLength_(0),\n        maxLength_(~SizeType(0)),\n        exclusiveMinimum_(false),\n        exclusiveMaximum_(false)\n    {\n        typedef typename SchemaDocumentType::ValueType ValueType;\n        typedef typename ValueType::ConstValueIterator ConstValueIterator;\n        typedef typename ValueType::ConstMemberIterator ConstMemberIterator;\n\n        if (!value.IsObject())\n            return;\n\n        if (const ValueType* v = GetMember(value, GetTypeString())) {\n            type_ = 0;\n            if (v->IsString())\n                AddType(*v);\n            else if (v->IsArray())\n                for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr)\n                    AddType(*itr);\n        }\n\n        if (const ValueType* v = GetMember(value, GetEnumString()))\n            if (v->IsArray() && v->Size() > 0) {\n                enum_ = static_cast<uint64_t*>(allocator_->Malloc(sizeof(uint64_t) * v->Size()));\n                for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr) {\n                    typedef Hasher<EncodingType, MemoryPoolAllocator<> > EnumHasherType;\n                    char buffer[256 + 24];\n                    MemoryPoolAllocator<> hasherAllocator(buffer, sizeof(buffer));\n                    EnumHasherType h(&hasherAllocator, 256);\n                    itr->Accept(h);\n                    enum_[enumCount_++] = h.GetHashCode();\n                }\n            }\n\n        if (schemaDocument) {\n            AssignIfExist(allOf_, *schemaDocument, p, value, GetAllOfString(), document);\n            AssignIfExist(anyOf_, *schemaDocument, p, value, GetAnyOfString(), document);\n            AssignIfExist(oneOf_, *schemaDocument, p, value, GetOneOfString(), document);\n        }\n\n        if (const ValueType* v = GetMember(value, GetNotString())) {\n            schemaDocument->CreateSchema(&not_, p.Append(GetNotString(), allocator_), *v, document);\n            notValidatorIndex_ = validatorCount_;\n            validatorCount_++;\n        }\n\n        // Object\n\n        const ValueType* properties = GetMember(value, GetPropertiesString());\n        const ValueType* required = GetMember(value, GetRequiredString());\n        const ValueType* dependencies = GetMember(value, GetDependenciesString());\n        {\n            // Gather properties from properties/required/dependencies\n            SValue allProperties(kArrayType);\n\n            if (properties && properties->IsObject())\n                for (ConstMemberIterator itr = properties->MemberBegin(); itr != properties->MemberEnd(); ++itr)\n                    AddUniqueElement(allProperties, itr->name);\n            \n            if (required && required->IsArray())\n                for (ConstValueIterator itr = required->Begin(); itr != required->End(); ++itr)\n                    if (itr->IsString())\n                        AddUniqueElement(allProperties, *itr);\n\n            if (dependencies && dependencies->IsObject())\n                for (ConstMemberIterator itr = dependencies->MemberBegin(); itr != dependencies->MemberEnd(); ++itr) {\n                    AddUniqueElement(allProperties, itr->name);\n                    if (itr->value.IsArray())\n                        for (ConstValueIterator i = itr->value.Begin(); i != itr->value.End(); ++i)\n                            if (i->IsString())\n                                AddUniqueElement(allProperties, *i);\n                }\n\n            if (allProperties.Size() > 0) {\n                propertyCount_ = allProperties.Size();\n                properties_ = static_cast<Property*>(allocator_->Malloc(sizeof(Property) * propertyCount_));\n                for (SizeType i = 0; i < propertyCount_; i++) {\n                    new (&properties_[i]) Property();\n                    properties_[i].name = allProperties[i];\n                    properties_[i].schema = typeless_;\n                }\n            }\n        }\n\n        if (properties && properties->IsObject()) {\n            PointerType q = p.Append(GetPropertiesString(), allocator_);\n            for (ConstMemberIterator itr = properties->MemberBegin(); itr != properties->MemberEnd(); ++itr) {\n                SizeType index;\n                if (FindPropertyIndex(itr->name, &index))\n                    schemaDocument->CreateSchema(&properties_[index].schema, q.Append(itr->name, allocator_), itr->value, document);\n            }\n        }\n\n        if (const ValueType* v = GetMember(value, GetPatternPropertiesString())) {\n            PointerType q = p.Append(GetPatternPropertiesString(), allocator_);\n            patternProperties_ = static_cast<PatternProperty*>(allocator_->Malloc(sizeof(PatternProperty) * v->MemberCount()));\n            patternPropertyCount_ = 0;\n\n            for (ConstMemberIterator itr = v->MemberBegin(); itr != v->MemberEnd(); ++itr) {\n                new (&patternProperties_[patternPropertyCount_]) PatternProperty();\n                patternProperties_[patternPropertyCount_].pattern = CreatePattern(itr->name);\n                schemaDocument->CreateSchema(&patternProperties_[patternPropertyCount_].schema, q.Append(itr->name, allocator_), itr->value, document);\n                patternPropertyCount_++;\n            }\n        }\n\n        if (required && required->IsArray())\n            for (ConstValueIterator itr = required->Begin(); itr != required->End(); ++itr)\n                if (itr->IsString()) {\n                    SizeType index;\n                    if (FindPropertyIndex(*itr, &index)) {\n                        properties_[index].required = true;\n                        hasRequired_ = true;\n                    }\n                }\n\n        if (dependencies && dependencies->IsObject()) {\n            PointerType q = p.Append(GetDependenciesString(), allocator_);\n            hasDependencies_ = true;\n            for (ConstMemberIterator itr = dependencies->MemberBegin(); itr != dependencies->MemberEnd(); ++itr) {\n                SizeType sourceIndex;\n                if (FindPropertyIndex(itr->name, &sourceIndex)) {\n                    if (itr->value.IsArray()) {\n                        properties_[sourceIndex].dependencies = static_cast<bool*>(allocator_->Malloc(sizeof(bool) * propertyCount_));\n                        std::memset(properties_[sourceIndex].dependencies, 0, sizeof(bool)* propertyCount_);\n                        for (ConstValueIterator targetItr = itr->value.Begin(); targetItr != itr->value.End(); ++targetItr) {\n                            SizeType targetIndex;\n                            if (FindPropertyIndex(*targetItr, &targetIndex))\n                                properties_[sourceIndex].dependencies[targetIndex] = true;\n                        }\n                    }\n                    else if (itr->value.IsObject()) {\n                        hasSchemaDependencies_ = true;\n                        schemaDocument->CreateSchema(&properties_[sourceIndex].dependenciesSchema, q.Append(itr->name, allocator_), itr->value, document);\n                        properties_[sourceIndex].dependenciesValidatorIndex = validatorCount_;\n                        validatorCount_++;\n                    }\n                }\n            }\n        }\n\n        if (const ValueType* v = GetMember(value, GetAdditionalPropertiesString())) {\n            if (v->IsBool())\n                additionalProperties_ = v->GetBool();\n            else if (v->IsObject())\n                schemaDocument->CreateSchema(&additionalPropertiesSchema_, p.Append(GetAdditionalPropertiesString(), allocator_), *v, document);\n        }\n\n        AssignIfExist(minProperties_, value, GetMinPropertiesString());\n        AssignIfExist(maxProperties_, value, GetMaxPropertiesString());\n\n        // Array\n        if (const ValueType* v = GetMember(value, GetItemsString())) {\n            PointerType q = p.Append(GetItemsString(), allocator_);\n            if (v->IsObject()) // List validation\n                schemaDocument->CreateSchema(&itemsList_, q, *v, document);\n            else if (v->IsArray()) { // Tuple validation\n                itemsTuple_ = static_cast<const Schema**>(allocator_->Malloc(sizeof(const Schema*) * v->Size()));\n                SizeType index = 0;\n                for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr, index++)\n                    schemaDocument->CreateSchema(&itemsTuple_[itemsTupleCount_++], q.Append(index, allocator_), *itr, document);\n            }\n        }\n\n        AssignIfExist(minItems_, value, GetMinItemsString());\n        AssignIfExist(maxItems_, value, GetMaxItemsString());\n\n        if (const ValueType* v = GetMember(value, GetAdditionalItemsString())) {\n            if (v->IsBool())\n                additionalItems_ = v->GetBool();\n            else if (v->IsObject())\n                schemaDocument->CreateSchema(&additionalItemsSchema_, p.Append(GetAdditionalItemsString(), allocator_), *v, document);\n        }\n\n        AssignIfExist(uniqueItems_, value, GetUniqueItemsString());\n\n        // String\n        AssignIfExist(minLength_, value, GetMinLengthString());\n        AssignIfExist(maxLength_, value, GetMaxLengthString());\n\n        if (const ValueType* v = GetMember(value, GetPatternString()))\n            pattern_ = CreatePattern(*v);\n\n        // Number\n        if (const ValueType* v = GetMember(value, GetMinimumString()))\n            if (v->IsNumber())\n                minimum_.CopyFrom(*v, *allocator_);\n\n        if (const ValueType* v = GetMember(value, GetMaximumString()))\n            if (v->IsNumber())\n                maximum_.CopyFrom(*v, *allocator_);\n\n        AssignIfExist(exclusiveMinimum_, value, GetExclusiveMinimumString());\n        AssignIfExist(exclusiveMaximum_, value, GetExclusiveMaximumString());\n\n        if (const ValueType* v = GetMember(value, GetMultipleOfString()))\n            if (v->IsNumber() && v->GetDouble() > 0.0)\n                multipleOf_.CopyFrom(*v, *allocator_);\n    }\n\n    ~Schema() {\n        AllocatorType::Free(enum_);\n        if (properties_) {\n            for (SizeType i = 0; i < propertyCount_; i++)\n                properties_[i].~Property();\n            AllocatorType::Free(properties_);\n        }\n        if (patternProperties_) {\n            for (SizeType i = 0; i < patternPropertyCount_; i++)\n                patternProperties_[i].~PatternProperty();\n            AllocatorType::Free(patternProperties_);\n        }\n        AllocatorType::Free(itemsTuple_);\n#if RAPIDJSON_SCHEMA_HAS_REGEX\n        if (pattern_) {\n            pattern_->~RegexType();\n            AllocatorType::Free(pattern_);\n        }\n#endif\n    }\n\n    bool BeginValue(Context& context) const {\n        if (context.inArray) {\n            if (uniqueItems_)\n                context.valueUniqueness = true;\n\n            if (itemsList_)\n                context.valueSchema = itemsList_;\n            else if (itemsTuple_) {\n                if (context.arrayElementIndex < itemsTupleCount_)\n                    context.valueSchema = itemsTuple_[context.arrayElementIndex];\n                else if (additionalItemsSchema_)\n                    context.valueSchema = additionalItemsSchema_;\n                else if (additionalItems_)\n                    context.valueSchema = typeless_;\n                else\n                    RAPIDJSON_INVALID_KEYWORD_RETURN(GetItemsString());\n            }\n            else\n                context.valueSchema = typeless_;\n\n            context.arrayElementIndex++;\n        }\n        return true;\n    }\n\n    RAPIDJSON_FORCEINLINE bool EndValue(Context& context) const {\n        if (context.patternPropertiesValidatorCount > 0) {\n            bool otherValid = false;\n            SizeType count = context.patternPropertiesValidatorCount;\n            if (context.objectPatternValidatorType != Context::kPatternValidatorOnly)\n                otherValid = context.patternPropertiesValidators[--count]->IsValid();\n\n            bool patternValid = true;\n            for (SizeType i = 0; i < count; i++)\n                if (!context.patternPropertiesValidators[i]->IsValid()) {\n                    patternValid = false;\n                    break;\n                }\n\n            if (context.objectPatternValidatorType == Context::kPatternValidatorOnly) {\n                if (!patternValid)\n                    RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternPropertiesString());\n            }\n            else if (context.objectPatternValidatorType == Context::kPatternValidatorWithProperty) {\n                if (!patternValid || !otherValid)\n                    RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternPropertiesString());\n            }\n            else if (!patternValid && !otherValid) // kPatternValidatorWithAdditionalProperty)\n                RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternPropertiesString());\n        }\n\n        if (enum_) {\n            const uint64_t h = context.factory.GetHashCode(context.hasher);\n            for (SizeType i = 0; i < enumCount_; i++)\n                if (enum_[i] == h)\n                    goto foundEnum;\n            RAPIDJSON_INVALID_KEYWORD_RETURN(GetEnumString());\n            foundEnum:;\n        }\n\n        if (allOf_.schemas)\n            for (SizeType i = allOf_.begin; i < allOf_.begin + allOf_.count; i++)\n                if (!context.validators[i]->IsValid())\n                    RAPIDJSON_INVALID_KEYWORD_RETURN(GetAllOfString());\n        \n        if (anyOf_.schemas) {\n            for (SizeType i = anyOf_.begin; i < anyOf_.begin + anyOf_.count; i++)\n                if (context.validators[i]->IsValid())\n                    goto foundAny;\n            RAPIDJSON_INVALID_KEYWORD_RETURN(GetAnyOfString());\n            foundAny:;\n        }\n\n        if (oneOf_.schemas) {\n            bool oneValid = false;\n            for (SizeType i = oneOf_.begin; i < oneOf_.begin + oneOf_.count; i++)\n                if (context.validators[i]->IsValid()) {\n                    if (oneValid)\n                        RAPIDJSON_INVALID_KEYWORD_RETURN(GetOneOfString());\n                    else\n                        oneValid = true;\n                }\n            if (!oneValid)\n                RAPIDJSON_INVALID_KEYWORD_RETURN(GetOneOfString());\n        }\n\n        if (not_ && context.validators[notValidatorIndex_]->IsValid())\n            RAPIDJSON_INVALID_KEYWORD_RETURN(GetNotString());\n\n        return true;\n    }\n\n    bool Null(Context& context) const { \n        if (!(type_ & (1 << kNullSchemaType)))\n            RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());\n        return CreateParallelValidator(context);\n    }\n    \n    bool Bool(Context& context, bool) const { \n        if (!(type_ & (1 << kBooleanSchemaType)))\n            RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());\n        return CreateParallelValidator(context);\n    }\n\n    bool Int(Context& context, int i) const {\n        if (!CheckInt(context, i))\n            return false;\n        return CreateParallelValidator(context);\n    }\n\n    bool Uint(Context& context, unsigned u) const {\n        if (!CheckUint(context, u))\n            return false;\n        return CreateParallelValidator(context);\n    }\n\n    bool Int64(Context& context, int64_t i) const {\n        if (!CheckInt(context, i))\n            return false;\n        return CreateParallelValidator(context);\n    }\n\n    bool Uint64(Context& context, uint64_t u) const {\n        if (!CheckUint(context, u))\n            return false;\n        return CreateParallelValidator(context);\n    }\n\n    bool Double(Context& context, double d) const {\n        if (!(type_ & (1 << kNumberSchemaType)))\n            RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());\n\n        if (!minimum_.IsNull() && !CheckDoubleMinimum(context, d))\n            return false;\n\n        if (!maximum_.IsNull() && !CheckDoubleMaximum(context, d))\n            return false;\n        \n        if (!multipleOf_.IsNull() && !CheckDoubleMultipleOf(context, d))\n            return false;\n        \n        return CreateParallelValidator(context);\n    }\n    \n    bool String(Context& context, const Ch* str, SizeType length, bool) const {\n        if (!(type_ & (1 << kStringSchemaType)))\n            RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());\n\n        if (minLength_ != 0 || maxLength_ != SizeType(~0)) {\n            SizeType count;\n            if (internal::CountStringCodePoint<EncodingType>(str, length, &count)) {\n                if (count < minLength_)\n                    RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinLengthString());\n                if (count > maxLength_)\n                    RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaxLengthString());\n            }\n        }\n\n        if (pattern_ && !IsPatternMatch(pattern_, str, length))\n            RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternString());\n\n        return CreateParallelValidator(context);\n    }\n\n    bool StartObject(Context& context) const { \n        if (!(type_ & (1 << kObjectSchemaType)))\n            RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());\n\n        if (hasDependencies_ || hasRequired_) {\n            context.propertyExist = static_cast<bool*>(context.factory.MallocState(sizeof(bool) * propertyCount_));\n            std::memset(context.propertyExist, 0, sizeof(bool) * propertyCount_);\n        }\n\n        if (patternProperties_) { // pre-allocate schema array\n            SizeType count = patternPropertyCount_ + 1; // extra for valuePatternValidatorType\n            context.patternPropertiesSchemas = static_cast<const SchemaType**>(context.factory.MallocState(sizeof(const SchemaType*) * count));\n            context.patternPropertiesSchemaCount = 0;\n            std::memset(context.patternPropertiesSchemas, 0, sizeof(SchemaType*) * count);\n        }\n\n        return CreateParallelValidator(context);\n    }\n    \n    bool Key(Context& context, const Ch* str, SizeType len, bool) const {\n        if (patternProperties_) {\n            context.patternPropertiesSchemaCount = 0;\n            for (SizeType i = 0; i < patternPropertyCount_; i++)\n                if (patternProperties_[i].pattern && IsPatternMatch(patternProperties_[i].pattern, str, len))\n                    context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = patternProperties_[i].schema;\n        }\n\n        SizeType index;\n        if (FindPropertyIndex(ValueType(str, len).Move(), &index)) {\n            if (context.patternPropertiesSchemaCount > 0) {\n                context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = properties_[index].schema;\n                context.valueSchema = typeless_;\n                context.valuePatternValidatorType = Context::kPatternValidatorWithProperty;\n            }\n            else\n                context.valueSchema = properties_[index].schema;\n\n            if (context.propertyExist)\n                context.propertyExist[index] = true;\n\n            return true;\n        }\n\n        if (additionalPropertiesSchema_) {\n            if (additionalPropertiesSchema_ && context.patternPropertiesSchemaCount > 0) {\n                context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = additionalPropertiesSchema_;\n                context.valueSchema = typeless_;\n                context.valuePatternValidatorType = Context::kPatternValidatorWithAdditionalProperty;\n            }\n            else\n                context.valueSchema = additionalPropertiesSchema_;\n            return true;\n        }\n        else if (additionalProperties_) {\n            context.valueSchema = typeless_;\n            return true;\n        }\n\n        if (context.patternPropertiesSchemaCount == 0) // patternProperties are not additional properties\n            RAPIDJSON_INVALID_KEYWORD_RETURN(GetAdditionalPropertiesString());\n\n        return true;\n    }\n\n    bool EndObject(Context& context, SizeType memberCount) const {\n        if (hasRequired_)\n            for (SizeType index = 0; index < propertyCount_; index++)\n                if (properties_[index].required)\n                    if (!context.propertyExist[index])\n                        RAPIDJSON_INVALID_KEYWORD_RETURN(GetRequiredString());\n\n        if (memberCount < minProperties_)\n            RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinPropertiesString());\n\n        if (memberCount > maxProperties_)\n            RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaxPropertiesString());\n\n        if (hasDependencies_) {\n            for (SizeType sourceIndex = 0; sourceIndex < propertyCount_; sourceIndex++)\n                if (context.propertyExist[sourceIndex]) {\n                    if (properties_[sourceIndex].dependencies) {\n                        for (SizeType targetIndex = 0; targetIndex < propertyCount_; targetIndex++)\n                            if (properties_[sourceIndex].dependencies[targetIndex] && !context.propertyExist[targetIndex])\n                                RAPIDJSON_INVALID_KEYWORD_RETURN(GetDependenciesString());\n                    }\n                    else if (properties_[sourceIndex].dependenciesSchema)\n                        if (!context.validators[properties_[sourceIndex].dependenciesValidatorIndex]->IsValid())\n                            RAPIDJSON_INVALID_KEYWORD_RETURN(GetDependenciesString());\n                }\n        }\n\n        return true;\n    }\n\n    bool StartArray(Context& context) const { \n        if (!(type_ & (1 << kArraySchemaType)))\n            RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());\n\n        context.arrayElementIndex = 0;\n        context.inArray = true;\n\n        return CreateParallelValidator(context);\n    }\n\n    bool EndArray(Context& context, SizeType elementCount) const { \n        context.inArray = false;\n        \n        if (elementCount < minItems_)\n            RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinItemsString());\n        \n        if (elementCount > maxItems_)\n            RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaxItemsString());\n\n        return true;\n    }\n\n    // Generate functions for string literal according to Ch\n#define RAPIDJSON_STRING_(name, ...) \\\n    static const ValueType& Get##name##String() {\\\n        static const Ch s[] = { __VA_ARGS__, '\\0' };\\\n        static const ValueType v(s, sizeof(s) / sizeof(Ch) - 1);\\\n        return v;\\\n    }\n\n    RAPIDJSON_STRING_(Null, 'n', 'u', 'l', 'l')\n    RAPIDJSON_STRING_(Boolean, 'b', 'o', 'o', 'l', 'e', 'a', 'n')\n    RAPIDJSON_STRING_(Object, 'o', 'b', 'j', 'e', 'c', 't')\n    RAPIDJSON_STRING_(Array, 'a', 'r', 'r', 'a', 'y')\n    RAPIDJSON_STRING_(String, 's', 't', 'r', 'i', 'n', 'g')\n    RAPIDJSON_STRING_(Number, 'n', 'u', 'm', 'b', 'e', 'r')\n    RAPIDJSON_STRING_(Integer, 'i', 'n', 't', 'e', 'g', 'e', 'r')\n    RAPIDJSON_STRING_(Type, 't', 'y', 'p', 'e')\n    RAPIDJSON_STRING_(Enum, 'e', 'n', 'u', 'm')\n    RAPIDJSON_STRING_(AllOf, 'a', 'l', 'l', 'O', 'f')\n    RAPIDJSON_STRING_(AnyOf, 'a', 'n', 'y', 'O', 'f')\n    RAPIDJSON_STRING_(OneOf, 'o', 'n', 'e', 'O', 'f')\n    RAPIDJSON_STRING_(Not, 'n', 'o', 't')\n    RAPIDJSON_STRING_(Properties, 'p', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's')\n    RAPIDJSON_STRING_(Required, 'r', 'e', 'q', 'u', 'i', 'r', 'e', 'd')\n    RAPIDJSON_STRING_(Dependencies, 'd', 'e', 'p', 'e', 'n', 'd', 'e', 'n', 'c', 'i', 'e', 's')\n    RAPIDJSON_STRING_(PatternProperties, 'p', 'a', 't', 't', 'e', 'r', 'n', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's')\n    RAPIDJSON_STRING_(AdditionalProperties, 'a', 'd', 'd', 'i', 't', 'i', 'o', 'n', 'a', 'l', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's')\n    RAPIDJSON_STRING_(MinProperties, 'm', 'i', 'n', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's')\n    RAPIDJSON_STRING_(MaxProperties, 'm', 'a', 'x', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's')\n    RAPIDJSON_STRING_(Items, 'i', 't', 'e', 'm', 's')\n    RAPIDJSON_STRING_(MinItems, 'm', 'i', 'n', 'I', 't', 'e', 'm', 's')\n    RAPIDJSON_STRING_(MaxItems, 'm', 'a', 'x', 'I', 't', 'e', 'm', 's')\n    RAPIDJSON_STRING_(AdditionalItems, 'a', 'd', 'd', 'i', 't', 'i', 'o', 'n', 'a', 'l', 'I', 't', 'e', 'm', 's')\n    RAPIDJSON_STRING_(UniqueItems, 'u', 'n', 'i', 'q', 'u', 'e', 'I', 't', 'e', 'm', 's')\n    RAPIDJSON_STRING_(MinLength, 'm', 'i', 'n', 'L', 'e', 'n', 'g', 't', 'h')\n    RAPIDJSON_STRING_(MaxLength, 'm', 'a', 'x', 'L', 'e', 'n', 'g', 't', 'h')\n    RAPIDJSON_STRING_(Pattern, 'p', 'a', 't', 't', 'e', 'r', 'n')\n    RAPIDJSON_STRING_(Minimum, 'm', 'i', 'n', 'i', 'm', 'u', 'm')\n    RAPIDJSON_STRING_(Maximum, 'm', 'a', 'x', 'i', 'm', 'u', 'm')\n    RAPIDJSON_STRING_(ExclusiveMinimum, 'e', 'x', 'c', 'l', 'u', 's', 'i', 'v', 'e', 'M', 'i', 'n', 'i', 'm', 'u', 'm')\n    RAPIDJSON_STRING_(ExclusiveMaximum, 'e', 'x', 'c', 'l', 'u', 's', 'i', 'v', 'e', 'M', 'a', 'x', 'i', 'm', 'u', 'm')\n    RAPIDJSON_STRING_(MultipleOf, 'm', 'u', 'l', 't', 'i', 'p', 'l', 'e', 'O', 'f')\n\n#undef RAPIDJSON_STRING_\n\nprivate:\n    enum SchemaValueType {\n        kNullSchemaType,\n        kBooleanSchemaType,\n        kObjectSchemaType,\n        kArraySchemaType,\n        kStringSchemaType,\n        kNumberSchemaType,\n        kIntegerSchemaType,\n        kTotalSchemaType\n    };\n\n#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX\n        typedef internal::GenericRegex<EncodingType> RegexType;\n#elif RAPIDJSON_SCHEMA_USE_STDREGEX\n        typedef std::basic_regex<Ch> RegexType;\n#else\n        typedef char RegexType;\n#endif\n\n    struct SchemaArray {\n        SchemaArray() : schemas(), count() {}\n        ~SchemaArray() { AllocatorType::Free(schemas); }\n        const SchemaType** schemas;\n        SizeType begin; // begin index of context.validators\n        SizeType count;\n    };\n\n    template <typename V1, typename V2>\n    void AddUniqueElement(V1& a, const V2& v) {\n        for (typename V1::ConstValueIterator itr = a.Begin(); itr != a.End(); ++itr)\n            if (*itr == v)\n                return;\n        V1 c(v, *allocator_);\n        a.PushBack(c, *allocator_);\n    }\n\n    static const ValueType* GetMember(const ValueType& value, const ValueType& name) {\n        typename ValueType::ConstMemberIterator itr = value.FindMember(name);\n        return itr != value.MemberEnd() ? &(itr->value) : 0;\n    }\n\n    static void AssignIfExist(bool& out, const ValueType& value, const ValueType& name) {\n        if (const ValueType* v = GetMember(value, name))\n            if (v->IsBool())\n                out = v->GetBool();\n    }\n\n    static void AssignIfExist(SizeType& out, const ValueType& value, const ValueType& name) {\n        if (const ValueType* v = GetMember(value, name))\n            if (v->IsUint64() && v->GetUint64() <= SizeType(~0))\n                out = static_cast<SizeType>(v->GetUint64());\n    }\n\n    void AssignIfExist(SchemaArray& out, SchemaDocumentType& schemaDocument, const PointerType& p, const ValueType& value, const ValueType& name, const ValueType& document) {\n        if (const ValueType* v = GetMember(value, name)) {\n            if (v->IsArray() && v->Size() > 0) {\n                PointerType q = p.Append(name, allocator_);\n                out.count = v->Size();\n                out.schemas = static_cast<const Schema**>(allocator_->Malloc(out.count * sizeof(const Schema*)));\n                memset(out.schemas, 0, sizeof(Schema*)* out.count);\n                for (SizeType i = 0; i < out.count; i++)\n                    schemaDocument.CreateSchema(&out.schemas[i], q.Append(i, allocator_), (*v)[i], document);\n                out.begin = validatorCount_;\n                validatorCount_ += out.count;\n            }\n        }\n    }\n\n#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX\n    template <typename ValueType>\n    RegexType* CreatePattern(const ValueType& value) {\n        if (value.IsString()) {\n            RegexType* r = new (allocator_->Malloc(sizeof(RegexType))) RegexType(value.GetString());\n            if (!r->IsValid()) {\n                r->~RegexType();\n                AllocatorType::Free(r);\n                r = 0;\n            }\n            return r;\n        }\n        return 0;\n    }\n\n    static bool IsPatternMatch(const RegexType* pattern, const Ch *str, SizeType) {\n        GenericRegexSearch<RegexType> rs(*pattern);\n        return rs.Search(str);\n    }\n#elif RAPIDJSON_SCHEMA_USE_STDREGEX\n    template <typename ValueType>\n    RegexType* CreatePattern(const ValueType& value) {\n        if (value.IsString())\n            try {\n                return new (allocator_->Malloc(sizeof(RegexType))) RegexType(value.GetString(), std::size_t(value.GetStringLength()), std::regex_constants::ECMAScript);\n            }\n            catch (const std::regex_error&) {\n            }\n        return 0;\n    }\n\n    static bool IsPatternMatch(const RegexType* pattern, const Ch *str, SizeType length) {\n        std::match_results<const Ch*> r;\n        return std::regex_search(str, str + length, r, *pattern);\n    }\n#else\n    template <typename ValueType>\n    RegexType* CreatePattern(const ValueType&) { return 0; }\n\n    static bool IsPatternMatch(const RegexType*, const Ch *, SizeType) { return true; }\n#endif // RAPIDJSON_SCHEMA_USE_STDREGEX\n\n    void AddType(const ValueType& type) {\n        if      (type == GetNullString()   ) type_ |= 1 << kNullSchemaType;\n        else if (type == GetBooleanString()) type_ |= 1 << kBooleanSchemaType;\n        else if (type == GetObjectString() ) type_ |= 1 << kObjectSchemaType;\n        else if (type == GetArrayString()  ) type_ |= 1 << kArraySchemaType;\n        else if (type == GetStringString() ) type_ |= 1 << kStringSchemaType;\n        else if (type == GetIntegerString()) type_ |= 1 << kIntegerSchemaType;\n        else if (type == GetNumberString() ) type_ |= (1 << kNumberSchemaType) | (1 << kIntegerSchemaType);\n    }\n\n    bool CreateParallelValidator(Context& context) const {\n        if (enum_ || context.arrayUniqueness)\n            context.hasher = context.factory.CreateHasher();\n\n        if (validatorCount_) {\n            RAPIDJSON_ASSERT(context.validators == 0);\n            context.validators = static_cast<ISchemaValidator**>(context.factory.MallocState(sizeof(ISchemaValidator*) * validatorCount_));\n            context.validatorCount = validatorCount_;\n\n            if (allOf_.schemas)\n                CreateSchemaValidators(context, allOf_);\n\n            if (anyOf_.schemas)\n                CreateSchemaValidators(context, anyOf_);\n            \n            if (oneOf_.schemas)\n                CreateSchemaValidators(context, oneOf_);\n            \n            if (not_)\n                context.validators[notValidatorIndex_] = context.factory.CreateSchemaValidator(*not_);\n            \n            if (hasSchemaDependencies_) {\n                for (SizeType i = 0; i < propertyCount_; i++)\n                    if (properties_[i].dependenciesSchema)\n                        context.validators[properties_[i].dependenciesValidatorIndex] = context.factory.CreateSchemaValidator(*properties_[i].dependenciesSchema);\n            }\n        }\n\n        return true;\n    }\n\n    void CreateSchemaValidators(Context& context, const SchemaArray& schemas) const {\n        for (SizeType i = 0; i < schemas.count; i++)\n            context.validators[schemas.begin + i] = context.factory.CreateSchemaValidator(*schemas.schemas[i]);\n    }\n\n    // O(n)\n    bool FindPropertyIndex(const ValueType& name, SizeType* outIndex) const {\n        SizeType len = name.GetStringLength();\n        const Ch* str = name.GetString();\n        for (SizeType index = 0; index < propertyCount_; index++)\n            if (properties_[index].name.GetStringLength() == len && \n                (std::memcmp(properties_[index].name.GetString(), str, sizeof(Ch) * len) == 0))\n            {\n                *outIndex = index;\n                return true;\n            }\n        return false;\n    }\n\n    bool CheckInt(Context& context, int64_t i) const {\n        if (!(type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType))))\n            RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());\n\n        if (!minimum_.IsNull()) {\n            if (minimum_.IsInt64()) {\n                if (exclusiveMinimum_ ? i <= minimum_.GetInt64() : i < minimum_.GetInt64())\n                    RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString());\n            }\n            else if (minimum_.IsUint64()) {\n                RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString()); // i <= max(int64_t) < minimum.GetUint64()\n            }\n            else if (!CheckDoubleMinimum(context, static_cast<double>(i)))\n                return false;\n        }\n\n        if (!maximum_.IsNull()) {\n            if (maximum_.IsInt64()) {\n                if (exclusiveMaximum_ ? i >= maximum_.GetInt64() : i > maximum_.GetInt64())\n                    RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString());\n            }\n            else if (maximum_.IsUint64())\n                /* do nothing */; // i <= max(int64_t) < maximum_.GetUint64()\n            else if (!CheckDoubleMaximum(context, static_cast<double>(i)))\n                return false;\n        }\n\n        if (!multipleOf_.IsNull()) {\n            if (multipleOf_.IsUint64()) {\n                if (static_cast<uint64_t>(i >= 0 ? i : -i) % multipleOf_.GetUint64() != 0)\n                    RAPIDJSON_INVALID_KEYWORD_RETURN(GetMultipleOfString());\n            }\n            else if (!CheckDoubleMultipleOf(context, static_cast<double>(i)))\n                return false;\n        }\n\n        return true;\n    }\n\n    bool CheckUint(Context& context, uint64_t i) const {\n        if (!(type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType))))\n            RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());\n\n        if (!minimum_.IsNull()) {\n            if (minimum_.IsUint64()) {\n                if (exclusiveMinimum_ ? i <= minimum_.GetUint64() : i < minimum_.GetUint64())\n                    RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString());\n            }\n            else if (minimum_.IsInt64())\n                /* do nothing */; // i >= 0 > minimum.Getint64()\n            else if (!CheckDoubleMinimum(context, static_cast<double>(i)))\n                return false;\n        }\n\n        if (!maximum_.IsNull()) {\n            if (maximum_.IsUint64()) {\n                if (exclusiveMaximum_ ? i >= maximum_.GetUint64() : i > maximum_.GetUint64())\n                    RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString());\n            }\n            else if (maximum_.IsInt64())\n                RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString()); // i >= 0 > maximum_\n            else if (!CheckDoubleMaximum(context, static_cast<double>(i)))\n                return false;\n        }\n\n        if (!multipleOf_.IsNull()) {\n            if (multipleOf_.IsUint64()) {\n                if (i % multipleOf_.GetUint64() != 0)\n                    RAPIDJSON_INVALID_KEYWORD_RETURN(GetMultipleOfString());\n            }\n            else if (!CheckDoubleMultipleOf(context, static_cast<double>(i)))\n                return false;\n        }\n\n        return true;\n    }\n\n    bool CheckDoubleMinimum(Context& context, double d) const {\n        if (exclusiveMinimum_ ? d <= minimum_.GetDouble() : d < minimum_.GetDouble())\n            RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString());\n        return true;\n    }\n\n    bool CheckDoubleMaximum(Context& context, double d) const {\n        if (exclusiveMaximum_ ? d >= maximum_.GetDouble() : d > maximum_.GetDouble())\n            RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString());\n        return true;\n    }\n\n    bool CheckDoubleMultipleOf(Context& context, double d) const {\n        double a = std::abs(d), b = std::abs(multipleOf_.GetDouble());\n        double q = std::floor(a / b);\n        double r = a - q * b;\n        if (r > 0.0)\n            RAPIDJSON_INVALID_KEYWORD_RETURN(GetMultipleOfString());\n        return true;\n    }\n\n    struct Property {\n        Property() : schema(), dependenciesSchema(), dependenciesValidatorIndex(), dependencies(), required(false) {}\n        ~Property() { AllocatorType::Free(dependencies); }\n        SValue name;\n        const SchemaType* schema;\n        const SchemaType* dependenciesSchema;\n        SizeType dependenciesValidatorIndex;\n        bool* dependencies;\n        bool required;\n    };\n\n    struct PatternProperty {\n        PatternProperty() : schema(), pattern() {}\n        ~PatternProperty() { \n            if (pattern) {\n                pattern->~RegexType();\n                AllocatorType::Free(pattern);\n            }\n        }\n        const SchemaType* schema;\n        RegexType* pattern;\n    };\n\n    AllocatorType* allocator_;\n    const SchemaType* typeless_;\n    uint64_t* enum_;\n    SizeType enumCount_;\n    SchemaArray allOf_;\n    SchemaArray anyOf_;\n    SchemaArray oneOf_;\n    const SchemaType* not_;\n    unsigned type_; // bitmask of kSchemaType\n    SizeType validatorCount_;\n    SizeType notValidatorIndex_;\n\n    Property* properties_;\n    const SchemaType* additionalPropertiesSchema_;\n    PatternProperty* patternProperties_;\n    SizeType patternPropertyCount_;\n    SizeType propertyCount_;\n    SizeType minProperties_;\n    SizeType maxProperties_;\n    bool additionalProperties_;\n    bool hasDependencies_;\n    bool hasRequired_;\n    bool hasSchemaDependencies_;\n\n    const SchemaType* additionalItemsSchema_;\n    const SchemaType* itemsList_;\n    const SchemaType** itemsTuple_;\n    SizeType itemsTupleCount_;\n    SizeType minItems_;\n    SizeType maxItems_;\n    bool additionalItems_;\n    bool uniqueItems_;\n\n    RegexType* pattern_;\n    SizeType minLength_;\n    SizeType maxLength_;\n\n    SValue minimum_;\n    SValue maximum_;\n    SValue multipleOf_;\n    bool exclusiveMinimum_;\n    bool exclusiveMaximum_;\n};\n\ntemplate<typename Stack, typename Ch>\nstruct TokenHelper {\n    RAPIDJSON_FORCEINLINE static void AppendIndexToken(Stack& documentStack, SizeType index) {\n        *documentStack.template Push<Ch>() = '/';\n        char buffer[21];\n        size_t length = static_cast<size_t>((sizeof(SizeType) == 4 ? u32toa(index, buffer) : u64toa(index, buffer)) - buffer);\n        for (size_t i = 0; i < length; i++)\n            *documentStack.template Push<Ch>() = buffer[i];\n    }\n};\n\n// Partial specialized version for char to prevent buffer copying.\ntemplate <typename Stack>\nstruct TokenHelper<Stack, char> {\n    RAPIDJSON_FORCEINLINE static void AppendIndexToken(Stack& documentStack, SizeType index) {\n        if (sizeof(SizeType) == 4) {\n            char *buffer = documentStack.template Push<char>(1 + 10); // '/' + uint\n            *buffer++ = '/';\n            const char* end = internal::u32toa(index, buffer);\n             documentStack.template Pop<char>(static_cast<size_t>(10 - (end - buffer)));\n        }\n        else {\n            char *buffer = documentStack.template Push<char>(1 + 20); // '/' + uint64\n            *buffer++ = '/';\n            const char* end = internal::u64toa(index, buffer);\n            documentStack.template Pop<char>(static_cast<size_t>(20 - (end - buffer)));\n        }\n    }\n};\n\n} // namespace internal\n\n///////////////////////////////////////////////////////////////////////////////\n// IGenericRemoteSchemaDocumentProvider\n\ntemplate <typename SchemaDocumentType>\nclass IGenericRemoteSchemaDocumentProvider {\npublic:\n    typedef typename SchemaDocumentType::Ch Ch;\n\n    virtual ~IGenericRemoteSchemaDocumentProvider() {}\n    virtual const SchemaDocumentType* GetRemoteDocument(const Ch* uri, SizeType length) = 0;\n};\n\n///////////////////////////////////////////////////////////////////////////////\n// GenericSchemaDocument\n\n//! JSON schema document.\n/*!\n    A JSON schema document is a compiled version of a JSON schema.\n    It is basically a tree of internal::Schema.\n\n    \\note This is an immutable class (i.e. its instance cannot be modified after construction).\n    \\tparam ValueT Type of JSON value (e.g. \\c Value ), which also determine the encoding.\n    \\tparam Allocator Allocator type for allocating memory of this document.\n*/\ntemplate <typename ValueT, typename Allocator = CrtAllocator>\nclass GenericSchemaDocument {\npublic:\n    typedef ValueT ValueType;\n    typedef IGenericRemoteSchemaDocumentProvider<GenericSchemaDocument> IRemoteSchemaDocumentProviderType;\n    typedef Allocator AllocatorType;\n    typedef typename ValueType::EncodingType EncodingType;\n    typedef typename EncodingType::Ch Ch;\n    typedef internal::Schema<GenericSchemaDocument> SchemaType;\n    typedef GenericPointer<ValueType, Allocator> PointerType;\n    friend class internal::Schema<GenericSchemaDocument>;\n    template <typename, typename, typename>\n    friend class GenericSchemaValidator;\n\n    //! Constructor.\n    /*!\n        Compile a JSON document into schema document.\n\n        \\param document A JSON document as source.\n        \\param remoteProvider An optional remote schema document provider for resolving remote reference. Can be null.\n        \\param allocator An optional allocator instance for allocating memory. Can be null.\n    */\n    explicit GenericSchemaDocument(const ValueType& document, IRemoteSchemaDocumentProviderType* remoteProvider = 0, Allocator* allocator = 0) :\n        remoteProvider_(remoteProvider),\n        allocator_(allocator),\n        ownAllocator_(),\n        root_(),\n        typeless_(),\n        schemaMap_(allocator, kInitialSchemaMapSize),\n        schemaRef_(allocator, kInitialSchemaRefSize)\n    {\n        if (!allocator_)\n            ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator());\n\n        typeless_ = static_cast<SchemaType*>(allocator_->Malloc(sizeof(SchemaType)));\n        new (typeless_) SchemaType(this, PointerType(), ValueType(kObjectType).Move(), ValueType(kObjectType).Move(), 0);\n\n        // Generate root schema, it will call CreateSchema() to create sub-schemas,\n        // And call AddRefSchema() if there are $ref.\n        CreateSchemaRecursive(&root_, PointerType(), document, document);\n\n        // Resolve $ref\n        while (!schemaRef_.Empty()) {\n            SchemaRefEntry* refEntry = schemaRef_.template Pop<SchemaRefEntry>(1);\n            if (const SchemaType* s = GetSchema(refEntry->target)) {\n                if (refEntry->schema)\n                    *refEntry->schema = s;\n\n                // Create entry in map if not exist\n                if (!GetSchema(refEntry->source)) {\n                    new (schemaMap_.template Push<SchemaEntry>()) SchemaEntry(refEntry->source, const_cast<SchemaType*>(s), false, allocator_);\n                }\n            }\n            else if (refEntry->schema)\n                *refEntry->schema = typeless_;\n\n            refEntry->~SchemaRefEntry();\n        }\n\n        RAPIDJSON_ASSERT(root_ != 0);\n\n        schemaRef_.ShrinkToFit(); // Deallocate all memory for ref\n    }\n\n#if RAPIDJSON_HAS_CXX11_RVALUE_REFS\n    //! Move constructor in C++11\n    GenericSchemaDocument(GenericSchemaDocument&& rhs) RAPIDJSON_NOEXCEPT :\n        remoteProvider_(rhs.remoteProvider_),\n        allocator_(rhs.allocator_),\n        ownAllocator_(rhs.ownAllocator_),\n        root_(rhs.root_),\n        typeless_(rhs.typeless_),\n        schemaMap_(std::move(rhs.schemaMap_)),\n        schemaRef_(std::move(rhs.schemaRef_))\n    {\n        rhs.remoteProvider_ = 0;\n        rhs.allocator_ = 0;\n        rhs.ownAllocator_ = 0;\n        rhs.typeless_ = 0;\n    }\n#endif\n\n    //! Destructor\n    ~GenericSchemaDocument() {\n        while (!schemaMap_.Empty())\n            schemaMap_.template Pop<SchemaEntry>(1)->~SchemaEntry();\n\n        if (typeless_) {\n            typeless_->~SchemaType();\n            Allocator::Free(typeless_);\n        }\n\n        RAPIDJSON_DELETE(ownAllocator_);\n    }\n\n    //! Get the root schema.\n    const SchemaType& GetRoot() const { return *root_; }\n\nprivate:\n    //! Prohibit copying\n    GenericSchemaDocument(const GenericSchemaDocument&);\n    //! Prohibit assignment\n    GenericSchemaDocument& operator=(const GenericSchemaDocument&);\n\n    struct SchemaRefEntry {\n        SchemaRefEntry(const PointerType& s, const PointerType& t, const SchemaType** outSchema, Allocator *allocator) : source(s, allocator), target(t, allocator), schema(outSchema) {}\n        PointerType source;\n        PointerType target;\n        const SchemaType** schema;\n    };\n\n    struct SchemaEntry {\n        SchemaEntry(const PointerType& p, SchemaType* s, bool o, Allocator* allocator) : pointer(p, allocator), schema(s), owned(o) {}\n        ~SchemaEntry() {\n            if (owned) {\n                schema->~SchemaType();\n                Allocator::Free(schema);\n            }\n        }\n        PointerType pointer;\n        SchemaType* schema;\n        bool owned;\n    };\n\n    void CreateSchemaRecursive(const SchemaType** schema, const PointerType& pointer, const ValueType& v, const ValueType& document) {\n        if (schema)\n            *schema = typeless_;\n\n        if (v.GetType() == kObjectType) {\n            const SchemaType* s = GetSchema(pointer);\n            if (!s)\n                CreateSchema(schema, pointer, v, document);\n\n            for (typename ValueType::ConstMemberIterator itr = v.MemberBegin(); itr != v.MemberEnd(); ++itr)\n                CreateSchemaRecursive(0, pointer.Append(itr->name, allocator_), itr->value, document);\n        }\n        else if (v.GetType() == kArrayType)\n            for (SizeType i = 0; i < v.Size(); i++)\n                CreateSchemaRecursive(0, pointer.Append(i, allocator_), v[i], document);\n    }\n\n    void CreateSchema(const SchemaType** schema, const PointerType& pointer, const ValueType& v, const ValueType& document) {\n        RAPIDJSON_ASSERT(pointer.IsValid());\n        if (v.IsObject()) {\n            if (!HandleRefSchema(pointer, schema, v, document)) {\n                SchemaType* s = new (allocator_->Malloc(sizeof(SchemaType))) SchemaType(this, pointer, v, document, allocator_);\n                new (schemaMap_.template Push<SchemaEntry>()) SchemaEntry(pointer, s, true, allocator_);\n                if (schema)\n                    *schema = s;\n            }\n        }\n    }\n\n    bool HandleRefSchema(const PointerType& source, const SchemaType** schema, const ValueType& v, const ValueType& document) {\n        static const Ch kRefString[] = { '$', 'r', 'e', 'f', '\\0' };\n        static const ValueType kRefValue(kRefString, 4);\n\n        typename ValueType::ConstMemberIterator itr = v.FindMember(kRefValue);\n        if (itr == v.MemberEnd())\n            return false;\n\n        if (itr->value.IsString()) {\n            SizeType len = itr->value.GetStringLength();\n            if (len > 0) {\n                const Ch* s = itr->value.GetString();\n                SizeType i = 0;\n                while (i < len && s[i] != '#') // Find the first #\n                    i++;\n\n                if (i > 0) { // Remote reference, resolve immediately\n                    if (remoteProvider_) {\n                        if (const GenericSchemaDocument* remoteDocument = remoteProvider_->GetRemoteDocument(s, i)) {\n                            PointerType pointer(&s[i], len - i, allocator_);\n                            if (pointer.IsValid()) {\n                                if (const SchemaType* sc = remoteDocument->GetSchema(pointer)) {\n                                    if (schema)\n                                        *schema = sc;\n                                    return true;\n                                }\n                            }\n                        }\n                    }\n                }\n                else if (s[i] == '#') { // Local reference, defer resolution\n                    PointerType pointer(&s[i], len - i, allocator_);\n                    if (pointer.IsValid()) {\n                        if (const ValueType* nv = pointer.Get(document))\n                            if (HandleRefSchema(source, schema, *nv, document))\n                                return true;\n\n                        new (schemaRef_.template Push<SchemaRefEntry>()) SchemaRefEntry(source, pointer, schema, allocator_);\n                        return true;\n                    }\n                }\n            }\n        }\n        return false;\n    }\n\n    const SchemaType* GetSchema(const PointerType& pointer) const {\n        for (const SchemaEntry* target = schemaMap_.template Bottom<SchemaEntry>(); target != schemaMap_.template End<SchemaEntry>(); ++target)\n            if (pointer == target->pointer)\n                return target->schema;\n        return 0;\n    }\n\n    PointerType GetPointer(const SchemaType* schema) const {\n        for (const SchemaEntry* target = schemaMap_.template Bottom<SchemaEntry>(); target != schemaMap_.template End<SchemaEntry>(); ++target)\n            if (schema == target->schema)\n                return target->pointer;\n        return PointerType();\n    }\n\n    const SchemaType* GetTypeless() const { return typeless_; }\n\n    static const size_t kInitialSchemaMapSize = 64;\n    static const size_t kInitialSchemaRefSize = 64;\n\n    IRemoteSchemaDocumentProviderType* remoteProvider_;\n    Allocator *allocator_;\n    Allocator *ownAllocator_;\n    const SchemaType* root_;                //!< Root schema.\n    SchemaType* typeless_;\n    internal::Stack<Allocator> schemaMap_;  // Stores created Pointer -> Schemas\n    internal::Stack<Allocator> schemaRef_;  // Stores Pointer from $ref and schema which holds the $ref\n};\n\n//! GenericSchemaDocument using Value type.\ntypedef GenericSchemaDocument<Value> SchemaDocument;\n//! IGenericRemoteSchemaDocumentProvider using SchemaDocument.\ntypedef IGenericRemoteSchemaDocumentProvider<SchemaDocument> IRemoteSchemaDocumentProvider;\n\n///////////////////////////////////////////////////////////////////////////////\n// GenericSchemaValidator\n\n//! JSON Schema Validator.\n/*!\n    A SAX style JSON schema validator.\n    It uses a \\c GenericSchemaDocument to validate SAX events.\n    It delegates the incoming SAX events to an output handler.\n    The default output handler does nothing.\n    It can be reused multiple times by calling \\c Reset().\n\n    \\tparam SchemaDocumentType Type of schema document.\n    \\tparam OutputHandler Type of output handler. Default handler does nothing.\n    \\tparam StateAllocator Allocator for storing the internal validation states.\n*/\ntemplate <\n    typename SchemaDocumentType,\n    typename OutputHandler = BaseReaderHandler<typename SchemaDocumentType::SchemaType::EncodingType>,\n    typename StateAllocator = CrtAllocator>\nclass GenericSchemaValidator :\n    public internal::ISchemaStateFactory<typename SchemaDocumentType::SchemaType>, \n    public internal::ISchemaValidator\n{\npublic:\n    typedef typename SchemaDocumentType::SchemaType SchemaType;\n    typedef typename SchemaDocumentType::PointerType PointerType;\n    typedef typename SchemaType::EncodingType EncodingType;\n    typedef typename EncodingType::Ch Ch;\n\n    //! Constructor without output handler.\n    /*!\n        \\param schemaDocument The schema document to conform to.\n        \\param allocator Optional allocator for storing internal validation states.\n        \\param schemaStackCapacity Optional initial capacity of schema path stack.\n        \\param documentStackCapacity Optional initial capacity of document path stack.\n    */\n    GenericSchemaValidator(\n        const SchemaDocumentType& schemaDocument,\n        StateAllocator* allocator = 0, \n        size_t schemaStackCapacity = kDefaultSchemaStackCapacity,\n        size_t documentStackCapacity = kDefaultDocumentStackCapacity)\n        :\n        schemaDocument_(&schemaDocument),\n        root_(schemaDocument.GetRoot()),\n        stateAllocator_(allocator),\n        ownStateAllocator_(0),\n        schemaStack_(allocator, schemaStackCapacity),\n        documentStack_(allocator, documentStackCapacity),\n        outputHandler_(CreateNullHandler()),\n        valid_(true)\n#if RAPIDJSON_SCHEMA_VERBOSE\n        , depth_(0)\n#endif\n    {\n    }\n\n    //! Constructor with output handler.\n    /*!\n        \\param schemaDocument The schema document to conform to.\n        \\param allocator Optional allocator for storing internal validation states.\n        \\param schemaStackCapacity Optional initial capacity of schema path stack.\n        \\param documentStackCapacity Optional initial capacity of document path stack.\n    */\n    GenericSchemaValidator(\n        const SchemaDocumentType& schemaDocument,\n        OutputHandler& outputHandler,\n        StateAllocator* allocator = 0, \n        size_t schemaStackCapacity = kDefaultSchemaStackCapacity,\n        size_t documentStackCapacity = kDefaultDocumentStackCapacity)\n        :\n        schemaDocument_(&schemaDocument),\n        root_(schemaDocument.GetRoot()),\n        stateAllocator_(allocator),\n        ownStateAllocator_(0),\n        schemaStack_(allocator, schemaStackCapacity),\n        documentStack_(allocator, documentStackCapacity),\n        outputHandler_(outputHandler),\n        nullHandler_(0),\n        valid_(true)\n#if RAPIDJSON_SCHEMA_VERBOSE\n        , depth_(0)\n#endif\n    {\n    }\n\n    //! Destructor.\n    ~GenericSchemaValidator() {\n        Reset();\n        if (nullHandler_) {\n            nullHandler_->~OutputHandler();\n            StateAllocator::Free(nullHandler_);\n        }\n        RAPIDJSON_DELETE(ownStateAllocator_);\n    }\n\n    //! Reset the internal states.\n    void Reset() {\n        while (!schemaStack_.Empty())\n            PopSchema();\n        documentStack_.Clear();\n        valid_ = true;\n    }\n\n    //! Checks whether the current state is valid.\n    // Implementation of ISchemaValidator\n    virtual bool IsValid() const { return valid_; }\n\n    //! Gets the JSON pointer pointed to the invalid schema.\n    PointerType GetInvalidSchemaPointer() const {\n        return schemaStack_.Empty() ? PointerType() : schemaDocument_->GetPointer(&CurrentSchema());\n    }\n\n    //! Gets the keyword of invalid schema.\n    const Ch* GetInvalidSchemaKeyword() const {\n        return schemaStack_.Empty() ? 0 : CurrentContext().invalidKeyword;\n    }\n\n    //! Gets the JSON pointer pointed to the invalid value.\n    PointerType GetInvalidDocumentPointer() const {\n        return documentStack_.Empty() ? PointerType() : PointerType(documentStack_.template Bottom<Ch>(), documentStack_.GetSize() / sizeof(Ch));\n    }\n\n#if RAPIDJSON_SCHEMA_VERBOSE\n#define RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_() \\\nRAPIDJSON_MULTILINEMACRO_BEGIN\\\n    *documentStack_.template Push<Ch>() = '\\0';\\\n    documentStack_.template Pop<Ch>(1);\\\n    internal::PrintInvalidDocument(documentStack_.template Bottom<Ch>());\\\nRAPIDJSON_MULTILINEMACRO_END\n#else\n#define RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_()\n#endif\n\n#define RAPIDJSON_SCHEMA_HANDLE_BEGIN_(method, arg1)\\\n    if (!valid_) return false; \\\n    if (!BeginValue() || !CurrentSchema().method arg1) {\\\n        RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_();\\\n        return valid_ = false;\\\n    }\n\n#define RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2)\\\n    for (Context* context = schemaStack_.template Bottom<Context>(); context != schemaStack_.template End<Context>(); context++) {\\\n        if (context->hasher)\\\n            static_cast<HasherType*>(context->hasher)->method arg2;\\\n        if (context->validators)\\\n            for (SizeType i_ = 0; i_ < context->validatorCount; i_++)\\\n                static_cast<GenericSchemaValidator*>(context->validators[i_])->method arg2;\\\n        if (context->patternPropertiesValidators)\\\n            for (SizeType i_ = 0; i_ < context->patternPropertiesValidatorCount; i_++)\\\n                static_cast<GenericSchemaValidator*>(context->patternPropertiesValidators[i_])->method arg2;\\\n    }\n\n#define RAPIDJSON_SCHEMA_HANDLE_END_(method, arg2)\\\n    return valid_ = EndValue() && outputHandler_.method arg2\n\n#define RAPIDJSON_SCHEMA_HANDLE_VALUE_(method, arg1, arg2) \\\n    RAPIDJSON_SCHEMA_HANDLE_BEGIN_   (method, arg1);\\\n    RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2);\\\n    RAPIDJSON_SCHEMA_HANDLE_END_     (method, arg2)\n\n    bool Null()             { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Null,   (CurrentContext()   ), ( )); }\n    bool Bool(bool b)       { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Bool,   (CurrentContext(), b), (b)); }\n    bool Int(int i)         { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Int,    (CurrentContext(), i), (i)); }\n    bool Uint(unsigned u)   { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Uint,   (CurrentContext(), u), (u)); }\n    bool Int64(int64_t i)   { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Int64,  (CurrentContext(), i), (i)); }\n    bool Uint64(uint64_t u) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Uint64, (CurrentContext(), u), (u)); }\n    bool Double(double d)   { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Double, (CurrentContext(), d), (d)); }\n    bool RawNumber(const Ch* str, SizeType length, bool copy)\n                                    { RAPIDJSON_SCHEMA_HANDLE_VALUE_(String, (CurrentContext(), str, length, copy), (str, length, copy)); }\n    bool String(const Ch* str, SizeType length, bool copy)\n                                    { RAPIDJSON_SCHEMA_HANDLE_VALUE_(String, (CurrentContext(), str, length, copy), (str, length, copy)); }\n\n    bool StartObject() {\n        RAPIDJSON_SCHEMA_HANDLE_BEGIN_(StartObject, (CurrentContext()));\n        RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(StartObject, ());\n        return valid_ = outputHandler_.StartObject();\n    }\n    \n    bool Key(const Ch* str, SizeType len, bool copy) {\n        if (!valid_) return false;\n        AppendToken(str, len);\n        if (!CurrentSchema().Key(CurrentContext(), str, len, copy)) return valid_ = false;\n        RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(Key, (str, len, copy));\n        return valid_ = outputHandler_.Key(str, len, copy);\n    }\n    \n    bool EndObject(SizeType memberCount) { \n        if (!valid_) return false;\n        RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(EndObject, (memberCount));\n        if (!CurrentSchema().EndObject(CurrentContext(), memberCount)) return valid_ = false;\n        RAPIDJSON_SCHEMA_HANDLE_END_(EndObject, (memberCount));\n    }\n\n    bool StartArray() {\n        RAPIDJSON_SCHEMA_HANDLE_BEGIN_(StartArray, (CurrentContext()));\n        RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(StartArray, ());\n        return valid_ = outputHandler_.StartArray();\n    }\n    \n    bool EndArray(SizeType elementCount) {\n        if (!valid_) return false;\n        RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(EndArray, (elementCount));\n        if (!CurrentSchema().EndArray(CurrentContext(), elementCount)) return valid_ = false;\n        RAPIDJSON_SCHEMA_HANDLE_END_(EndArray, (elementCount));\n    }\n\n#undef RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_\n#undef RAPIDJSON_SCHEMA_HANDLE_BEGIN_\n#undef RAPIDJSON_SCHEMA_HANDLE_PARALLEL_\n#undef RAPIDJSON_SCHEMA_HANDLE_VALUE_\n\n    // Implementation of ISchemaStateFactory<SchemaType>\n    virtual ISchemaValidator* CreateSchemaValidator(const SchemaType& root) {\n        return new (GetStateAllocator().Malloc(sizeof(GenericSchemaValidator))) GenericSchemaValidator(*schemaDocument_, root,\n#if RAPIDJSON_SCHEMA_VERBOSE\n        depth_ + 1,\n#endif\n        &GetStateAllocator());\n    }\n\n    virtual void DestroySchemaValidator(ISchemaValidator* validator) {\n        GenericSchemaValidator* v = static_cast<GenericSchemaValidator*>(validator);\n        v->~GenericSchemaValidator();\n        StateAllocator::Free(v);\n    }\n\n    virtual void* CreateHasher() {\n        return new (GetStateAllocator().Malloc(sizeof(HasherType))) HasherType(&GetStateAllocator());\n    }\n\n    virtual uint64_t GetHashCode(void* hasher) {\n        return static_cast<HasherType*>(hasher)->GetHashCode();\n    }\n\n    virtual void DestroryHasher(void* hasher) {\n        HasherType* h = static_cast<HasherType*>(hasher);\n        h->~HasherType();\n        StateAllocator::Free(h);\n    }\n\n    virtual void* MallocState(size_t size) {\n        return GetStateAllocator().Malloc(size);\n    }\n\n    virtual void FreeState(void* p) {\n        return StateAllocator::Free(p);\n    }\n\nprivate:\n    typedef typename SchemaType::Context Context;\n    typedef GenericValue<UTF8<>, StateAllocator> HashCodeArray;\n    typedef internal::Hasher<EncodingType, StateAllocator> HasherType;\n\n    GenericSchemaValidator( \n        const SchemaDocumentType& schemaDocument,\n        const SchemaType& root,\n#if RAPIDJSON_SCHEMA_VERBOSE\n        unsigned depth,\n#endif\n        StateAllocator* allocator = 0,\n        size_t schemaStackCapacity = kDefaultSchemaStackCapacity,\n        size_t documentStackCapacity = kDefaultDocumentStackCapacity)\n        :\n        schemaDocument_(&schemaDocument),\n        root_(root),\n        stateAllocator_(allocator),\n        ownStateAllocator_(0),\n        schemaStack_(allocator, schemaStackCapacity),\n        documentStack_(allocator, documentStackCapacity),\n        outputHandler_(CreateNullHandler()),\n        valid_(true)\n#if RAPIDJSON_SCHEMA_VERBOSE\n        , depth_(depth)\n#endif\n    {\n    }\n\n    StateAllocator& GetStateAllocator() {\n        if (!stateAllocator_)\n            stateAllocator_ = ownStateAllocator_ = RAPIDJSON_NEW(StateAllocator());\n        return *stateAllocator_;\n    }\n\n    bool BeginValue() {\n        if (schemaStack_.Empty())\n            PushSchema(root_);\n        else {\n            if (CurrentContext().inArray)\n                internal::TokenHelper<internal::Stack<StateAllocator>, Ch>::AppendIndexToken(documentStack_, CurrentContext().arrayElementIndex);\n\n            if (!CurrentSchema().BeginValue(CurrentContext()))\n                return false;\n\n            SizeType count = CurrentContext().patternPropertiesSchemaCount;\n            const SchemaType** sa = CurrentContext().patternPropertiesSchemas;\n            typename Context::PatternValidatorType patternValidatorType = CurrentContext().valuePatternValidatorType;\n            bool valueUniqueness = CurrentContext().valueUniqueness;\n            RAPIDJSON_ASSERT(CurrentContext().valueSchema);\n            PushSchema(*CurrentContext().valueSchema);\n\n            if (count > 0) {\n                CurrentContext().objectPatternValidatorType = patternValidatorType;\n                ISchemaValidator**& va = CurrentContext().patternPropertiesValidators;\n                SizeType& validatorCount = CurrentContext().patternPropertiesValidatorCount;\n                va = static_cast<ISchemaValidator**>(MallocState(sizeof(ISchemaValidator*) * count));\n                for (SizeType i = 0; i < count; i++)\n                    va[validatorCount++] = CreateSchemaValidator(*sa[i]);\n            }\n\n            CurrentContext().arrayUniqueness = valueUniqueness;\n        }\n        return true;\n    }\n\n    bool EndValue() {\n        if (!CurrentSchema().EndValue(CurrentContext()))\n            return false;\n\n#if RAPIDJSON_SCHEMA_VERBOSE\n        GenericStringBuffer<EncodingType> sb;\n        schemaDocument_->GetPointer(&CurrentSchema()).Stringify(sb);\n\n        *documentStack_.template Push<Ch>() = '\\0';\n        documentStack_.template Pop<Ch>(1);\n        internal::PrintValidatorPointers(depth_, sb.GetString(), documentStack_.template Bottom<Ch>());\n#endif\n\n        uint64_t h = CurrentContext().arrayUniqueness ? static_cast<HasherType*>(CurrentContext().hasher)->GetHashCode() : 0;\n        \n        PopSchema();\n\n        if (!schemaStack_.Empty()) {\n            Context& context = CurrentContext();\n            if (context.valueUniqueness) {\n                HashCodeArray* a = static_cast<HashCodeArray*>(context.arrayElementHashCodes);\n                if (!a)\n                    CurrentContext().arrayElementHashCodes = a = new (GetStateAllocator().Malloc(sizeof(HashCodeArray))) HashCodeArray(kArrayType);\n                for (typename HashCodeArray::ConstValueIterator itr = a->Begin(); itr != a->End(); ++itr)\n                    if (itr->GetUint64() == h)\n                        RAPIDJSON_INVALID_KEYWORD_RETURN(SchemaType::GetUniqueItemsString());\n                a->PushBack(h, GetStateAllocator());\n            }\n        }\n\n        // Remove the last token of document pointer\n        while (!documentStack_.Empty() && *documentStack_.template Pop<Ch>(1) != '/')\n            ;\n\n        return true;\n    }\n\n    void AppendToken(const Ch* str, SizeType len) {\n        documentStack_.template Reserve<Ch>(1 + len * 2); // worst case all characters are escaped as two characters\n        *documentStack_.template PushUnsafe<Ch>() = '/';\n        for (SizeType i = 0; i < len; i++) {\n            if (str[i] == '~') {\n                *documentStack_.template PushUnsafe<Ch>() = '~';\n                *documentStack_.template PushUnsafe<Ch>() = '0';\n            }\n            else if (str[i] == '/') {\n                *documentStack_.template PushUnsafe<Ch>() = '~';\n                *documentStack_.template PushUnsafe<Ch>() = '1';\n            }\n            else\n                *documentStack_.template PushUnsafe<Ch>() = str[i];\n        }\n    }\n\n    RAPIDJSON_FORCEINLINE void PushSchema(const SchemaType& schema) { new (schemaStack_.template Push<Context>()) Context(*this, &schema); }\n    \n    RAPIDJSON_FORCEINLINE void PopSchema() {\n        Context* c = schemaStack_.template Pop<Context>(1);\n        if (HashCodeArray* a = static_cast<HashCodeArray*>(c->arrayElementHashCodes)) {\n            a->~HashCodeArray();\n            StateAllocator::Free(a);\n        }\n        c->~Context();\n    }\n\n    const SchemaType& CurrentSchema() const { return *schemaStack_.template Top<Context>()->schema; }\n    Context& CurrentContext() { return *schemaStack_.template Top<Context>(); }\n    const Context& CurrentContext() const { return *schemaStack_.template Top<Context>(); }\n\n    OutputHandler& CreateNullHandler() {\n        return *(nullHandler_ = static_cast<OutputHandler*>(GetStateAllocator().Malloc(sizeof(OutputHandler))));\n    }\n\n    static const size_t kDefaultSchemaStackCapacity = 1024;\n    static const size_t kDefaultDocumentStackCapacity = 256;\n    const SchemaDocumentType* schemaDocument_;\n    const SchemaType& root_;\n    StateAllocator* stateAllocator_;\n    StateAllocator* ownStateAllocator_;\n    internal::Stack<StateAllocator> schemaStack_;    //!< stack to store the current path of schema (BaseSchemaType *)\n    internal::Stack<StateAllocator> documentStack_;  //!< stack to store the current path of validating document (Ch)\n    OutputHandler& outputHandler_;\n    OutputHandler* nullHandler_;\n    bool valid_;\n#if RAPIDJSON_SCHEMA_VERBOSE\n    unsigned depth_;\n#endif\n};\n\ntypedef GenericSchemaValidator<SchemaDocument> SchemaValidator;\n\n///////////////////////////////////////////////////////////////////////////////\n// SchemaValidatingReader\n\n//! A helper class for parsing with validation.\n/*!\n    This helper class is a functor, designed as a parameter of \\ref GenericDocument::Populate().\n\n    \\tparam parseFlags Combination of \\ref ParseFlag.\n    \\tparam InputStream Type of input stream, implementing Stream concept.\n    \\tparam SourceEncoding Encoding of the input stream.\n    \\tparam SchemaDocumentType Type of schema document.\n    \\tparam StackAllocator Allocator type for stack.\n*/\ntemplate <\n    unsigned parseFlags,\n    typename InputStream,\n    typename SourceEncoding,\n    typename SchemaDocumentType = SchemaDocument,\n    typename StackAllocator = CrtAllocator>\nclass SchemaValidatingReader {\npublic:\n    typedef typename SchemaDocumentType::PointerType PointerType;\n    typedef typename InputStream::Ch Ch;\n\n    //! Constructor\n    /*!\n        \\param is Input stream.\n        \\param sd Schema document.\n    */\n    SchemaValidatingReader(InputStream& is, const SchemaDocumentType& sd) : is_(is), sd_(sd), invalidSchemaKeyword_(), isValid_(true) {}\n\n    template <typename Handler>\n    bool operator()(Handler& handler) {\n        GenericReader<SourceEncoding, typename SchemaDocumentType::EncodingType, StackAllocator> reader;\n        GenericSchemaValidator<SchemaDocumentType, Handler> validator(sd_, handler);\n        parseResult_ = reader.template Parse<parseFlags>(is_, validator);\n\n        isValid_ = validator.IsValid();\n        if (isValid_) {\n            invalidSchemaPointer_ = PointerType();\n            invalidSchemaKeyword_ = 0;\n            invalidDocumentPointer_ = PointerType();\n        }\n        else {\n            invalidSchemaPointer_ = validator.GetInvalidSchemaPointer();\n            invalidSchemaKeyword_ = validator.GetInvalidSchemaKeyword();\n            invalidDocumentPointer_ = validator.GetInvalidDocumentPointer();\n        }\n\n        return parseResult_;\n    }\n\n    const ParseResult& GetParseResult() const { return parseResult_; }\n    bool IsValid() const { return isValid_; }\n    const PointerType& GetInvalidSchemaPointer() const { return invalidSchemaPointer_; }\n    const Ch* GetInvalidSchemaKeyword() const { return invalidSchemaKeyword_; }\n    const PointerType& GetInvalidDocumentPointer() const { return invalidDocumentPointer_; }\n\nprivate:\n    InputStream& is_;\n    const SchemaDocumentType& sd_;\n\n    ParseResult parseResult_;\n    PointerType invalidSchemaPointer_;\n    const Ch* invalidSchemaKeyword_;\n    PointerType invalidDocumentPointer_;\n    bool isValid_;\n};\n\nRAPIDJSON_NAMESPACE_END\nRAPIDJSON_DIAG_POP\n\n#endif // RAPIDJSON_SCHEMA_H_\n"
  },
  {
    "path": "rapidjson/stream.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#include \"rapidjson.h\"\n\n#ifndef RAPIDJSON_STREAM_H_\n#define RAPIDJSON_STREAM_H_\n\n#include \"encodings.h\"\n\nRAPIDJSON_NAMESPACE_BEGIN\n\n///////////////////////////////////////////////////////////////////////////////\n//  Stream\n\n/*! \\class rapidjson::Stream\n    \\brief Concept for reading and writing characters.\n\n    For read-only stream, no need to implement PutBegin(), Put(), Flush() and PutEnd().\n\n    For write-only stream, only need to implement Put() and Flush().\n\n\\code\nconcept Stream {\n    typename Ch;    //!< Character type of the stream.\n\n    //! Read the current character from stream without moving the read cursor.\n    Ch Peek() const;\n\n    //! Read the current character from stream and moving the read cursor to next character.\n    Ch Take();\n\n    //! Get the current read cursor.\n    //! \\return Number of characters read from start.\n    size_t Tell();\n\n    //! Begin writing operation at the current read pointer.\n    //! \\return The begin writer pointer.\n    Ch* PutBegin();\n\n    //! Write a character.\n    void Put(Ch c);\n\n    //! Flush the buffer.\n    void Flush();\n\n    //! End the writing operation.\n    //! \\param begin The begin write pointer returned by PutBegin().\n    //! \\return Number of characters written.\n    size_t PutEnd(Ch* begin);\n}\n\\endcode\n*/\n\n//! Provides additional information for stream.\n/*!\n    By using traits pattern, this type provides a default configuration for stream.\n    For custom stream, this type can be specialized for other configuration.\n    See TEST(Reader, CustomStringStream) in readertest.cpp for example.\n*/\ntemplate<typename Stream>\nstruct StreamTraits {\n    //! Whether to make local copy of stream for optimization during parsing.\n    /*!\n        By default, for safety, streams do not use local copy optimization.\n        Stream that can be copied fast should specialize this, like StreamTraits<StringStream>.\n    */\n    enum { copyOptimization = 0 };\n};\n\n//! Reserve n characters for writing to a stream.\ntemplate<typename Stream>\ninline void PutReserve(Stream& stream, size_t count) {\n    (void)stream;\n    (void)count;\n}\n\n//! Write character to a stream, presuming buffer is reserved.\ntemplate<typename Stream>\ninline void PutUnsafe(Stream& stream, typename Stream::Ch c) {\n    stream.Put(c);\n}\n\n//! Put N copies of a character to a stream.\ntemplate<typename Stream, typename Ch>\ninline void PutN(Stream& stream, Ch c, size_t n) {\n    PutReserve(stream, n);\n    for (size_t i = 0; i < n; i++)\n        PutUnsafe(stream, c);\n}\n\n///////////////////////////////////////////////////////////////////////////////\n// StringStream\n\n//! Read-only string stream.\n/*! \\note implements Stream concept\n*/\ntemplate <typename Encoding>\nstruct GenericStringStream {\n    typedef typename Encoding::Ch Ch;\n\n    GenericStringStream(const Ch *src) : src_(src), head_(src) {}\n\n    Ch Peek() const { return *src_; }\n    Ch Take() { return *src_++; }\n    size_t Tell() const { return static_cast<size_t>(src_ - head_); }\n\n    Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }\n    void Put(Ch) { RAPIDJSON_ASSERT(false); }\n    void Flush() { RAPIDJSON_ASSERT(false); }\n    size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }\n\n    const Ch* src_;     //!< Current read position.\n    const Ch* head_;    //!< Original head of the string.\n};\n\ntemplate <typename Encoding>\nstruct StreamTraits<GenericStringStream<Encoding> > {\n    enum { copyOptimization = 1 };\n};\n\n//! String stream with UTF8 encoding.\ntypedef GenericStringStream<UTF8<> > StringStream;\n\n///////////////////////////////////////////////////////////////////////////////\n// InsituStringStream\n\n//! A read-write string stream.\n/*! This string stream is particularly designed for in-situ parsing.\n    \\note implements Stream concept\n*/\ntemplate <typename Encoding>\nstruct GenericInsituStringStream {\n    typedef typename Encoding::Ch Ch;\n\n    GenericInsituStringStream(Ch *src) : src_(src), dst_(0), head_(src) {}\n\n    // Read\n    Ch Peek() { return *src_; }\n    Ch Take() { return *src_++; }\n    size_t Tell() { return static_cast<size_t>(src_ - head_); }\n\n    // Write\n    void Put(Ch c) { RAPIDJSON_ASSERT(dst_ != 0); *dst_++ = c; }\n\n    Ch* PutBegin() { return dst_ = src_; }\n    size_t PutEnd(Ch* begin) { return static_cast<size_t>(dst_ - begin); }\n    void Flush() {}\n\n    Ch* Push(size_t count) { Ch* begin = dst_; dst_ += count; return begin; }\n    void Pop(size_t count) { dst_ -= count; }\n\n    Ch* src_;\n    Ch* dst_;\n    Ch* head_;\n};\n\ntemplate <typename Encoding>\nstruct StreamTraits<GenericInsituStringStream<Encoding> > {\n    enum { copyOptimization = 1 };\n};\n\n//! Insitu string stream with UTF8 encoding.\ntypedef GenericInsituStringStream<UTF8<> > InsituStringStream;\n\nRAPIDJSON_NAMESPACE_END\n\n#endif // RAPIDJSON_STREAM_H_\n"
  },
  {
    "path": "rapidjson/stringbuffer.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_STRINGBUFFER_H_\n#define RAPIDJSON_STRINGBUFFER_H_\n\n#include \"stream.h\"\n#include \"internal/stack.h\"\n\n#if RAPIDJSON_HAS_CXX11_RVALUE_REFS\n#include <utility> // std::move\n#endif\n\n#include \"internal/stack.h\"\n\n#if defined(__clang__)\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(c++98-compat)\n#endif\n\nRAPIDJSON_NAMESPACE_BEGIN\n\n//! Represents an in-memory output stream.\n/*!\n    \\tparam Encoding Encoding of the stream.\n    \\tparam Allocator type for allocating memory buffer.\n    \\note implements Stream concept\n*/\ntemplate <typename Encoding, typename Allocator = CrtAllocator>\nclass GenericStringBuffer {\npublic:\n    typedef typename Encoding::Ch Ch;\n\n    GenericStringBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {}\n\n#if RAPIDJSON_HAS_CXX11_RVALUE_REFS\n    GenericStringBuffer(GenericStringBuffer&& rhs) : stack_(std::move(rhs.stack_)) {}\n    GenericStringBuffer& operator=(GenericStringBuffer&& rhs) {\n        if (&rhs != this)\n            stack_ = std::move(rhs.stack_);\n        return *this;\n    }\n#endif\n\n    void Put(Ch c) { *stack_.template Push<Ch>() = c; }\n    void PutUnsafe(Ch c) { *stack_.template PushUnsafe<Ch>() = c; }\n    void Flush() {}\n\n    void Clear() { stack_.Clear(); }\n    void ShrinkToFit() {\n        // Push and pop a null terminator. This is safe.\n        *stack_.template Push<Ch>() = '\\0';\n        stack_.ShrinkToFit();\n        stack_.template Pop<Ch>(1);\n    }\n\n    void Reserve(size_t count) { stack_.template Reserve<Ch>(count); }\n    Ch* Push(size_t count) { return stack_.template Push<Ch>(count); }\n    Ch* PushUnsafe(size_t count) { return stack_.template PushUnsafe<Ch>(count); }\n    void Pop(size_t count) { stack_.template Pop<Ch>(count); }\n\n    const Ch* GetString() const {\n        // Push and pop a null terminator. This is safe.\n        *stack_.template Push<Ch>() = '\\0';\n        stack_.template Pop<Ch>(1);\n\n        return stack_.template Bottom<Ch>();\n    }\n\n    //! Get the size of string in bytes in the string buffer.\n    size_t GetSize() const { return stack_.GetSize(); }\n\n    //! Get the length of string in Ch in the string buffer.\n    size_t GetLength() const { return stack_.GetSize() / sizeof(Ch); }\n\n    static const size_t kDefaultCapacity = 256;\n    mutable internal::Stack<Allocator> stack_;\n\nprivate:\n    // Prohibit copy constructor & assignment operator.\n    GenericStringBuffer(const GenericStringBuffer&);\n    GenericStringBuffer& operator=(const GenericStringBuffer&);\n};\n\n//! String buffer with UTF8 encoding\ntypedef GenericStringBuffer<UTF8<> > StringBuffer;\n\ntemplate<typename Encoding, typename Allocator>\ninline void PutReserve(GenericStringBuffer<Encoding, Allocator>& stream, size_t count) {\n    stream.Reserve(count);\n}\n\ntemplate<typename Encoding, typename Allocator>\ninline void PutUnsafe(GenericStringBuffer<Encoding, Allocator>& stream, typename Encoding::Ch c) {\n    stream.PutUnsafe(c);\n}\n\n//! Implement specialized version of PutN() with memset() for better performance.\ntemplate<>\ninline void PutN(GenericStringBuffer<UTF8<> >& stream, char c, size_t n) {\n    std::memset(stream.stack_.Push<char>(n), c, n * sizeof(c));\n}\n\nRAPIDJSON_NAMESPACE_END\n\n#if defined(__clang__)\nRAPIDJSON_DIAG_POP\n#endif\n\n#endif // RAPIDJSON_STRINGBUFFER_H_\n"
  },
  {
    "path": "rapidjson/writer.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_WRITER_H_\n#define RAPIDJSON_WRITER_H_\n\n#include \"stream.h\"\n#include \"internal/stack.h\"\n#include \"internal/strfunc.h\"\n#include \"internal/dtoa.h\"\n#include \"internal/itoa.h\"\n#include \"stringbuffer.h\"\n#include <new>      // placement new\n\n#if defined(RAPIDJSON_SIMD) && defined(_MSC_VER)\n#include <intrin.h>\n#pragma intrinsic(_BitScanForward)\n#endif\n#ifdef RAPIDJSON_SSE42\n#include <nmmintrin.h>\n#elif defined(RAPIDJSON_SSE2)\n#include <emmintrin.h>\n#endif\n\n#ifdef _MSC_VER\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(4127) // conditional expression is constant\n#endif\n\n#ifdef __clang__\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(padded)\nRAPIDJSON_DIAG_OFF(unreachable-code)\nRAPIDJSON_DIAG_OFF(c++98-compat)\n#endif\n\nRAPIDJSON_NAMESPACE_BEGIN\n\n///////////////////////////////////////////////////////////////////////////////\n// WriteFlag\n\n/*! \\def RAPIDJSON_WRITE_DEFAULT_FLAGS \n    \\ingroup RAPIDJSON_CONFIG\n    \\brief User-defined kWriteDefaultFlags definition.\n\n    User can define this as any \\c WriteFlag combinations.\n*/\n#ifndef RAPIDJSON_WRITE_DEFAULT_FLAGS\n#define RAPIDJSON_WRITE_DEFAULT_FLAGS kWriteNoFlags\n#endif\n\n//! Combination of writeFlags\nenum WriteFlag {\n    kWriteNoFlags = 0,              //!< No flags are set.\n    kWriteValidateEncodingFlag = 1, //!< Validate encoding of JSON strings.\n    kWriteNanAndInfFlag = 2,        //!< Allow writing of Infinity, -Infinity and NaN.\n    kWriteDefaultFlags = RAPIDJSON_WRITE_DEFAULT_FLAGS  //!< Default write flags. Can be customized by defining RAPIDJSON_WRITE_DEFAULT_FLAGS\n};\n\n//! JSON writer\n/*! Writer implements the concept Handler.\n    It generates JSON text by events to an output os.\n\n    User may programmatically calls the functions of a writer to generate JSON text.\n\n    On the other side, a writer can also be passed to objects that generates events, \n\n    for example Reader::Parse() and Document::Accept().\n\n    \\tparam OutputStream Type of output stream.\n    \\tparam SourceEncoding Encoding of source string.\n    \\tparam TargetEncoding Encoding of output stream.\n    \\tparam StackAllocator Type of allocator for allocating memory of stack.\n    \\note implements Handler concept\n*/\ntemplate<typename OutputStream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator, unsigned writeFlags = kWriteDefaultFlags>\nclass Writer {\npublic:\n    typedef typename SourceEncoding::Ch Ch;\n\n    static const int kDefaultMaxDecimalPlaces = 324;\n\n    //! Constructor\n    /*! \\param os Output stream.\n        \\param stackAllocator User supplied allocator. If it is null, it will create a private one.\n        \\param levelDepth Initial capacity of stack.\n    */\n    explicit\n    Writer(OutputStream& os, StackAllocator* stackAllocator = 0, size_t levelDepth = kDefaultLevelDepth) : \n        os_(&os), level_stack_(stackAllocator, levelDepth * sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {}\n\n    explicit\n    Writer(StackAllocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) :\n        os_(0), level_stack_(allocator, levelDepth * sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {}\n\n#if RAPIDJSON_HAS_CXX11_RVALUE_REFS\n    Writer(Writer&& rhs) :\n        os_(rhs.os_), level_stack_(std::move(rhs.level_stack_)), maxDecimalPlaces_(rhs.maxDecimalPlaces_), hasRoot_(rhs.hasRoot_) {\n        rhs.os_ = 0;\n    }\n#endif\n\n    //! Reset the writer with a new stream.\n    /*!\n        This function reset the writer with a new stream and default settings,\n        in order to make a Writer object reusable for output multiple JSONs.\n\n        \\param os New output stream.\n        \\code\n        Writer<OutputStream> writer(os1);\n        writer.StartObject();\n        // ...\n        writer.EndObject();\n\n        writer.Reset(os2);\n        writer.StartObject();\n        // ...\n        writer.EndObject();\n        \\endcode\n    */\n    void Reset(OutputStream& os) {\n        os_ = &os;\n        hasRoot_ = false;\n        level_stack_.Clear();\n    }\n\n    //! Checks whether the output is a complete JSON.\n    /*!\n        A complete JSON has a complete root object or array.\n    */\n    bool IsComplete() const {\n        return hasRoot_ && level_stack_.Empty();\n    }\n\n    int GetMaxDecimalPlaces() const {\n        return maxDecimalPlaces_;\n    }\n\n    //! Sets the maximum number of decimal places for double output.\n    /*!\n        This setting truncates the output with specified number of decimal places.\n\n        For example, \n\n        \\code\n        writer.SetMaxDecimalPlaces(3);\n        writer.StartArray();\n        writer.Double(0.12345);                 // \"0.123\"\n        writer.Double(0.0001);                  // \"0.0\"\n        writer.Double(1.234567890123456e30);    // \"1.234567890123456e30\" (do not truncate significand for positive exponent)\n        writer.Double(1.23e-4);                 // \"0.0\"                  (do truncate significand for negative exponent)\n        writer.EndArray();\n        \\endcode\n\n        The default setting does not truncate any decimal places. You can restore to this setting by calling\n        \\code\n        writer.SetMaxDecimalPlaces(Writer::kDefaultMaxDecimalPlaces);\n        \\endcode\n    */\n    void SetMaxDecimalPlaces(int maxDecimalPlaces) {\n        maxDecimalPlaces_ = maxDecimalPlaces;\n    }\n\n    /*!@name Implementation of Handler\n        \\see Handler\n    */\n    //@{\n\n    bool Null()                 { Prefix(kNullType);   return EndValue(WriteNull()); }\n    bool Bool(bool b)           { Prefix(b ? kTrueType : kFalseType); return EndValue(WriteBool(b)); }\n    bool Int(int i)             { Prefix(kNumberType); return EndValue(WriteInt(i)); }\n    bool Uint(unsigned u)       { Prefix(kNumberType); return EndValue(WriteUint(u)); }\n    bool Int64(int64_t i64)     { Prefix(kNumberType); return EndValue(WriteInt64(i64)); }\n    bool Uint64(uint64_t u64)   { Prefix(kNumberType); return EndValue(WriteUint64(u64)); }\n\n    //! Writes the given \\c double value to the stream\n    /*!\n        \\param d The value to be written.\n        \\return Whether it is succeed.\n    */\n    bool Double(double d)       { Prefix(kNumberType); return EndValue(WriteDouble(d)); }\n\n    bool RawNumber(const Ch* str, SizeType length, bool copy = false) {\n        RAPIDJSON_ASSERT(str != 0);\n        (void)copy;\n        Prefix(kNumberType);\n        return EndValue(WriteString(str, length));\n    }\n\n    bool String(const Ch* str, SizeType length, bool copy = false) {\n        RAPIDJSON_ASSERT(str != 0);\n        (void)copy;\n        Prefix(kStringType);\n        return EndValue(WriteString(str, length));\n    }\n\n#if RAPIDJSON_HAS_STDSTRING\n    bool String(const std::basic_string<Ch>& str) {\n        return String(str.data(), SizeType(str.size()));\n    }\n#endif\n\n    bool StartObject() {\n        Prefix(kObjectType);\n        new (level_stack_.template Push<Level>()) Level(false);\n        return WriteStartObject();\n    }\n\n    bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); }\n\n    bool EndObject(SizeType memberCount = 0) {\n        (void)memberCount;\n        RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level));\n        RAPIDJSON_ASSERT(!level_stack_.template Top<Level>()->inArray);\n        level_stack_.template Pop<Level>(1);\n        return EndValue(WriteEndObject());\n    }\n\n    bool StartArray() {\n        Prefix(kArrayType);\n        new (level_stack_.template Push<Level>()) Level(true);\n        return WriteStartArray();\n    }\n\n    bool EndArray(SizeType elementCount = 0) {\n        (void)elementCount;\n        RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level));\n        RAPIDJSON_ASSERT(level_stack_.template Top<Level>()->inArray);\n        level_stack_.template Pop<Level>(1);\n        return EndValue(WriteEndArray());\n    }\n    //@}\n\n    /*! @name Convenience extensions */\n    //@{\n\n    //! Simpler but slower overload.\n    bool String(const Ch* str) { return String(str, internal::StrLen(str)); }\n    bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); }\n\n    //@}\n\n    //! Write a raw JSON value.\n    /*!\n        For user to write a stringified JSON as a value.\n\n        \\param json A well-formed JSON value. It should not contain null character within [0, length - 1] range.\n        \\param length Length of the json.\n        \\param type Type of the root of json.\n    */\n    bool RawValue(const Ch* json, size_t length, Type type) {\n        RAPIDJSON_ASSERT(json != 0);\n        Prefix(type);\n        return EndValue(WriteRawValue(json, length));\n    }\n\nprotected:\n    //! Information for each nested level\n    struct Level {\n        Level(bool inArray_) : valueCount(0), inArray(inArray_) {}\n        size_t valueCount;  //!< number of values in this level\n        bool inArray;       //!< true if in array, otherwise in object\n    };\n\n    static const size_t kDefaultLevelDepth = 32;\n\n    bool WriteNull()  {\n        PutReserve(*os_, 4);\n        PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 'l'); return true;\n    }\n\n    bool WriteBool(bool b)  {\n        if (b) {\n            PutReserve(*os_, 4);\n            PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'r'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'e');\n        }\n        else {\n            PutReserve(*os_, 5);\n            PutUnsafe(*os_, 'f'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 's'); PutUnsafe(*os_, 'e');\n        }\n        return true;\n    }\n\n    bool WriteInt(int i) {\n        char buffer[11];\n        const char* end = internal::i32toa(i, buffer);\n        PutReserve(*os_, static_cast<size_t>(end - buffer));\n        for (const char* p = buffer; p != end; ++p)\n            PutUnsafe(*os_, static_cast<typename TargetEncoding::Ch>(*p));\n        return true;\n    }\n\n    bool WriteUint(unsigned u) {\n        char buffer[10];\n        const char* end = internal::u32toa(u, buffer);\n        PutReserve(*os_, static_cast<size_t>(end - buffer));\n        for (const char* p = buffer; p != end; ++p)\n            PutUnsafe(*os_, static_cast<typename TargetEncoding::Ch>(*p));\n        return true;\n    }\n\n    bool WriteInt64(int64_t i64) {\n        char buffer[21];\n        const char* end = internal::i64toa(i64, buffer);\n        PutReserve(*os_, static_cast<size_t>(end - buffer));\n        for (const char* p = buffer; p != end; ++p)\n            PutUnsafe(*os_, static_cast<typename TargetEncoding::Ch>(*p));\n        return true;\n    }\n\n    bool WriteUint64(uint64_t u64) {\n        char buffer[20];\n        char* end = internal::u64toa(u64, buffer);\n        PutReserve(*os_, static_cast<size_t>(end - buffer));\n        for (char* p = buffer; p != end; ++p)\n            PutUnsafe(*os_, static_cast<typename TargetEncoding::Ch>(*p));\n        return true;\n    }\n\n    bool WriteDouble(double d) {\n        if (internal::Double(d).IsNanOrInf()) {\n            if (!(writeFlags & kWriteNanAndInfFlag))\n                return false;\n            if (internal::Double(d).IsNan()) {\n                PutReserve(*os_, 3);\n                PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N');\n                return true;\n            }\n            if (internal::Double(d).Sign()) {\n                PutReserve(*os_, 9);\n                PutUnsafe(*os_, '-');\n            }\n            else\n                PutReserve(*os_, 8);\n            PutUnsafe(*os_, 'I'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'f');\n            PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'y');\n            return true;\n        }\n\n        char buffer[25];\n        char* end = internal::dtoa(d, buffer, maxDecimalPlaces_);\n        PutReserve(*os_, static_cast<size_t>(end - buffer));\n        for (char* p = buffer; p != end; ++p)\n            PutUnsafe(*os_, static_cast<typename TargetEncoding::Ch>(*p));\n        return true;\n    }\n\n    bool WriteString(const Ch* str, SizeType length)  {\n        static const typename TargetEncoding::Ch hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };\n        static const char escape[256] = {\n#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n            //0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F\n            'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'b', 't', 'n', 'u', 'f', 'r', 'u', 'u', // 00\n            'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', // 10\n              0,   0, '\"',   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, // 20\n            Z16, Z16,                                                                       // 30~4F\n              0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,'\\\\',   0,   0,   0, // 50\n            Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16                                // 60~FF\n#undef Z16\n        };\n\n        if (TargetEncoding::supportUnicode)\n            PutReserve(*os_, 2 + length * 6); // \"\\uxxxx...\"\n        else\n            PutReserve(*os_, 2 + length * 12);  // \"\\uxxxx\\uyyyy...\"\n\n        PutUnsafe(*os_, '\\\"');\n        GenericStringStream<SourceEncoding> is(str);\n        while (ScanWriteUnescapedString(is, length)) {\n            const Ch c = is.Peek();\n            if (!TargetEncoding::supportUnicode && static_cast<unsigned>(c) >= 0x80) {\n                // Unicode escaping\n                unsigned codepoint;\n                if (RAPIDJSON_UNLIKELY(!SourceEncoding::Decode(is, &codepoint)))\n                    return false;\n                PutUnsafe(*os_, '\\\\');\n                PutUnsafe(*os_, 'u');\n                if (codepoint <= 0xD7FF || (codepoint >= 0xE000 && codepoint <= 0xFFFF)) {\n                    PutUnsafe(*os_, hexDigits[(codepoint >> 12) & 15]);\n                    PutUnsafe(*os_, hexDigits[(codepoint >>  8) & 15]);\n                    PutUnsafe(*os_, hexDigits[(codepoint >>  4) & 15]);\n                    PutUnsafe(*os_, hexDigits[(codepoint      ) & 15]);\n                }\n                else {\n                    RAPIDJSON_ASSERT(codepoint >= 0x010000 && codepoint <= 0x10FFFF);\n                    // Surrogate pair\n                    unsigned s = codepoint - 0x010000;\n                    unsigned lead = (s >> 10) + 0xD800;\n                    unsigned trail = (s & 0x3FF) + 0xDC00;\n                    PutUnsafe(*os_, hexDigits[(lead >> 12) & 15]);\n                    PutUnsafe(*os_, hexDigits[(lead >>  8) & 15]);\n                    PutUnsafe(*os_, hexDigits[(lead >>  4) & 15]);\n                    PutUnsafe(*os_, hexDigits[(lead      ) & 15]);\n                    PutUnsafe(*os_, '\\\\');\n                    PutUnsafe(*os_, 'u');\n                    PutUnsafe(*os_, hexDigits[(trail >> 12) & 15]);\n                    PutUnsafe(*os_, hexDigits[(trail >>  8) & 15]);\n                    PutUnsafe(*os_, hexDigits[(trail >>  4) & 15]);\n                    PutUnsafe(*os_, hexDigits[(trail      ) & 15]);                    \n                }\n            }\n            else if ((sizeof(Ch) == 1 || static_cast<unsigned>(c) < 256) && RAPIDJSON_UNLIKELY(escape[static_cast<unsigned char>(c)]))  {\n                is.Take();\n                PutUnsafe(*os_, '\\\\');\n                PutUnsafe(*os_, static_cast<typename TargetEncoding::Ch>(escape[static_cast<unsigned char>(c)]));\n                if (escape[static_cast<unsigned char>(c)] == 'u') {\n                    PutUnsafe(*os_, '0');\n                    PutUnsafe(*os_, '0');\n                    PutUnsafe(*os_, hexDigits[static_cast<unsigned char>(c) >> 4]);\n                    PutUnsafe(*os_, hexDigits[static_cast<unsigned char>(c) & 0xF]);\n                }\n            }\n            else if (RAPIDJSON_UNLIKELY(!(writeFlags & kWriteValidateEncodingFlag ? \n                Transcoder<SourceEncoding, TargetEncoding>::Validate(is, *os_) :\n                Transcoder<SourceEncoding, TargetEncoding>::TranscodeUnsafe(is, *os_))))\n                return false;\n        }\n        PutUnsafe(*os_, '\\\"');\n        return true;\n    }\n\n    bool ScanWriteUnescapedString(GenericStringStream<SourceEncoding>& is, size_t length) {\n        return RAPIDJSON_LIKELY(is.Tell() < length);\n    }\n\n    bool WriteStartObject() { os_->Put('{'); return true; }\n    bool WriteEndObject()   { os_->Put('}'); return true; }\n    bool WriteStartArray()  { os_->Put('['); return true; }\n    bool WriteEndArray()    { os_->Put(']'); return true; }\n\n    bool WriteRawValue(const Ch* json, size_t length) {\n        PutReserve(*os_, length);\n        for (size_t i = 0; i < length; i++) {\n            RAPIDJSON_ASSERT(json[i] != '\\0');\n            PutUnsafe(*os_, json[i]);\n        }\n        return true;\n    }\n\n    void Prefix(Type type) {\n        (void)type;\n        if (RAPIDJSON_LIKELY(level_stack_.GetSize() != 0)) { // this value is not at root\n            Level* level = level_stack_.template Top<Level>();\n            if (level->valueCount > 0) {\n                if (level->inArray) \n                    os_->Put(','); // add comma if it is not the first element in array\n                else  // in object\n                    os_->Put((level->valueCount % 2 == 0) ? ',' : ':');\n            }\n            if (!level->inArray && level->valueCount % 2 == 0)\n                RAPIDJSON_ASSERT(type == kStringType);  // if it's in object, then even number should be a name\n            level->valueCount++;\n        }\n        else {\n            RAPIDJSON_ASSERT(!hasRoot_);    // Should only has one and only one root.\n            hasRoot_ = true;\n        }\n    }\n\n    // Flush the value if it is the top level one.\n    bool EndValue(bool ret) {\n        if (RAPIDJSON_UNLIKELY(level_stack_.Empty()))   // end of json text\n            os_->Flush();\n        return ret;\n    }\n\n    OutputStream* os_;\n    internal::Stack<StackAllocator> level_stack_;\n    int maxDecimalPlaces_;\n    bool hasRoot_;\n\nprivate:\n    // Prohibit copy constructor & assignment operator.\n    Writer(const Writer&);\n    Writer& operator=(const Writer&);\n};\n\n// Full specialization for StringStream to prevent memory copying\n\ntemplate<>\ninline bool Writer<StringBuffer>::WriteInt(int i) {\n    char *buffer = os_->Push(11);\n    const char* end = internal::i32toa(i, buffer);\n    os_->Pop(static_cast<size_t>(11 - (end - buffer)));\n    return true;\n}\n\ntemplate<>\ninline bool Writer<StringBuffer>::WriteUint(unsigned u) {\n    char *buffer = os_->Push(10);\n    const char* end = internal::u32toa(u, buffer);\n    os_->Pop(static_cast<size_t>(10 - (end - buffer)));\n    return true;\n}\n\ntemplate<>\ninline bool Writer<StringBuffer>::WriteInt64(int64_t i64) {\n    char *buffer = os_->Push(21);\n    const char* end = internal::i64toa(i64, buffer);\n    os_->Pop(static_cast<size_t>(21 - (end - buffer)));\n    return true;\n}\n\ntemplate<>\ninline bool Writer<StringBuffer>::WriteUint64(uint64_t u) {\n    char *buffer = os_->Push(20);\n    const char* end = internal::u64toa(u, buffer);\n    os_->Pop(static_cast<size_t>(20 - (end - buffer)));\n    return true;\n}\n\ntemplate<>\ninline bool Writer<StringBuffer>::WriteDouble(double d) {\n    if (internal::Double(d).IsNanOrInf()) {\n        // Note: This code path can only be reached if (RAPIDJSON_WRITE_DEFAULT_FLAGS & kWriteNanAndInfFlag).\n        if (!(kWriteDefaultFlags & kWriteNanAndInfFlag))\n            return false;\n        if (internal::Double(d).IsNan()) {\n            PutReserve(*os_, 3);\n            PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N');\n            return true;\n        }\n        if (internal::Double(d).Sign()) {\n            PutReserve(*os_, 9);\n            PutUnsafe(*os_, '-');\n        }\n        else\n            PutReserve(*os_, 8);\n        PutUnsafe(*os_, 'I'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'f');\n        PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'y');\n        return true;\n    }\n    \n    char *buffer = os_->Push(25);\n    char* end = internal::dtoa(d, buffer, maxDecimalPlaces_);\n    os_->Pop(static_cast<size_t>(25 - (end - buffer)));\n    return true;\n}\n\n#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42)\ntemplate<>\ninline bool Writer<StringBuffer>::ScanWriteUnescapedString(StringStream& is, size_t length) {\n    if (length < 16)\n        return RAPIDJSON_LIKELY(is.Tell() < length);\n\n    if (!RAPIDJSON_LIKELY(is.Tell() < length))\n        return false;\n\n    const char* p = is.src_;\n    const char* end = is.head_ + length;\n    const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));\n    const char* endAligned = reinterpret_cast<const char*>(reinterpret_cast<size_t>(end) & static_cast<size_t>(~15));\n    if (nextAligned > end)\n        return true;\n\n    while (p != nextAligned)\n        if (*p < 0x20 || *p == '\\\"' || *p == '\\\\') {\n            is.src_ = p;\n            return RAPIDJSON_LIKELY(is.Tell() < length);\n        }\n        else\n            os_->PutUnsafe(*p++);\n\n    // The rest of string using SIMD\n    static const char dquote[16] = { '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"' };\n    static const char bslash[16] = { '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\' };\n    static const char space[16]  = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 };\n    const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));\n    const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));\n    const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));\n\n    for (; p != endAligned; p += 16) {\n        const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));\n        const __m128i t1 = _mm_cmpeq_epi8(s, dq);\n        const __m128i t2 = _mm_cmpeq_epi8(s, bs);\n        const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x19) == 0x19\n        const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);\n        unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x));\n        if (RAPIDJSON_UNLIKELY(r != 0)) {   // some of characters is escaped\n            SizeType len;\n#ifdef _MSC_VER         // Find the index of first escaped\n            unsigned long offset;\n            _BitScanForward(&offset, r);\n            len = offset;\n#else\n            len = static_cast<SizeType>(__builtin_ffs(r) - 1);\n#endif\n            char* q = reinterpret_cast<char*>(os_->PushUnsafe(len));\n            for (size_t i = 0; i < len; i++)\n                q[i] = p[i];\n\n            p += len;\n            break;\n        }\n        _mm_storeu_si128(reinterpret_cast<__m128i *>(os_->PushUnsafe(16)), s);\n    }\n\n    is.src_ = p;\n    return RAPIDJSON_LIKELY(is.Tell() < length);\n}\n#endif // defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42)\n\nRAPIDJSON_NAMESPACE_END\n\n#ifdef _MSC_VER\nRAPIDJSON_DIAG_POP\n#endif\n\n#ifdef __clang__\nRAPIDJSON_DIAG_POP\n#endif\n\n#endif // RAPIDJSON_RAPIDJSON_H_\n"
  },
  {
    "path": "socket.cpp",
    "content": "/*\n  * This program is free software: you can redistribute it and/or modify\n  * it under the terms of the GNU General Public License as published by\n  * the Free Software Foundation, either version 3 of the License, or\n  * any later version.\n  *\n  * This program is distributed in the hope that it will be useful,\n  * but WITHOUT ANY WARRANTY; without even the implied warranty of\n  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n  * GNU General Public License for more details.\n  *\n  * You should have received a copy of the GNU General Public License\n  * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n  *\n  * Additional permission under GNU GPL version 3 section 7\n  *\n  * If you modify this Program, or any covered work, by linking or combining\n  * it with OpenSSL (or a modified version of that library), containing parts\n  * covered by the terms of OpenSSL License and SSLeay License, the licensors\n  * of this Program grant you additional permission to convey the resulting work.\n  *\n  */\n\n#include \"socket.h\"\n#include \"jpsock.h\"\n#include \"jconf.h\"\n#include \"console.h\"\n#include \"executor.h\"\n\n#ifndef CONF_NO_TLS\n#include <openssl/ssl.h>\n#include <openssl/err.h>\n#include <openssl/opensslconf.h>\n\n#ifndef OPENSSL_THREADS\n#error OpenSSL was compiled without thread support\n#endif\n#endif\n\nplain_socket::plain_socket(jpsock* err_callback) : pCallback(err_callback)\n{\n\thSocket = INVALID_SOCKET;\n\tpSockAddr = nullptr;\n}\n\nbool plain_socket::set_hostname(const char* sAddr)\n{\n\tchar sAddrMb[256];\n\tchar *sTmp, *sPort;\n\n\tsize_t ln = strlen(sAddr);\n\tif (ln >= sizeof(sAddrMb))\n\t\treturn pCallback->set_socket_error(\"CONNECT error: Pool address overflow.\");\n\n\tmemcpy(sAddrMb, sAddr, ln);\n\tsAddrMb[ln] = '\\0';\n\n\tif ((sTmp = strstr(sAddrMb, \"//\")) != nullptr)\n\t\tmemmove(sAddrMb, sTmp, strlen(sTmp) + 1);\n\n\tif ((sPort = strchr(sAddrMb, ':')) == nullptr)\n\t\treturn pCallback->set_socket_error(\"CONNECT error: Pool port number not specified, please use format <hostname>:<port>.\");\n\n\tsPort[0] = '\\0';\n\tsPort++;\n\n\taddrinfo hints = { 0 };\n\thints.ai_family = AF_UNSPEC;\n\thints.ai_socktype = SOCK_STREAM;\n\thints.ai_protocol = IPPROTO_TCP;\n\n\tpAddrRoot = nullptr;\n\tint err;\n\tif ((err = getaddrinfo(sAddrMb, sPort, &hints, &pAddrRoot)) != 0)\n\t\treturn pCallback->set_socket_error_strerr(\"CONNECT error: GetAddrInfo: \", err);\n\n\taddrinfo *ptr = pAddrRoot;\n\taddrinfo *ipv4 = nullptr, *ipv6 = nullptr;\n\n\twhile (ptr != nullptr)\n\t{\n\t\tif (ptr->ai_family == AF_INET)\n\t\t\tipv4 = ptr;\n\t\tif (ptr->ai_family == AF_INET6)\n\t\t\tipv6 = ptr;\n\t\tptr = ptr->ai_next;\n\t}\n\n\tif (ipv4 == nullptr && ipv6 == nullptr)\n\t{\n\t\tfreeaddrinfo(pAddrRoot);\n\t\tpAddrRoot = nullptr;\n\t\treturn pCallback->set_socket_error(\"CONNECT error: I found some DNS records but no IPv4 or IPv6 addresses.\");\n\t}\n\telse if (ipv4 != nullptr && ipv6 == nullptr)\n\t\tpSockAddr = ipv4;\n\telse if (ipv4 == nullptr && ipv6 != nullptr)\n\t\tpSockAddr = ipv6;\n\telse if (ipv4 != nullptr && ipv6 != nullptr)\n\t{\n\t\tif(jconf::inst()->PreferIpv4())\n\t\t\tpSockAddr = ipv4;\n\t\telse\n\t\t\tpSockAddr = ipv6;\n\t}\n\n\thSocket = socket(pSockAddr->ai_family, pSockAddr->ai_socktype, pSockAddr->ai_protocol);\n\n\tif (hSocket == INVALID_SOCKET)\n\t{\n\t\tfreeaddrinfo(pAddrRoot);\n\t\tpAddrRoot = nullptr;\n\t\treturn pCallback->set_socket_error_strerr(\"CONNECT error: Socket creation failed \");\n\t}\n\n\treturn true;\n}\n\nbool plain_socket::connect()\n{\n\tint ret = ::connect(hSocket, pSockAddr->ai_addr, (int)pSockAddr->ai_addrlen);\n\n\tfreeaddrinfo(pAddrRoot);\n\tpAddrRoot = nullptr;\n\n\tif (ret != 0)\n\t\treturn pCallback->set_socket_error_strerr(\"CONNECT error: \");\n\telse\n\t\treturn true;\n}\n\nint plain_socket::recv(char* buf, unsigned int len)\n{\n\tint ret = ::recv(hSocket, buf, len, 0);\n\n\tif(ret == 0)\n\t\tpCallback->set_socket_error(\"RECEIVE error: socket closed\");\n\tif(ret == SOCKET_ERROR || ret < 0)\n\t\tpCallback->set_socket_error_strerr(\"RECEIVE error: \");\n\n\treturn ret;\n}\n\nbool plain_socket::send(const char* buf)\n{\n\tint pos = 0, slen = strlen(buf);\n\twhile (pos != slen)\n\t{\n\t\tint ret = ::send(hSocket, buf + pos, slen - pos, 0);\n\t\tif (ret == SOCKET_ERROR)\n\t\t{\n\t\t\tpCallback->set_socket_error_strerr(\"SEND error: \");\n\t\t\treturn false;\n\t\t}\n\t\telse\n\t\t\tpos += ret;\n\t}\n\n\treturn true;\n}\n\nvoid plain_socket::close(bool free)\n{\n\tif(hSocket != INVALID_SOCKET)\n\t{\n\t\tsock_close(hSocket);\n\t\thSocket = INVALID_SOCKET;\n\t}\n}\n\n#ifndef CONF_NO_TLS\ntls_socket::tls_socket(jpsock* err_callback) : pCallback(err_callback)\n{\n}\n\nvoid tls_socket::print_error()\n{\n\tBIO* err_bio = BIO_new(BIO_s_mem());\n\tERR_print_errors(err_bio);\n\n\tchar *buf = nullptr;\n\tsize_t len = BIO_get_mem_data(err_bio, &buf);\n\n\tpCallback->set_socket_error(buf, len);\n\n\tBIO_free(err_bio);\n}\n\nvoid tls_socket::init_ctx()\n{\n\tconst SSL_METHOD* method = SSLv23_method();\n\n\tif(method == nullptr)\n\t\treturn;\n\n\tctx = SSL_CTX_new(method);\n\tif(ctx == nullptr)\n\t\treturn;\n\n\tif(jconf::inst()->TlsSecureAlgos())\n\t{\n\t\tSSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_COMPRESSION);\n\t}\n}\n\nbool tls_socket::set_hostname(const char* sAddr)\n{\n\tif(ctx == nullptr)\n\t{\n\t\tinit_ctx();\n\t\tif(ctx == nullptr)\n\t\t{\n\t\t\tprint_error();\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tif((bio = BIO_new_ssl_connect(ctx)) == nullptr)\n\t{\n\t\tprint_error();\n\t\treturn false;\n\t}\n\n\tif(BIO_set_conn_hostname(bio, sAddr) != 1)\n\t{\n\t\tprint_error();\n\t\treturn false;\n\t}\n\n\tBIO_get_ssl(bio, &ssl);\n\tif(ssl == nullptr)\n\t{\n\t\tprint_error();\n\t\treturn false;\n\t}\n\n\tif(jconf::inst()->TlsSecureAlgos())\n\t{\n\t\tif(SSL_set_cipher_list(ssl, \"HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4:!SHA1\") != 1)\n\t\t{\n\t\t\tprint_error();\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n\nbool tls_socket::connect()\n{\n\tif(BIO_do_connect(bio) != 1)\n\t{\n\t\tprint_error();\n\t\treturn false;\n\t}\n\n\tif(BIO_do_handshake(bio) != 1)\n\t{\n\t\tprint_error();\n\t\treturn false;\n\t}\n\n\t/* Step 1: verify a server certificate was presented during the negotiation */\n\tX509* cert = SSL_get_peer_certificate(ssl);\n\tif(cert == nullptr)\n\t{\n\t\tprint_error();\n\t\treturn false;\n\t}\n\n\tconst EVP_MD* digest;\n\tunsigned char md[EVP_MAX_MD_SIZE];\n\tunsigned int dlen;\n\n\tdigest = EVP_get_digestbyname(\"sha256\");\n\tif(digest == nullptr)\n\t{\n\t\tprint_error();\n\t\treturn false;\n\t}\n\n\tif(X509_digest(cert, digest, md, &dlen) != 1)\n\t{\n\t\tX509_free(cert);\n\t\tprint_error();\n\t\treturn false;\n\t}\n\n\tif(pCallback->pool_id != executor::dev_pool_id)\n\t{\n\t\t//Base64 encode digest\n\t\tBIO *bmem, *b64;\n\t\tb64 = BIO_new(BIO_f_base64());\n\t\tbmem = BIO_new(BIO_s_mem());\n\n\t\tBIO_puts(bmem, \"SHA256:\");\n\t\tb64 = BIO_push(b64, bmem);\n\t\tBIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);\n\t\tBIO_write(b64, md, dlen);\n\t\tBIO_flush(b64);\n\n\t\tconst char* conf_md = jconf::inst()->GetTlsFingerprint();\n\t\tchar *b64_md = nullptr;\n\t\tsize_t b64_len = BIO_get_mem_data(bmem, &b64_md);\n\n\t\tif(strlen(conf_md) == 0)\n\t\t{\n\t\t\tprinter::inst()->print_msg(L1, \"Server fingerprint: %.*s\", (int)b64_len, b64_md);\n\t\t}\n\t\telse if(strncmp(b64_md, conf_md, b64_len) != 0)\n\t\t{\n\t\t\tprinter::inst()->print_msg(L0, \"FINGERPRINT FAILED CHECK: %.*s was given, %s was configured\",\n\t\t\t\t(int)b64_len, b64_md, conf_md);\n\n\t\t\tpCallback->set_socket_error(\"FINGERPRINT FAILED CHECK\");\n\t\t\tBIO_free_all(b64);\n\t\t\tX509_free(cert);\n\t\t\treturn false;\n\t\t}\n\n\t\tBIO_free_all(b64);\n\t}\n\n\tX509_free(cert);\n\treturn true;\n}\n\nint tls_socket::recv(char* buf, unsigned int len)\n{\n\tint ret = BIO_read(bio, buf, len);\n\n\tif(ret == 0)\n\t\tpCallback->set_socket_error(\"RECEIVE error: socket closed\");\n\tif(ret < 0)\n\t\tprint_error();\n\n\treturn ret;\n}\n\nbool tls_socket::send(const char* buf)\n{\n\treturn BIO_puts(bio, buf) > 0;\n}\n\nvoid tls_socket::close(bool free)\n{\n\tif(bio == nullptr || ssl == nullptr)\n\t\treturn;\n\n\tif(!free)\n\t{\n\t\tsock_close(BIO_get_fd(bio, nullptr));\n\t}\n\telse\n\t{\n\t\tBIO_free_all(bio);\n\t\tssl = nullptr;\n\t\tbio = nullptr;\n\t}\n}\n#endif\n\n"
  },
  {
    "path": "socket.h",
    "content": "#pragma once\n#include \"socks.h\"\nclass jpsock;\n\nclass base_socket\n{\npublic:\n\tvirtual bool set_hostname(const char* sAddr) = 0;\n\tvirtual bool connect() = 0;\n\tvirtual int recv(char* buf, unsigned int len) = 0;\n\tvirtual bool send(const char* buf) = 0;\n\tvirtual void close(bool free) = 0;\n};\n\nclass plain_socket : public base_socket\n{\npublic:\n\tplain_socket(jpsock* err_callback);\n\n\tbool set_hostname(const char* sAddr);\n\tbool connect();\n\tint recv(char* buf, unsigned int len);\n\tbool send(const char* buf);\n\tvoid close(bool free);\n\nprivate:\n\tjpsock* pCallback;\n\taddrinfo *pSockAddr;\n\taddrinfo *pAddrRoot;\n\tSOCKET hSocket;\n};\n\ntypedef struct ssl_ctx_st SSL_CTX;\ntypedef struct bio_st BIO;\ntypedef struct ssl_st SSL;\n\nclass tls_socket : public base_socket\n{\npublic:\n\ttls_socket(jpsock* err_callback);\n\n\tbool set_hostname(const char* sAddr);\n\tbool connect();\n\tint recv(char* buf, unsigned int len);\n\tbool send(const char* buf);\n\tvoid close(bool free);\n\nprivate:\n\tvoid init_ctx();\n\tvoid print_error();\n\n\tjpsock* pCallback;\n\n\tSSL_CTX* ctx = nullptr;\n\tBIO* bio = nullptr;\n\tSSL* ssl = nullptr;\n};\n"
  },
  {
    "path": "socks.h",
    "content": "#pragma once\n#ifdef _WIN32\n#ifndef _WIN32_WINNT\n#define _WIN32_WINNT 0x0601  /* Windows 7 */\n#endif\n#include <winsock2.h>\n#include <ws2tcpip.h>\n#include <windows.h>\n\ninline void sock_init()\n{\n\tstatic bool bWSAInit = false;\n\n\tif (!bWSAInit)\n\t{\n\t\tWSADATA wsaData;\n\t\tWSAStartup(MAKEWORD(2, 2), &wsaData);\n\t\tbWSAInit = true;\n\t}\n}\n\ninline void sock_close(SOCKET s)\n{\n\tshutdown(s, SD_BOTH);\n\tclosesocket(s);\n}\n\ninline const char* sock_strerror(char* buf, size_t len)\n{\n\tbuf[0] = '\\0';\n\n\tFormatMessageA(\n\t\tFORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK,\n\t\tNULL, WSAGetLastError(),\n\t\tMAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),\n\t\t(LPSTR)buf, len, NULL);\n\n\treturn buf;\n}\n\ninline const char* sock_gai_strerror(int err, char* buf, size_t len)\n{\n\tbuf[0] = '\\0';\n\n\tFormatMessageA(\n\t\tFORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK,\n\t\tNULL, (DWORD)err,\n\t\tMAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),\n\t\t(LPSTR)buf, len, NULL);\n\n\treturn buf;\n}\n\n#else\n\n/* Assume that any non-Windows platform uses POSIX-style sockets instead. */\n#include <sys/socket.h>\n#include <arpa/inet.h>\n#include <netdb.h>  /* Needed for getaddrinfo() and freeaddrinfo() */\n#include <unistd.h> /* Needed for close() */\n#include <errno.h>\n#include <string.h>\n\ninline void sock_init() {}\ntypedef int SOCKET;\n\n#define INVALID_SOCKET  (-1)\n#define SOCKET_ERROR    (-1)\n\ninline void sock_close(SOCKET s)\n{\n\tshutdown(s, SHUT_RDWR);\n\tclose(s);\n}\n\ninline const char* sock_strerror(char* buf, size_t len)\n{\n\tbuf[0] = '\\0';\n#if defined(__APPLE__)\n\tstrerror_r(errno, buf, len);\n\treturn buf;\n#else\n\treturn strerror_r(errno, buf, len);\n#endif\n}\n\ninline const char* sock_gai_strerror(int err, char* buf, size_t len)\n{\n\tbuf[0] = '\\0';\n\treturn gai_strerror(err);\n}\n#endif\n"
  },
  {
    "path": "thdq.hpp",
    "content": "#pragma once\r\n\r\n#include <queue>\r\n#include <thread>\r\n#include <mutex>\r\n#include <condition_variable>\r\n\r\ntemplate <typename T>\r\nclass thdq\r\n{\r\npublic:\r\n\tT pop()\r\n\t{\r\n\t\tstd::unique_lock<std::mutex> mlock(mutex_);\r\n\t\twhile (queue_.empty()) { cond_.wait(mlock); }\r\n\t\tauto item = std::move(queue_.front());\r\n\t\tqueue_.pop();\r\n\t\treturn item;\r\n\t}\r\n\r\n\tvoid pop(T& item)\r\n\t{\r\n\t\tstd::unique_lock<std::mutex> mlock(mutex_);\r\n\t\twhile (queue_.empty()) { cond_.wait(mlock); }\r\n\t\titem = queue_.front();\r\n\t\tqueue_.pop();\r\n\t}\r\n\r\n\tvoid push(const T& item)\r\n\t{\r\n\t\tstd::unique_lock<std::mutex> mlock(mutex_);\r\n\t\tqueue_.push(item);\r\n\t\tmlock.unlock();\r\n\t\tcond_.notify_one();\r\n\t}\r\n\r\n\tvoid push(T&& item)\r\n\t{\r\n\t\tstd::unique_lock<std::mutex> mlock(mutex_);\r\n\t\tqueue_.push(std::move(item));\r\n\t\tmlock.unlock();\r\n\t\tcond_.notify_one();\r\n\t}\r\n\r\nprivate:\r\n\tstd::queue<T> queue_;\r\n\tstd::mutex mutex_;\r\n\tstd::condition_variable cond_;\r\n};\n"
  },
  {
    "path": "version.h",
    "content": "#pragma once\n\n#define XMR_STAK_NAME \"xmr-stak-amd\"\n#define XMR_STAK_VERSION \"1.1.0-1.4.0\"\n"
  },
  {
    "path": "webdesign.cpp",
    "content": "#include <stdlib.h>\n\nextern const char sHtmlCssEtag [] = \"00000006\";\nextern const char sHtmlCssFile [] =\n\t\"body {\"\n\t\t\"font-family: Tahoma, Arial, sans-serif;\"\n\t\t\"font-size: 80%;\"\n\t\t\"background-color: rgb(240, 240, 240);\"\n\t\"}\"\n\n\t\"a {\"\n\t\t\"color: rgb(44, 55, 66);\"\n\t\"}\"\n\n\t\"a:link {\"\n\t\t\"text-decoration: none;\"\n\t\"}\"\n\n\t\"a:visited {\"\n\t\t\"color: rgb(44, 55, 66);\"\n\t\"}\"\n\n\t\"a:hover {\"\n\t\t\"color: rgb(255, 153, 0);\"\n\t\"}\"\n\n\t\"a:active {\"\n\t\t\"color: rgb(204, 122, 0);\"\n\t\"}\"\n\n\t\".all {\"\n\t\t\"max-width:600px;\"\n\t\t\"margin: auto;\"\n\t\"}\"\n\n\t\".header {\"\n\t\t\"background-color: rgb(30, 30, 30);\"\n\t\t\"color: white;\"\n\t\t\"padding: 10px;\"\n\t\t\"font-weight: bold;\"\n\t\t\"margin: 10px 0px;\"\n\t\"}\"\n\n\t\".links {\"\n\t\t\"padding: 7px;\"\n\t\t\"text-align: center;\"\n\t\t\"background-color: rgb(215, 215, 215);\"\n\t\t\"box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.2), 0px 1px 1px 0px rgba(0, 0, 0, 0.14), 0px 2px 1px -1px rgba(0, 0, 0, 0.12);\"\n\t\"}\"\n\n\t\".data th, td {\"\n\t\t\"padding: 5px 12px;\"\n\t\t\"text-align: right;\"\n\t\t\"border-bottom: 1px solid #ccc;\"\n\t\"}\"\n\n\t\".data tr:nth-child(even) {\"\n\t\t\"background-color: #ddd;\"\n\t\"}\"\n\n\t\".data th {\"\n\t\t\"background-color: #ccc;\"\n\t\"}\"\n\n\t\".data table {\"\n\t\t\"width: 100%;\"\n\t\t\"max-width: 600px;\"\n\t\"}\"\n\n\t\".letter {\"\n\t\t\"font-weight: bold;\"\n\t\"}\"\n\n\t\"h4 {\"\n\t\t\"background-color: rgb(0, 130, 130);\"\n\t\t\"color: white;\"\n\t\t\"padding: 10px;\"\n\t\t\"margin: 10px 0px;\"\n\t\"}\"\n\n\t\".flex-container {\"\n\t\t\"display: -webkit-flex;\"\n\t\t\"display: flex;\"\n\t\"}\"\n\n\t\".flex-item {\"\n\t\t\"width: 33%;\"\n\t\t\"margin: 3px;\"\n\t\"}\";\n\nsize_t sHtmlCssSize = sizeof(sHtmlCssFile) - 1;\n\nextern const char sHtmlCommonHeader [] =\n\t\"<!DOCTYPE html>\"\n\t\"<html>\"\n\t\"<head><meta name='viewport' content='width=device-width' />\"\n\t\"<link rel='stylesheet' href='style.css' /><title>%s</title></head>\"\n\t\"<body>\"\n\t\"<div class='all'>\"\n\t\"<div class='header'><span style='color: rgb(255, 160, 0)'>XMR</span>-Stak-AMD</div>\"\n\n\t\"<div class='flex-container'>\"\n\t\t\"<div class='links flex-item'>\"\n\t\t\t\"<a href='/h'><div><span class='letter'>H</span>ashrate</div></a>\"\n\t\t\"</div>\"\n\t\t\"<div class='links flex-item'>\"\n\t\t\t\"<a href='/r'><div><span class='letter'>R</span>esults</div></a>\"\n\t\t\"</div>\"\n\t\t\"<div class='links flex-item'>\"\n\t\t\t\"<a href='/c'><div><span class='letter'>C</span>onnection</div></a>\"\n\t\t\"</div>\"\n\t\"</div>\"\n\t\"<h4>%s</h4>\";\n\nextern const char sHtmlHashrateBodyHigh [] =\n\t\"<div class=data>\"\n\t\"<table>\"\n\t\t\"<tr><th>Thread ID</th><th>10s</th><th>60s</th><th>15m</th><th rowspan='%u'>H/s</td></tr>\";\n\nextern const char sHtmlHashrateTableRow [] =\n\t\"<tr><th>%u</th><td>%s</td><td>%s</td><td>%s</td></tr>\";\n\nextern const char sHtmlHashrateBodyLow [] =\n\t\t\"<tr><th>Totals:</th><td>%s</td><td>%s</td><td>%s</td></tr>\"\n\t\t\"<tr><th>Highest:</th><td>%s</td><td colspan='2'></td></tr>\"\n\t\"</table>\"\n\t\"</div></div></body></html>\";\n\nextern const char sHtmlConnectionBodyHigh [] =\n\t\"<div class=data>\"\n\t\"<table>\"\n\t\t\"<tr><th>Pool address</th><td>%s</td></tr>\"\n\t\t\"<tr><th>Connected since</th><td>%s</td></tr>\"\n\t\t\"<tr><th>Pool ping time</th><td>%u ms</td></tr>\"\n\t\"</table>\"\n\t\"<h4>Network error log</h4>\"\n\t\"<table>\"\n\t\t\"<tr><th style='width: 20%; min-width: 10em;'>Date</th><th>Error</th></tr>\";\n\nextern const char sHtmlConnectionTableRow [] =\n\t\"<tr><td>%s</td><td>%s</td></tr>\";\n\nextern const char sHtmlConnectionBodyLow [] =\n\t\"</table></div></div></body></html>\";\n\nextern const char sHtmlResultBodyHigh [] =\n\t\"<div class=data>\"\n\t\"<table>\"\n\t\t\"<tr><th>Difficulty</th><td>%u</td></tr>\"\n\t\t\"<tr><th>Good results</th><td>%u / %u (%.1f %%)</td></tr>\"\n\t\t\"<tr><th>Avg result time</th><td>%.1f sec</td></tr>\"\n\t\t\"<tr><th>Pool-side hashes</th><td>%u</td></tr>\"\n\t\"</table>\"\n\t\"<h4>Top 10 best results found</h4>\"\n\t\"<table>\"\n\t\t\"<tr><th style='width: 2em;'>1</th><td>%llu</td><th style='width: 2em;'>2</th><td>%llu</td></tr>\"\n\t\t\"<tr><th>3</th><td>%llu</td><th>4</th><td>%llu</td></tr>\"\n\t\t\"<tr><th>5</th><td>%llu</td><th>6</th><td>%llu</td></tr>\"\n\t\t\"<tr><th>7</th><td>%llu</td><th>8</th><td>%llu</td></tr>\"\n\t\t\"<tr><th>9</th><td>%llu</td><th>10</th><td>%llu</td></tr>\"\n\t\"</table>\"\n\t\"<h4>Error details</h4>\"\n\t\"<table>\"\n\t\t\"<tr><th colspan='2'>Error text</th></tr>\"\n\t\t\"<tr><th style='width: 5em;'>Count</th><th>Last seen</th></tr>\";\n\nextern const char sHtmlResultTableRow [] =\n\t\"<tr><td colspan='2'>%s</td></tr><tr><td>%llu</td><td>%s</td></tr>\";\n\nextern const char sHtmlResultBodyLow [] =\n\t\"</table></div></div></body></html>\";\n\n"
  },
  {
    "path": "webdesign.h",
    "content": "#pragma once\n\nextern const char sHtmlCssEtag[];\nextern const char sHtmlCssFile[];\nextern size_t sHtmlCssSize;\n\nextern const char sHtmlCommonHeader[];\n\nextern const char sHtmlHashrateBodyHigh[];\nextern const char sHtmlHashrateTableRow[];\nextern const char sHtmlHashrateBodyLow[];\n\nextern const char sHtmlConnectionBodyHigh[];\nextern const char sHtmlConnectionTableRow[];\nextern const char sHtmlConnectionBodyLow[];\n\nextern const char sHtmlResultBodyHigh[];\nextern const char sHtmlResultTableRow[];\nextern const char sHtmlResultBodyLow[];\n"
  },
  {
    "path": "xmr-stak-amd.cbp",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>\n<CodeBlocks_project_file>\n\t<FileVersion major=\"1\" minor=\"6\" />\n\t<Project>\n\t\t<Option title=\"xmr-stak-amd\" />\n\t\t<Option pch_mode=\"2\" />\n\t\t<Option compiler=\"gcc\" />\n\t\t<Build>\n\t\t\t<Target title=\"Debug\">\n\t\t\t\t<Option output=\"bin/Debug/miner\" prefix_auto=\"1\" extension_auto=\"1\" />\n\t\t\t\t<Option object_output=\"obj/Debug/\" />\n\t\t\t\t<Option type=\"1\" />\n\t\t\t\t<Option compiler=\"gcc\" />\n\t\t\t\t<Option parameters=\"config-debug.txt\" />\n\t\t\t\t<Compiler>\n\t\t\t\t\t<Add option=\"-march=corei7-avx\" />\n\t\t\t\t\t<Add option=\"-std=c++11\" />\n\t\t\t\t\t<Add option=\"-m64\" />\n\t\t\t\t\t<Add option=\"-g\" />\n\t\t\t\t\t<Add directory=\"include\" />\n\t\t\t\t</Compiler>\n\t\t\t\t<Linker>\n\t\t\t\t\t<Add option=\"-m64\" />\n\t\t\t\t</Linker>\n\t\t\t</Target>\n\t\t\t<Target title=\"Release\">\n\t\t\t\t<Option output=\"bin/Release/miner\" prefix_auto=\"1\" extension_auto=\"1\" />\n\t\t\t\t<Option object_output=\"obj/Release/\" />\n\t\t\t\t<Option type=\"1\" />\n\t\t\t\t<Option compiler=\"gcc\" />\n\t\t\t\t<Option parameters=\"config-debug.txt\" />\n\t\t\t\t<Compiler>\n\t\t\t\t\t<Add option=\"-march=westmere\" />\n\t\t\t\t\t<Add option=\"-O3\" />\n\t\t\t\t\t<Add option=\"-std=c++11\" />\n\t\t\t\t\t<Add option=\"-m64\" />\n\t\t\t\t\t<Add option=\"-DNDEBUG\" />\n\t\t\t\t\t<Add directory=\"include\" />\n\t\t\t\t</Compiler>\n\t\t\t\t<Linker>\n\t\t\t\t\t<Add option=\"-s\" />\n\t\t\t\t\t<Add option=\"-m64\" />\n\t\t\t\t</Linker>\n\t\t\t</Target>\n\t\t\t<Target title=\"Release_test\">\n\t\t\t\t<Option output=\"bin/Release_test/miner\" prefix_auto=\"1\" extension_auto=\"1\" />\n\t\t\t\t<Option object_output=\"obj/Release_test/\" />\n\t\t\t\t<Option type=\"1\" />\n\t\t\t\t<Option compiler=\"gcc\" />\n\t\t\t\t<Option parameters=\"config-debug.txt\" />\n\t\t\t\t<Compiler>\n\t\t\t\t\t<Add option=\"-march=westmere\" />\n\t\t\t\t\t<Add option=\"-O3\" />\n\t\t\t\t\t<Add option=\"-std=c++11\" />\n\t\t\t\t\t<Add option=\"-m64\" />\n\t\t\t\t\t<Add directory=\"include\" />\n\t\t\t\t</Compiler>\n\t\t\t\t<Linker>\n\t\t\t\t\t<Add option=\"-s\" />\n\t\t\t\t\t<Add option=\"-m64\" />\n\t\t\t\t</Linker>\n\t\t\t</Target>\n\t\t</Build>\n\t\t<Compiler>\n\t\t\t<Add option=\"-Wall\" />\n\t\t</Compiler>\n\t\t<Linker>\n\t\t\t<Add library=\"pthread\" />\n\t\t\t<Add library=\"libmicrohttpd\" />\n\t\t\t<Add library=\"OpenCL\" />\n\t\t\t<Add library=\"crypto\" />\n\t\t\t<Add library=\"ssl\" />\n\t\t</Linker>\n\t\t<Unit filename=\"amd_gpu/gpu.c\">\n\t\t\t<Option compilerVar=\"CC\" />\n\t\t</Unit>\n\t\t<Unit filename=\"amd_gpu/gpu.h\" />\n\t\t<Unit filename=\"cli-miner.cpp\" />\n\t\t<Unit filename=\"console.cpp\" />\n\t\t<Unit filename=\"console.h\" />\n\t\t<Unit filename=\"crypto/c_blake256.c\">\n\t\t\t<Option compilerVar=\"CC\" />\n\t\t</Unit>\n\t\t<Unit filename=\"crypto/c_blake256.h\" />\n\t\t<Unit filename=\"crypto/c_groestl.c\">\n\t\t\t<Option compilerVar=\"CC\" />\n\t\t</Unit>\n\t\t<Unit filename=\"crypto/c_groestl.h\" />\n\t\t<Unit filename=\"crypto/c_jh.c\">\n\t\t\t<Option compilerVar=\"CC\" />\n\t\t</Unit>\n\t\t<Unit filename=\"crypto/c_jh.h\" />\n\t\t<Unit filename=\"crypto/c_keccak.c\">\n\t\t\t<Option compilerVar=\"CC\" />\n\t\t</Unit>\n\t\t<Unit filename=\"crypto/c_keccak.h\" />\n\t\t<Unit filename=\"crypto/c_skein.c\">\n\t\t\t<Option compilerVar=\"CC\" />\n\t\t</Unit>\n\t\t<Unit filename=\"crypto/c_skein.h\" />\n\t\t<Unit filename=\"crypto/cryptonight.h\" />\n\t\t<Unit filename=\"crypto/cryptonight_aesni.h\" />\n\t\t<Unit filename=\"crypto/cryptonight_common.cpp\" />\n\t\t<Unit filename=\"crypto/groestl_tables.h\" />\n\t\t<Unit filename=\"crypto/hash.h\" />\n\t\t<Unit filename=\"crypto/int-util.h\" />\n\t\t<Unit filename=\"crypto/skein_port.h\" />\n\t\t<Unit filename=\"crypto/soft_aes.c\">\n\t\t\t<Option compilerVar=\"CC\" />\n\t\t</Unit>\n\t\t<Unit filename=\"donate-level.h\" />\n\t\t<Unit filename=\"executor.cpp\" />\n\t\t<Unit filename=\"executor.h\" />\n\t\t<Unit filename=\"httpd.cpp\" />\n\t\t<Unit filename=\"httpd.h\" />\n\t\t<Unit filename=\"jconf.cpp\" />\n\t\t<Unit filename=\"jconf.h\" />\n\t\t<Unit filename=\"jext.h\" />\n\t\t<Unit filename=\"jpsock.cpp\" />\n\t\t<Unit filename=\"jpsock.h\" />\n\t\t<Unit filename=\"minethd.cpp\" />\n\t\t<Unit filename=\"minethd.h\" />\n\t\t<Unit filename=\"msgstruct.h\" />\n\t\t<Unit filename=\"rapidjson/allocators.h\" />\n\t\t<Unit filename=\"rapidjson/document.h\" />\n\t\t<Unit filename=\"rapidjson/encodedstream.h\" />\n\t\t<Unit filename=\"rapidjson/encodings.h\" />\n\t\t<Unit filename=\"rapidjson/error/en.h\" />\n\t\t<Unit filename=\"rapidjson/error/error.h\" />\n\t\t<Unit filename=\"rapidjson/filereadstream.h\" />\n\t\t<Unit filename=\"rapidjson/filewritestream.h\" />\n\t\t<Unit filename=\"rapidjson/fwd.h\" />\n\t\t<Unit filename=\"rapidjson/internal/biginteger.h\" />\n\t\t<Unit filename=\"rapidjson/internal/diyfp.h\" />\n\t\t<Unit filename=\"rapidjson/internal/dtoa.h\" />\n\t\t<Unit filename=\"rapidjson/internal/ieee754.h\" />\n\t\t<Unit filename=\"rapidjson/internal/itoa.h\" />\n\t\t<Unit filename=\"rapidjson/internal/meta.h\" />\n\t\t<Unit filename=\"rapidjson/internal/pow10.h\" />\n\t\t<Unit filename=\"rapidjson/internal/regex.h\" />\n\t\t<Unit filename=\"rapidjson/internal/stack.h\" />\n\t\t<Unit filename=\"rapidjson/internal/strfunc.h\" />\n\t\t<Unit filename=\"rapidjson/internal/strtod.h\" />\n\t\t<Unit filename=\"rapidjson/internal/swap.h\" />\n\t\t<Unit filename=\"rapidjson/istreamwrapper.h\" />\n\t\t<Unit filename=\"rapidjson/memorybuffer.h\" />\n\t\t<Unit filename=\"rapidjson/memorystream.h\" />\n\t\t<Unit filename=\"rapidjson/msinttypes/inttypes.h\" />\n\t\t<Unit filename=\"rapidjson/msinttypes/stdint.h\" />\n\t\t<Unit filename=\"rapidjson/ostreamwrapper.h\" />\n\t\t<Unit filename=\"rapidjson/pointer.h\" />\n\t\t<Unit filename=\"rapidjson/prettywriter.h\" />\n\t\t<Unit filename=\"rapidjson/rapidjson.h\" />\n\t\t<Unit filename=\"rapidjson/reader.h\" />\n\t\t<Unit filename=\"rapidjson/schema.h\" />\n\t\t<Unit filename=\"rapidjson/stream.h\" />\n\t\t<Unit filename=\"rapidjson/stringbuffer.h\" />\n\t\t<Unit filename=\"rapidjson/writer.h\" />\n\t\t<Unit filename=\"socket.cpp\" />\n\t\t<Unit filename=\"socket.h\" />\n\t\t<Unit filename=\"socks.h\" />\n\t\t<Unit filename=\"thdq.hpp\" />\n\t\t<Unit filename=\"webdesign.cpp\" />\n\t\t<Unit filename=\"webdesign.h\" />\n\t\t<Extensions>\n\t\t\t<code_completion />\n\t\t\t<debugger />\n\t\t</Extensions>\n\t</Project>\n</CodeBlocks_project_file>\n"
  }
]