diff --git a/.github/workflows/msbuild.yml b/.github/workflows/msbuild.yml
index fa68b50..86e900c 100644
--- a/.github/workflows/msbuild.yml
+++ b/.github/workflows/msbuild.yml
@@ -20,9 +20,6 @@ env:
# https://docs.github.com/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
BUILD_CONFIGURATION: Release
-permissions:
- contents: read
-
jobs:
build:
runs-on: windows-latest
@@ -42,6 +39,7 @@ jobs:
# Add additional options to the MSBuild command line here (like platform or verbosity level).
# See https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference
run: msbuild /m /p:Configuration=${{env.BUILD_CONFIGURATION}} ${{env.SOLUTION_FILE_PATH}}
+
- name: Upload build artifacts
uses: actions/upload-artifact@v2
with:
diff --git a/.vscode/settings.json b/.vscode/settings.json
index ad52f84..3036db0 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -88,6 +88,7 @@
"random": "cpp",
"hash_map": "cpp",
"hash_set": "cpp",
- "filesystem": "cpp"
+ "filesystem": "cpp",
+ "regex": "cpp"
}
}
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..0ad25db
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,661 @@
+ GNU AFFERO GENERAL PUBLIC LICENSE
+ Version 3, 19 November 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU Affero General Public License is a free, copyleft license for
+software and other kinds of works, specifically designed to ensure
+cooperation with the community in the case of network server software.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+our General Public Licenses are intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ Developers that use our General Public Licenses protect your rights
+with two steps: (1) assert copyright on the software, and (2) offer
+you this License which gives you legal permission to copy, distribute
+and/or modify the software.
+
+ A secondary benefit of defending all users' freedom is that
+improvements made in alternate versions of the program, if they
+receive widespread use, become available for other developers to
+incorporate. Many developers of free software are heartened and
+encouraged by the resulting cooperation. However, in the case of
+software used on network servers, this result may fail to come about.
+The GNU General Public License permits making a modified version and
+letting the public access it on a server without ever releasing its
+source code to the public.
+
+ The GNU Affero General Public License is designed specifically to
+ensure that, in such cases, the modified source code becomes available
+to the community. It requires the operator of a network server to
+provide the source code of the modified version running there to the
+users of that server. Therefore, public use of a modified version, on
+a publicly accessible server, gives the public access to the source
+code of the modified version.
+
+ An older license, called the Affero General Public License and
+published by Affero, was designed to accomplish similar goals. This is
+a different license, not a version of the Affero GPL, but Affero has
+released a new version of the Affero GPL which permits relicensing under
+this license.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU Affero General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Remote Network Interaction; Use with the GNU General Public License.
+
+ Notwithstanding any other provision of this License, if you modify the
+Program, your modified version must prominently offer all users
+interacting with it remotely through a computer network (if your version
+supports such interaction) an opportunity to receive the Corresponding
+Source of your version by providing access to the Corresponding Source
+from a network server at no charge, through some standard or customary
+means of facilitating copying of software. This Corresponding Source
+shall include the Corresponding Source for any work covered by version 3
+of the GNU General Public License that is incorporated pursuant to the
+following paragraph.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the work with which it is combined will remain governed by version
+3 of the GNU General Public License.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU Affero General Public License from time to time. Such new versions
+will be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU Affero General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU Affero General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU Affero General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If your software can interact with users remotely through a computer
+network, you should also make sure that it provides a way for users to
+get its source. For example, if your program is a web application, its
+interface could display a "Source" link that leads users to an archive
+of the code. There are many ways you could offer source, and different
+solutions will be better for different programs; see section 13 for the
+specific requirements.
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU AGPL, see
+.
diff --git a/csgo2/Server.cpp b/csgo2/Server.cpp
new file mode 100644
index 0000000..b4da975
--- /dev/null
+++ b/csgo2/Server.cpp
@@ -0,0 +1,77 @@
+#include "server.h"
+namespace Server {
+size_t receive_data(void* contents, size_t size, size_t nmemb, void* stream) {
+ std::string* str = (std::string*)stream;
+ (*str).append((char*)contents, size * nmemb);
+ return size * nmemb;
+}
+CURLcode HttpGet(const std::string& strUrl, std::string& strResponse,
+ std::string header, int nTimeout) {
+ CURLcode res;
+ CURL* pCURL = curl_easy_init();
+ if (pCURL == NULL) {
+ return CURLE_FAILED_INIT;
+ }
+ struct curl_slist* headers = NULL;
+
+ if (header.empty() == false) {
+ headers = curl_slist_append(headers, (char*)header.c_str());
+ }
+ headers = curl_slist_append(headers, "Accept: application/json");
+ headers = curl_slist_append(headers,
+ "Content-Type: application/json"); // text/html
+ headers = curl_slist_append(headers, "charsets: utf-8");
+ curl_easy_setopt(pCURL, CURLOPT_HTTPHEADER, headers);
+ curl_easy_setopt(pCURL, CURLOPT_URL, strUrl.c_str());
+ // curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
+ curl_easy_setopt(pCURL, CURLOPT_NOSIGNAL, 1L);
+ curl_easy_setopt(pCURL, CURLOPT_TIMEOUT, nTimeout);
+ curl_easy_setopt(pCURL, CURLOPT_SSL_VERIFYPEER, false);
+ curl_easy_setopt(pCURL, CURLOPT_NOPROGRESS, 1L);
+ curl_easy_setopt(pCURL, CURLOPT_WRITEFUNCTION, receive_data);
+ curl_easy_setopt(pCURL, CURLOPT_WRITEDATA, (void*)&strResponse);
+ res = curl_easy_perform(pCURL);
+ curl_slist_free_all(headers);
+ curl_easy_cleanup(pCURL);
+
+ return res;
+}
+
+CURLcode HttpPost(const std::string& strUrl, std::string header,
+ std::string szJson, std::string& strResponse, int nTimeout) {
+ CURLcode res;
+ CURL* pCURL = curl_easy_init();
+ struct curl_slist* headers = NULL;
+ if (pCURL == NULL) {
+ return CURLE_FAILED_INIT;
+ }
+ if (header.empty() == false) {
+ headers = curl_slist_append(headers, (char*)header.c_str());
+ }
+ CURLcode ret;
+ ret = curl_easy_setopt(pCURL, CURLOPT_URL, strUrl.c_str());
+ // std::string data = curl_easy_escape(pCURL, szJson.c_str(),
+ // szJson.size());
+ std::string data = szJson;
+ ret = curl_easy_setopt(pCURL, CURLOPT_POST, 1L);
+ // headers = curl_slist_append(headers, "expect: ");
+ headers = curl_slist_append(headers, "Accept: application/json");
+ headers = curl_slist_append(headers,
+ "Content-Type: application/json"); // text/html
+ headers = curl_slist_append(headers, "charsets: utf-8");
+ ret = curl_easy_setopt(pCURL, CURLOPT_HTTPHEADER, headers);
+ ret = curl_easy_setopt(pCURL, CURLOPT_POSTFIELDS, data.c_str());
+ ret = curl_easy_setopt(pCURL, CURLOPT_TIMEOUT, 60);
+ ret = curl_easy_setopt(pCURL, CURLOPT_NOSIGNAL, 1);
+ ret = curl_easy_setopt(pCURL, CURLOPT_TIMEOUT_MS, 60000);
+ ret = curl_easy_setopt(pCURL, CURLOPT_SSL_VERIFYPEER, false);
+ ret = curl_easy_setopt(pCURL, CURLOPT_NOPROGRESS, 1L);
+ ret = curl_easy_setopt(pCURL, CURLOPT_WRITEFUNCTION, receive_data);
+ ret = curl_easy_setopt(pCURL, CURLOPT_WRITEDATA, (void*)&strResponse);
+ res = curl_easy_perform(pCURL);
+ curl_slist_free_all(headers);
+ curl_easy_cleanup(pCURL);
+ return res;
+}
+
+} // namespace Server
diff --git a/csgo2/Server.h b/csgo2/Server.h
new file mode 100644
index 0000000..e6f7f6f
--- /dev/null
+++ b/csgo2/Server.h
@@ -0,0 +1,9 @@
+#pragma once
+#include "head.h"
+#include "libcurl/libcurl.h"
+namespace Server {
+CURLcode HttpPost(const std::string& strUrl, std::string header,
+ std::string szJson, std::string& strResponse, int nTimeout);
+CURLcode HttpGet(const std::string& strUrl, std::string& strResponse,
+ std::string header, int nTimeout);
+} // namespace Server
diff --git a/csgo2/csgo2.vcxproj b/csgo2/csgo2.vcxproj
index 91df1b8..33fcf4c 100644
--- a/csgo2/csgo2.vcxproj
+++ b/csgo2/csgo2.vcxproj
@@ -82,12 +82,14 @@
$(MSBuildProjectDirectory)\sdk\protobuf-2.6.1\src;$(MSBuildProjectDirectory)\LuaBridge;$(IncludePath)
$(ProjectName)
$(SolutionDir)$(Configuration)\
+ $(ProjectDir)libcurl\lib\;$(LibraryPath)
false
$(MSBuildProjectDirectory)\sdk\protobuf-2.6.1\src;$(MSBuildProjectDirectory)\LuaBridge;$(IncludePath)
$(ProjectName)
$(SolutionDir)$(Configuration)\
+ $(ProjectDir)libcurl\lib\;$(LibraryPath)
@@ -137,6 +139,7 @@
Windows
true
false
+ %(AdditionalDependencies)
@@ -150,6 +153,8 @@
NotUsing
pch.h
stdcpplatest
+ MultiThreaded
+ MaxSpeed
Windows
@@ -157,6 +162,7 @@
true
true
false
+ %(AdditionalDependencies)
@@ -166,6 +172,7 @@
+
@@ -241,6 +248,7 @@
+
@@ -256,6 +264,9 @@
+
+
+
@@ -311,6 +322,7 @@
+
diff --git a/csgo2/csgo2.vcxproj.filters b/csgo2/csgo2.vcxproj.filters
index da8a3a2..fb83021 100644
--- a/csgo2/csgo2.vcxproj.filters
+++ b/csgo2/csgo2.vcxproj.filters
@@ -85,6 +85,15 @@
{23cedcbc-aa1d-444b-baf2-0f55c87c525e}
+
+ {40443ff4-f9c7-4ed8-824e-244fc667bcf3}
+
+
+ {766101f1-81fc-457d-b23e-f896d2582e12}
+
+
+ {6733acfb-5291-4538-9448-3e945dc649ce}
+
@@ -354,6 +363,12 @@
头文件\sdk\public
+
+ 头文件\http
+
+
+ 源文件\script_engine\lua_cjson
+
@@ -536,6 +551,18 @@
源文件\hijack
+
+ 源文件\http
+
+
+ 源文件\script_engine\lua_cjson
+
+
+ 源文件\script_engine\lua_cjson
+
+
+ 源文件\script_engine\lua_cjson
+
diff --git a/csgo2/dllmain.cpp b/csgo2/dllmain.cpp
index 2b9b716..186337d 100644
--- a/csgo2/dllmain.cpp
+++ b/csgo2/dllmain.cpp
@@ -37,6 +37,7 @@ auto init(void* ctx) -> bool {
Sleep(200);
}
+ global::isMetaModInit = (GetModuleHandleA("metamod.2.cs2.dll") != nullptr);
if (Offset::Init() == false) {
LOG("Offset::Init() == false !\n");
return false;
diff --git a/csgo2/events.cpp b/csgo2/events.cpp
index 0f818c9..10b921a 100644
--- a/csgo2/events.cpp
+++ b/csgo2/events.cpp
@@ -1,57 +1,56 @@
#include "events.h"
namespace events {
+auto OnPlayerTeamChangeEevent(IGameEvent* event) -> void {
+ GameEventKeySymbol_t userIdNameParams{"userid"};
+ GameEventKeySymbol_t teamNameParams{"team"};
+ GameEventKeySymbol_t oldteamNameParams{"oldteam"};
+ GameEventKeySymbol_t disconnectNameParams{"disconnect"};
+ GameEventKeySymbol_t silentNameParams{"silent"};
+ GameEventKeySymbol_t isbotParams{"isbot"};
+
+ const auto PlayerPawn = reinterpret_cast(
+ event->GetPlayerPawn(userIdNameParams));
+ if (PlayerPawn == nullptr) {
+ return;
+ }
+ if (PlayerPawn->IsBasePlayerController() == false) {
+ return;
+ }
+ const auto Player = PlayerPawn->GetPlayerController();
+ if (Player == nullptr) {
+ return;
+ }
+ const auto playerIndex = Player->GetRefEHandle().GetEntryIndex();
+ auto team = event->GetInt(teamNameParams);
+ auto oldTeam = event->GetInt(oldteamNameParams);
+ auto disconnect = event->GetBool(disconnectNameParams);
+ auto slient = event->GetBool(silentNameParams);
+ auto isBot = event->GetBool(isbotParams);
+ if (ScriptCallBacks::luaCall_onPlayerTeamChange(
+ playerIndex, team, oldTeam, disconnect, slient, isBot) == true) {
+ event->SetBool(silentNameParams, true);
+ }
+}
auto OnPlayerHurtEvent(IGameEvent* event) -> void {
/*
auto luaCall_onPlayerHurt(int userid, int attacker, int health, int armor,
const char* weapon, int dmg_health, int dmg_armor,
int hitgroup) -> void
*/
- UnkGameEventStruct_t userIdNameParams{"userid"};
- UnkGameEventStruct_t attackerNameParams{"attacker"};
- UnkGameEventStruct_t healthNameParams{"health"};
- UnkGameEventStruct_t armorNameParams{0};
- UnkGameEventStruct_t weaponNameParams{0};
- UnkGameEventStruct_t dmg_healthNameParams{0};
- UnkGameEventStruct_t dmg_armorNameParams{0};
- UnkGameEventStruct_t hitgroupNameParams{0};
-
- static const auto healthStr = "health";
- static const auto armorStr = "armor";
- static const auto weaponStr = "weapon";
- static const auto dmg_healthStr = "dmg_health";
- static const auto dmg_armorStr = "dmg_armor";
- static const auto hitgroupStr = "hitgroup";
-
- // healthNameParams.m_Unk = Offset::FnServerHashFunction(
- // healthStr, sizeof healthStr, SERVER_HASH_FUCNTION_KEY);
- // healthNameParams.m_Key = healthStr;
-
- armorNameParams.m_Unk = Offset::FnServerHashFunction(
- armorStr, sizeof armorStr, SERVER_HASH_FUCNTION_KEY);
- armorNameParams.m_Key = armorStr;
-
- weaponNameParams.m_Unk = Offset::FnServerHashFunction(
- weaponStr, sizeof weaponStr, SERVER_HASH_FUCNTION_KEY);
-
- weaponNameParams.m_Key = weaponStr;
-
- dmg_healthNameParams.m_Unk = Offset::FnServerHashFunction(
- dmg_healthStr, sizeof dmg_healthStr, SERVER_HASH_FUCNTION_KEY);
- dmg_healthNameParams.m_Key = dmg_healthStr;
-
- dmg_armorNameParams.m_Unk = Offset::FnServerHashFunction(
- dmg_armorStr, sizeof dmg_armorStr, SERVER_HASH_FUCNTION_KEY);
- dmg_armorNameParams.m_Key = dmg_armorStr;
-
- hitgroupNameParams.m_Unk = Offset::FnServerHashFunction(
- hitgroupStr, sizeof hitgroupStr, SERVER_HASH_FUCNTION_KEY);
- hitgroupNameParams.m_Key = hitgroupStr;
+ GameEventKeySymbol_t userIdNameParams{"userid"};
+ GameEventKeySymbol_t attackerNameParams{"attacker"};
+ GameEventKeySymbol_t healthNameParams{"health"};
+ GameEventKeySymbol_t armorNameParams{"armor"};
+ GameEventKeySymbol_t weaponNameParams{"weapon"};
+ GameEventKeySymbol_t dmg_healthNameParams{"dmg_health"};
+ GameEventKeySymbol_t dmg_armorNameParams{"dmg_armor"};
+ GameEventKeySymbol_t hitgroupNameParams{"hitgroup"};
const auto victimPawn = reinterpret_cast(
- event->GetPlayerPawn(&userIdNameParams));
+ event->GetPlayerPawn(userIdNameParams));
const auto attackerPawn = reinterpret_cast(
- event->GetPlayerPawn(&attackerNameParams));
+ event->GetPlayerPawn(attackerNameParams));
if (victimPawn == nullptr || attackerPawn == nullptr) {
return;
}
@@ -67,12 +66,12 @@ auto OnPlayerHurtEvent(IGameEvent* event) -> void {
const auto victimIndex = victim->GetRefEHandle().GetEntryIndex();
const auto attackerIndex = attacker->GetRefEHandle().GetEntryIndex();
- auto health = event->GetInt(&healthNameParams);
- auto armor = event->GetInt(&armorNameParams);
- auto weapon = event->GetString(&weaponNameParams);
- auto dmg_health = event->GetInt(&dmg_healthNameParams);
- auto dmg_armor = event->GetInt(&dmg_armorNameParams);
- auto hitgroup = event->GetInt(&hitgroupNameParams);
+ auto health = event->GetInt(healthNameParams);
+ auto armor = event->GetInt(armorNameParams);
+ auto weapon = event->GetString(weaponNameParams);
+ auto dmg_health = event->GetInt(dmg_healthNameParams);
+ auto dmg_armor = event->GetInt(dmg_armorNameParams);
+ auto hitgroup = event->GetInt(hitgroupNameParams);
ScriptCallBacks::luaCall_onPlayerHurt(victimIndex, attackerIndex, health,
armor, weapon, dmg_health, dmg_armor,
hitgroup);
@@ -84,45 +83,25 @@ auto OnRoundEndEvent(IGameEvent* event) -> void {
"message" "string" // end round message
*/
- UnkGameEventStruct_t winnerNameParams{0};
- UnkGameEventStruct_t reasonNameParams{0};
- UnkGameEventStruct_t messageNameParams{0};
-
- static const auto winnerStr = "winner";
- static const auto reasonStr = "reason";
- static const auto messageStr = "message";
+ GameEventKeySymbol_t winnerNameParams{"winner"};
+ GameEventKeySymbol_t reasonNameParams{"reason"};
+ GameEventKeySymbol_t messageNameParams{"message"};
- winnerNameParams.m_Unk = Offset::FnServerHashFunction(
- winnerStr, sizeof winnerStr, SERVER_HASH_FUCNTION_KEY);
- winnerNameParams.m_Key = winnerStr;
-
- reasonNameParams.m_Unk = Offset::FnServerHashFunction(
- reasonStr, sizeof reasonStr, SERVER_HASH_FUCNTION_KEY);
- reasonNameParams.m_Key = reasonStr;
-
- messageNameParams.m_Unk = Offset::FnServerHashFunction(
- messageStr, sizeof messageStr, SERVER_HASH_FUCNTION_KEY);
- messageNameParams.m_Key = messageStr;
-
- const auto message = event->GetString(&messageNameParams);
- const auto winner = event->GetInt(&winnerNameParams);
- const auto reason = event->GetInt(&reasonNameParams);
+ const auto message = event->GetString(messageNameParams);
+ const auto winner = event->GetInt(winnerNameParams);
+ const auto reason = event->GetInt(reasonNameParams);
ScriptCallBacks::luaCall_onRoundEnd(winner, reason, message);
}
auto OnRoundStartEvent(IGameEvent* event) -> void {
- UnkGameEventStruct_t timelimitNameParams{0};
- static const auto timelimitStr = "timelimit";
- timelimitNameParams.m_Unk = Offset::FnServerHashFunction(
- timelimitStr, sizeof timelimitStr, SERVER_HASH_FUCNTION_KEY);
- timelimitNameParams.m_Key = timelimitStr;
- const auto timelimit = event->GetInt(&timelimitNameParams);
+ GameEventKeySymbol_t timelimitNameParams{"timelimit"};
+ const auto timelimit = event->GetInt(timelimitNameParams);
ScriptCallBacks::luaCall_onRoundStart(timelimit);
}
auto OnPlayerSpawnEvent(IGameEvent* event) -> void {
- UnkGameEventStruct_t userIdNameParams{"userid"};
+ GameEventKeySymbol_t userIdNameParams{"userid"};
const auto playerPawn = reinterpret_cast(
- event->GetPlayerPawn(&userIdNameParams));
+ event->GetPlayerPawn(userIdNameParams));
if (playerPawn == nullptr) {
return;
}
@@ -134,18 +113,15 @@ auto OnPlayerSpawnEvent(IGameEvent* event) -> void {
ScriptCallBacks::luaCall_onPlayerSpawn(playerIndex);
}
auto OnPlayerDeathEvent(IGameEvent* event) -> void {
- UnkGameEventStruct_t userIdNameParams{"userid"};
- UnkGameEventStruct_t attackerNameParams{"attacker"};
- UnkGameEventStruct_t headshotNameParams{0};
- static const auto headShotStr = "headshot";
- headshotNameParams.m_Unk = Offset::FnServerHashFunction(
- headShotStr, sizeof headShotStr, SERVER_HASH_FUCNTION_KEY);
- headshotNameParams.m_Key = headShotStr;
+ GameEventKeySymbol_t userIdNameParams{"userid"};
+ GameEventKeySymbol_t attackerNameParams{"attacker"};
+ GameEventKeySymbol_t headshotNameParams{"headshot"};
+
const auto victimPawn = reinterpret_cast(
- event->GetPlayerPawn(&userIdNameParams));
+ event->GetPlayerPawn(userIdNameParams));
const auto attackerPawn = reinterpret_cast(
- event->GetPlayerPawn(&attackerNameParams));
- const auto isHeadShot = event->GetBool(&headshotNameParams);
+ event->GetPlayerPawn(attackerNameParams));
+ const auto isHeadShot = event->GetBool(headshotNameParams);
if (victimPawn == nullptr || attackerPawn == nullptr) {
return;
}
@@ -165,6 +141,9 @@ auto OnPlayerDeathEvent(IGameEvent* event) -> void {
// printf("player[%p] %s kill[%p] %llu\n", attacker,
// &attacker->m_iszPlayerName(), victim, &victim->m_steamID());
}
+auto OnConsoleChat(std::string message) -> bool {
+ return ScriptCallBacks::luaCall_onPlayerSpeak(-1, static_cast(_ChatType::kConsole), message);
+}
auto OnPlayerChat(CCSPlayerController* player, std::string message) -> bool {
auto [procesChatSuccess, chatType, chatCtx] =
SdkTools::ProcessChatString(message);
@@ -172,7 +151,8 @@ auto OnPlayerChat(CCSPlayerController* player, std::string message) -> bool {
return false;
}
return ScriptCallBacks::luaCall_onPlayerSpeak(
- player->GetRefEHandle().GetEntryIndex(), chatType, chatCtx);
+ player->GetRefEHandle().GetEntryIndex(), static_cast(chatType),
+ chatCtx);
}
auto OnPlayerConnect(int slot, const char* pszName, uint64_t xuid,
const char* pszNetworkID, const char* pszAddress,
diff --git a/csgo2/events.h b/csgo2/events.h
index a39ca12..d0eae3f 100644
--- a/csgo2/events.h
+++ b/csgo2/events.h
@@ -4,6 +4,7 @@ class CCSPlayerController;
namespace events {
auto OnPlayerDeathEvent(IGameEvent* event) -> void;
auto OnPlayerChat(CCSPlayerController* player, std::string message) -> bool;
+auto OnConsoleChat(std::string message) -> bool;
auto OnPlayerConnect(int slot, const char* pszName, uint64_t xuid,
const char* pszNetworkID, const char* pszAddress,
bool bFakePlayer) -> void;
@@ -14,4 +15,5 @@ auto OnPlayerSpawnEvent(IGameEvent* event) -> void;
auto OnRoundStartEvent(IGameEvent* event) -> void;
auto OnRoundEndEvent(IGameEvent* event) -> void;
auto OnPlayerHurtEvent(IGameEvent* event) -> void;
+auto OnPlayerTeamChangeEevent(IGameEvent* event) -> void;
} // namespace events
diff --git a/csgo2/global.cpp b/csgo2/global.cpp
index 1c49f54..9f8ded0 100644
--- a/csgo2/global.cpp
+++ b/csgo2/global.cpp
@@ -7,4 +7,5 @@ namespace global {
CGlobalVars* GlobalVars;
float m_flUniversalTime;
float m_flLastTickedTime;
+ bool isMetaModInit;
}
\ No newline at end of file
diff --git a/csgo2/global.h b/csgo2/global.h
index 41ccf18..802a32a 100644
--- a/csgo2/global.h
+++ b/csgo2/global.h
@@ -10,4 +10,5 @@ namespace global {
extern CGlobalVars* GlobalVars;
extern float m_flUniversalTime;
extern float m_flLastTickedTime;
+ extern bool isMetaModInit;
}
\ No newline at end of file
diff --git a/csgo2/head.h b/csgo2/head.h
index 4abf661..dfc8fcb 100644
--- a/csgo2/head.h
+++ b/csgo2/head.h
@@ -62,3 +62,4 @@ static void DebugPrintA(const char* format, ...) {
#include "script_callbacks.h"
#include "timer.h"
#include "weapon.h"
+#include "Server.h"
\ No newline at end of file
diff --git a/csgo2/hooks.cpp b/csgo2/hooks.cpp
index 4300839..fa89dc7 100644
--- a/csgo2/hooks.cpp
+++ b/csgo2/hooks.cpp
@@ -13,7 +13,7 @@ Host_Say_t original_Host_Say = NULL;
StartupServer_t origin_StartServer = NULL;
GameFrame_t origin_GameFrame = NULL;
CCSWeaponBase_Spawn_t origin_CCSWeaponBase_Spawn = NULL;
-
+// https://github.com/Source2ZE/CS2Fixes/blob/main/src/commands.cpp#L494
void __fastcall hook_CCSWeaponBase_Spawn(CBaseEntity* pThis, void* a2) {
const char* pszClassName = pThis->m_pEntity()->m_designerName;
@@ -31,14 +31,26 @@ void __fastcall hook_CCSWeaponBase_Spawn(CBaseEntity* pThis, void* a2) {
pWeapon->m_AttributeManager()->m_Item()->m_bInitialized()) {
break;
}
- if (GameWeapons::WeaponMap.find(pszClassName) ==
- GameWeapons::WeaponMap.end()) {
+ const auto weaponName = Tools::toLower(std::string(pszClassName));
+ auto lookupWeaponSimpleName = std::string();
+ for (const auto& weapon : GameWeapons::WeaponMap) {
+ const auto& key = weapon.first;
+ const auto& [fullWeaponName, weaponItemDefIndex] = weapon.second;
+ if (fullWeaponName.find(weaponName) == std::string::npos) {
+ continue;
+ }
+ lookupWeaponSimpleName = key;
+ break;
+ }
+ if (lookupWeaponSimpleName.size() <= 1) {
break;
}
+ // lazy , fix me
const auto [fullWeaponName, weaponiItemDefIndex] =
- GameWeapons::WeaponMap.at(pszClassName);
+ GameWeapons::WeaponMap.at(lookupWeaponSimpleName);
- LOG("Fixing a %s with index = %d and initialized = %d\n", pszClassName,
+ LOG("Fixing a %s with index = %d and initialized = %d\n",
+ fullWeaponName.c_str(),
pWeapon->m_AttributeManager()->m_Item()->m_iItemDefinitionIndex(),
pWeapon->m_AttributeManager()->m_Item()->m_bInitialized());
@@ -56,22 +68,23 @@ void __fastcall hook_GameFrame(void* rcx, bool simulating, bool bFirstTick,
* true | game is ticking
* false | game is not ticking
*/
- if (simulating && global::HasTicked) {
- global::m_flUniversalTime +=
- global::GlobalVars->curtime - global::m_flLastTickedTime;
- } else {
- global::m_flUniversalTime += global::GlobalVars->interval_per_tick;
- }
+ if (global::GlobalVars != nullptr) {
+ if (simulating && global::HasTicked) {
+ global::m_flUniversalTime +=
+ global::GlobalVars->curtime - global::m_flLastTickedTime;
+ } else {
+ global::m_flUniversalTime += global::GlobalVars->interval_per_tick;
+ }
- global::m_flLastTickedTime = global::GlobalVars->curtime;
- global::HasTicked = true;
+ global::m_flLastTickedTime = global::GlobalVars->curtime;
+ global::HasTicked = true;
+ GameTimer::ExcuteTimers();
+ GameTickRunTime::ExcuteTickFunctions();
+ }
if (global::EntitySystem == nullptr) {
global::EntitySystem = CGameEntitySystem::GetInstance();
}
-
- GameTimer::ExcuteTimers();
- GameTickRunTime::ExcuteTickFunctions();
return origin_GameFrame(rcx, simulating, bFirstTick, bLastTick);
}
void __fastcall hook_StartServer(void* rcx,
@@ -126,11 +139,17 @@ void __fastcall hook_Host_Say(void* pEntity, void* args, bool teamonly,
char* pos = nullptr;
bool blockMsg = false;
do {
- if (theArgs == nullptr || theEntity == nullptr) {
+ if (theArgs == nullptr) {
break;
}
const auto message = std::string(theArgs->GetCommandString());
-
+ if (theEntity == nullptr) {
+ if (events::OnConsoleChat(message) == true) {
+ blockMsg = true;
+ break;
+ }
+ break;
+ }
if (events::OnPlayerChat(theEntity, message) == true) {
blockMsg = true;
break;
@@ -169,6 +188,7 @@ bool __fastcall hook_FireEventServerSide(CGameEventManager* rcx,
static constexpr auto round_start = hash_32_fnv1a_const("round_start");
static constexpr auto round_end = hash_32_fnv1a_const("round_end");
static constexpr auto player_hurt = hash_32_fnv1a_const("player_hurt");
+ static constexpr auto player_team = hash_32_fnv1a_const("player_team");
switch (hash_32_fnv1a_const(eventName)) {
case player_death:
@@ -186,6 +206,9 @@ bool __fastcall hook_FireEventServerSide(CGameEventManager* rcx,
case player_hurt:
events::OnPlayerHurtEvent(event);
break;
+ case player_team:
+ events::OnPlayerTeamChangeEevent(event);
+ break;
// Vbug,ⲻ
/*
case player_chat:
@@ -258,6 +281,9 @@ auto initVmtHook() -> bool {
return original_OnClientConnected && original_OnClientDisconnect &&
origin_StartServer && origin_GameFrame;
}
+auto initConVarHooks() -> void {
+ // Offset::InterFaces::IVEngineCvar->RegisterConVar
+}
auto init() -> bool {
bool isSuccess = initMinHook() && initVmtHook();
// bool isSuccess = initVmtHook();
diff --git a/csgo2/libcurl/inc/README.md b/csgo2/libcurl/inc/README.md
new file mode 100644
index 0000000..bd28a30
--- /dev/null
+++ b/csgo2/libcurl/inc/README.md
@@ -0,0 +1,14 @@
+# include
+
+Public include files for libcurl, external users.
+
+They're all placed in the curl subdirectory here for better fit in any kind of
+environment. You must include files from here using...
+
+ #include
+
+... style and point the compiler's include path to the directory holding the
+curl subdirectory. It makes it more likely to survive future modifications.
+
+The public curl include files can be shared freely between different platforms
+and different architectures.
diff --git a/csgo2/libcurl/inc/curl/.gitignore b/csgo2/libcurl/inc/curl/.gitignore
new file mode 100644
index 0000000..555795f
--- /dev/null
+++ b/csgo2/libcurl/inc/curl/.gitignore
@@ -0,0 +1,3 @@
+curlver.h.dist
+stamp-h2
+stamp-h3
diff --git a/csgo2/libcurl/inc/curl/Makefile.am b/csgo2/libcurl/inc/curl/Makefile.am
new file mode 100644
index 0000000..e772737
--- /dev/null
+++ b/csgo2/libcurl/inc/curl/Makefile.am
@@ -0,0 +1,39 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, , et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
+pkginclude_HEADERS = \
+ curl.h curlver.h easy.h mprintf.h stdcheaders.h multi.h \
+ typecheck-gcc.h system.h urlapi.h options.h
+
+pkgincludedir= $(includedir)/curl
+
+CHECKSRC = $(CS_$(V))
+CS_0 = @echo " RUN " $@;
+CS_1 =
+CS_ = $(CS_0)
+
+checksrc:
+ $(CHECKSRC)@PERL@ $(top_srcdir)/lib/checksrc.pl -D$(top_srcdir)/include/curl $(pkginclude_HEADERS)
+
+if CURLDEBUG
+# for debug builds, we scan the sources on all regular make invokes
+all-local: checksrc
+endif
diff --git a/csgo2/libcurl/inc/curl/curl.h b/csgo2/libcurl/inc/curl/curl.h
new file mode 100644
index 0000000..3c0461b
--- /dev/null
+++ b/csgo2/libcurl/inc/curl/curl.h
@@ -0,0 +1,3037 @@
+#ifndef CURLINC_CURL_H
+#define CURLINC_CURL_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, , et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * If you have libcurl problems, all docs and details are found here:
+ * https://curl.se/libcurl/
+ *
+ * curl-library mailing list subscription and unsubscription web interface:
+ * https://cool.haxx.se/mailman/listinfo/curl-library/
+ */
+
+#ifdef CURL_NO_OLDIES
+#define CURL_STRICTER
+#endif
+
+#include "curlver.h" /* libcurl version defines */
+#include "system.h" /* determine things run-time */
+
+/*
+ * Define CURL_WIN32 when build target is Win32 API
+ */
+
+#if (defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) && \
+ !defined(__SYMBIAN32__)
+#define CURL_WIN32
+#endif
+
+#include
+#include
+
+#if defined(__FreeBSD__) && (__FreeBSD__ >= 2)
+/* Needed for __FreeBSD_version symbol definition */
+#include
+#endif
+
+/* The include stuff here below is mainly for time_t! */
+#include
+#include
+
+#if defined(CURL_WIN32) && !defined(_WIN32_WCE) && !defined(__CYGWIN__)
+#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H) || \
+ defined(__LWIP_OPT_H__) || defined(LWIP_HDR_OPT_H))
+/* The check above prevents the winsock2 inclusion if winsock.h already was
+ included, since they can't co-exist without problems */
+#include
+#include
+#endif
+#endif
+
+/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish
+ libc5-based Linux systems. Only include it on systems that are known to
+ require it! */
+#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \
+ defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \
+ defined(ANDROID) || defined(__ANDROID__) || defined(__OpenBSD__) || \
+ defined(__CYGWIN__) || defined(AMIGA) || \
+ (defined(__FreeBSD_version) && (__FreeBSD_version < 800000))
+#include
+#endif
+
+#if !defined(CURL_WIN32) && !defined(_WIN32_WCE)
+#include
+#endif
+
+#if !defined(CURL_WIN32) && !defined(__WATCOMC__) && !defined(__VXWORKS__)
+#include
+#endif
+
+#ifdef __BEOS__
+#include
+#endif
+
+/* Compatibility for non-Clang compilers */
+#ifndef __has_declspec_attribute
+# define __has_declspec_attribute(x) 0
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER)
+typedef struct Curl_easy CURL;
+typedef struct Curl_share CURLSH;
+#else
+typedef void CURL;
+typedef void CURLSH;
+#endif
+
+/*
+ * libcurl external API function linkage decorations.
+ */
+
+#ifdef CURL_STATICLIB
+# define CURL_EXTERN
+#elif defined(CURL_WIN32) || defined(__SYMBIAN32__) || \
+ (__has_declspec_attribute(dllexport) && \
+ __has_declspec_attribute(dllimport))
+# if defined(BUILDING_LIBCURL)
+# define CURL_EXTERN __declspec(dllexport)
+# else
+# define CURL_EXTERN __declspec(dllimport)
+# endif
+#elif defined(BUILDING_LIBCURL) && defined(CURL_HIDDEN_SYMBOLS)
+# define CURL_EXTERN CURL_EXTERN_SYMBOL
+#else
+# define CURL_EXTERN
+#endif
+
+#ifndef curl_socket_typedef
+/* socket typedef */
+#if defined(CURL_WIN32) && !defined(__LWIP_OPT_H__) && !defined(LWIP_HDR_OPT_H)
+typedef SOCKET curl_socket_t;
+#define CURL_SOCKET_BAD INVALID_SOCKET
+#else
+typedef int curl_socket_t;
+#define CURL_SOCKET_BAD -1
+#endif
+#define curl_socket_typedef
+#endif /* curl_socket_typedef */
+
+/* enum for the different supported SSL backends */
+typedef enum {
+ CURLSSLBACKEND_NONE = 0,
+ CURLSSLBACKEND_OPENSSL = 1,
+ CURLSSLBACKEND_GNUTLS = 2,
+ CURLSSLBACKEND_NSS = 3,
+ CURLSSLBACKEND_OBSOLETE4 = 4, /* Was QSOSSL. */
+ CURLSSLBACKEND_GSKIT = 5,
+ CURLSSLBACKEND_POLARSSL = 6,
+ CURLSSLBACKEND_WOLFSSL = 7,
+ CURLSSLBACKEND_SCHANNEL = 8,
+ CURLSSLBACKEND_SECURETRANSPORT = 9,
+ CURLSSLBACKEND_AXTLS = 10, /* never used since 7.63.0 */
+ CURLSSLBACKEND_MBEDTLS = 11,
+ CURLSSLBACKEND_MESALINK = 12,
+ CURLSSLBACKEND_BEARSSL = 13
+} curl_sslbackend;
+
+/* aliases for library clones and renames */
+#define CURLSSLBACKEND_LIBRESSL CURLSSLBACKEND_OPENSSL
+#define CURLSSLBACKEND_BORINGSSL CURLSSLBACKEND_OPENSSL
+
+/* deprecated names: */
+#define CURLSSLBACKEND_CYASSL CURLSSLBACKEND_WOLFSSL
+#define CURLSSLBACKEND_DARWINSSL CURLSSLBACKEND_SECURETRANSPORT
+
+struct curl_httppost {
+ struct curl_httppost *next; /* next entry in the list */
+ char *name; /* pointer to allocated name */
+ long namelength; /* length of name length */
+ char *contents; /* pointer to allocated data contents */
+ long contentslength; /* length of contents field, see also
+ CURL_HTTPPOST_LARGE */
+ char *buffer; /* pointer to allocated buffer contents */
+ long bufferlength; /* length of buffer field */
+ char *contenttype; /* Content-Type */
+ struct curl_slist *contentheader; /* list of extra headers for this form */
+ struct curl_httppost *more; /* if one field name has more than one
+ file, this link should link to following
+ files */
+ long flags; /* as defined below */
+
+/* specified content is a file name */
+#define CURL_HTTPPOST_FILENAME (1<<0)
+/* specified content is a file name */
+#define CURL_HTTPPOST_READFILE (1<<1)
+/* name is only stored pointer do not free in formfree */
+#define CURL_HTTPPOST_PTRNAME (1<<2)
+/* contents is only stored pointer do not free in formfree */
+#define CURL_HTTPPOST_PTRCONTENTS (1<<3)
+/* upload file from buffer */
+#define CURL_HTTPPOST_BUFFER (1<<4)
+/* upload file from pointer contents */
+#define CURL_HTTPPOST_PTRBUFFER (1<<5)
+/* upload file contents by using the regular read callback to get the data and
+ pass the given pointer as custom pointer */
+#define CURL_HTTPPOST_CALLBACK (1<<6)
+/* use size in 'contentlen', added in 7.46.0 */
+#define CURL_HTTPPOST_LARGE (1<<7)
+
+ char *showfilename; /* The file name to show. If not set, the
+ actual file name will be used (if this
+ is a file part) */
+ void *userp; /* custom pointer used for
+ HTTPPOST_CALLBACK posts */
+ curl_off_t contentlen; /* alternative length of contents
+ field. Used if CURL_HTTPPOST_LARGE is
+ set. Added in 7.46.0 */
+};
+
+
+/* This is a return code for the progress callback that, when returned, will
+ signal libcurl to continue executing the default progress function */
+#define CURL_PROGRESSFUNC_CONTINUE 0x10000001
+
+/* This is the CURLOPT_PROGRESSFUNCTION callback prototype. It is now
+ considered deprecated but was the only choice up until 7.31.0 */
+typedef int (*curl_progress_callback)(void *clientp,
+ double dltotal,
+ double dlnow,
+ double ultotal,
+ double ulnow);
+
+/* This is the CURLOPT_XFERINFOFUNCTION callback prototype. It was introduced
+ in 7.32.0, avoids the use of floating point numbers and provides more
+ detailed information. */
+typedef int (*curl_xferinfo_callback)(void *clientp,
+ curl_off_t dltotal,
+ curl_off_t dlnow,
+ curl_off_t ultotal,
+ curl_off_t ulnow);
+
+#ifndef CURL_MAX_READ_SIZE
+ /* The maximum receive buffer size configurable via CURLOPT_BUFFERSIZE. */
+#define CURL_MAX_READ_SIZE 524288
+#endif
+
+#ifndef CURL_MAX_WRITE_SIZE
+ /* Tests have proven that 20K is a very bad buffer size for uploads on
+ Windows, while 16K for some odd reason performed a lot better.
+ We do the ifndef check to allow this value to easier be changed at build
+ time for those who feel adventurous. The practical minimum is about
+ 400 bytes since libcurl uses a buffer of this size as a scratch area
+ (unrelated to network send operations). */
+#define CURL_MAX_WRITE_SIZE 16384
+#endif
+
+#ifndef CURL_MAX_HTTP_HEADER
+/* The only reason to have a max limit for this is to avoid the risk of a bad
+ server feeding libcurl with a never-ending header that will cause reallocs
+ infinitely */
+#define CURL_MAX_HTTP_HEADER (100*1024)
+#endif
+
+/* This is a magic return code for the write callback that, when returned,
+ will signal libcurl to pause receiving on the current transfer. */
+#define CURL_WRITEFUNC_PAUSE 0x10000001
+
+typedef size_t (*curl_write_callback)(char *buffer,
+ size_t size,
+ size_t nitems,
+ void *outstream);
+
+/* This callback will be called when a new resolver request is made */
+typedef int (*curl_resolver_start_callback)(void *resolver_state,
+ void *reserved, void *userdata);
+
+/* enumeration of file types */
+typedef enum {
+ CURLFILETYPE_FILE = 0,
+ CURLFILETYPE_DIRECTORY,
+ CURLFILETYPE_SYMLINK,
+ CURLFILETYPE_DEVICE_BLOCK,
+ CURLFILETYPE_DEVICE_CHAR,
+ CURLFILETYPE_NAMEDPIPE,
+ CURLFILETYPE_SOCKET,
+ CURLFILETYPE_DOOR, /* is possible only on Sun Solaris now */
+
+ CURLFILETYPE_UNKNOWN /* should never occur */
+} curlfiletype;
+
+#define CURLFINFOFLAG_KNOWN_FILENAME (1<<0)
+#define CURLFINFOFLAG_KNOWN_FILETYPE (1<<1)
+#define CURLFINFOFLAG_KNOWN_TIME (1<<2)
+#define CURLFINFOFLAG_KNOWN_PERM (1<<3)
+#define CURLFINFOFLAG_KNOWN_UID (1<<4)
+#define CURLFINFOFLAG_KNOWN_GID (1<<5)
+#define CURLFINFOFLAG_KNOWN_SIZE (1<<6)
+#define CURLFINFOFLAG_KNOWN_HLINKCOUNT (1<<7)
+
+/* Information about a single file, used when doing FTP wildcard matching */
+struct curl_fileinfo {
+ char *filename;
+ curlfiletype filetype;
+ time_t time; /* always zero! */
+ unsigned int perm;
+ int uid;
+ int gid;
+ curl_off_t size;
+ long int hardlinks;
+
+ struct {
+ /* If some of these fields is not NULL, it is a pointer to b_data. */
+ char *time;
+ char *perm;
+ char *user;
+ char *group;
+ char *target; /* pointer to the target filename of a symlink */
+ } strings;
+
+ unsigned int flags;
+
+ /* used internally */
+ char *b_data;
+ size_t b_size;
+ size_t b_used;
+};
+
+/* return codes for CURLOPT_CHUNK_BGN_FUNCTION */
+#define CURL_CHUNK_BGN_FUNC_OK 0
+#define CURL_CHUNK_BGN_FUNC_FAIL 1 /* tell the lib to end the task */
+#define CURL_CHUNK_BGN_FUNC_SKIP 2 /* skip this chunk over */
+
+/* if splitting of data transfer is enabled, this callback is called before
+ download of an individual chunk started. Note that parameter "remains" works
+ only for FTP wildcard downloading (for now), otherwise is not used */
+typedef long (*curl_chunk_bgn_callback)(const void *transfer_info,
+ void *ptr,
+ int remains);
+
+/* return codes for CURLOPT_CHUNK_END_FUNCTION */
+#define CURL_CHUNK_END_FUNC_OK 0
+#define CURL_CHUNK_END_FUNC_FAIL 1 /* tell the lib to end the task */
+
+/* If splitting of data transfer is enabled this callback is called after
+ download of an individual chunk finished.
+ Note! After this callback was set then it have to be called FOR ALL chunks.
+ Even if downloading of this chunk was skipped in CHUNK_BGN_FUNC.
+ This is the reason why we don't need "transfer_info" parameter in this
+ callback and we are not interested in "remains" parameter too. */
+typedef long (*curl_chunk_end_callback)(void *ptr);
+
+/* return codes for FNMATCHFUNCTION */
+#define CURL_FNMATCHFUNC_MATCH 0 /* string corresponds to the pattern */
+#define CURL_FNMATCHFUNC_NOMATCH 1 /* pattern doesn't match the string */
+#define CURL_FNMATCHFUNC_FAIL 2 /* an error occurred */
+
+/* callback type for wildcard downloading pattern matching. If the
+ string matches the pattern, return CURL_FNMATCHFUNC_MATCH value, etc. */
+typedef int (*curl_fnmatch_callback)(void *ptr,
+ const char *pattern,
+ const char *string);
+
+/* These are the return codes for the seek callbacks */
+#define CURL_SEEKFUNC_OK 0
+#define CURL_SEEKFUNC_FAIL 1 /* fail the entire transfer */
+#define CURL_SEEKFUNC_CANTSEEK 2 /* tell libcurl seeking can't be done, so
+ libcurl might try other means instead */
+typedef int (*curl_seek_callback)(void *instream,
+ curl_off_t offset,
+ int origin); /* 'whence' */
+
+/* This is a return code for the read callback that, when returned, will
+ signal libcurl to immediately abort the current transfer. */
+#define CURL_READFUNC_ABORT 0x10000000
+/* This is a return code for the read callback that, when returned, will
+ signal libcurl to pause sending data on the current transfer. */
+#define CURL_READFUNC_PAUSE 0x10000001
+
+/* Return code for when the trailing headers' callback has terminated
+ without any errors*/
+#define CURL_TRAILERFUNC_OK 0
+/* Return code for when was an error in the trailing header's list and we
+ want to abort the request */
+#define CURL_TRAILERFUNC_ABORT 1
+
+typedef size_t (*curl_read_callback)(char *buffer,
+ size_t size,
+ size_t nitems,
+ void *instream);
+
+typedef int (*curl_trailer_callback)(struct curl_slist **list,
+ void *userdata);
+
+typedef enum {
+ CURLSOCKTYPE_IPCXN, /* socket created for a specific IP connection */
+ CURLSOCKTYPE_ACCEPT, /* socket created by accept() call */
+ CURLSOCKTYPE_LAST /* never use */
+} curlsocktype;
+
+/* The return code from the sockopt_callback can signal information back
+ to libcurl: */
+#define CURL_SOCKOPT_OK 0
+#define CURL_SOCKOPT_ERROR 1 /* causes libcurl to abort and return
+ CURLE_ABORTED_BY_CALLBACK */
+#define CURL_SOCKOPT_ALREADY_CONNECTED 2
+
+typedef int (*curl_sockopt_callback)(void *clientp,
+ curl_socket_t curlfd,
+ curlsocktype purpose);
+
+struct curl_sockaddr {
+ int family;
+ int socktype;
+ int protocol;
+ unsigned int addrlen; /* addrlen was a socklen_t type before 7.18.0 but it
+ turned really ugly and painful on the systems that
+ lack this type */
+ struct sockaddr addr;
+};
+
+typedef curl_socket_t
+(*curl_opensocket_callback)(void *clientp,
+ curlsocktype purpose,
+ struct curl_sockaddr *address);
+
+typedef int
+(*curl_closesocket_callback)(void *clientp, curl_socket_t item);
+
+typedef enum {
+ CURLIOE_OK, /* I/O operation successful */
+ CURLIOE_UNKNOWNCMD, /* command was unknown to callback */
+ CURLIOE_FAILRESTART, /* failed to restart the read */
+ CURLIOE_LAST /* never use */
+} curlioerr;
+
+typedef enum {
+ CURLIOCMD_NOP, /* no operation */
+ CURLIOCMD_RESTARTREAD, /* restart the read stream from start */
+ CURLIOCMD_LAST /* never use */
+} curliocmd;
+
+typedef curlioerr (*curl_ioctl_callback)(CURL *handle,
+ int cmd,
+ void *clientp);
+
+#ifndef CURL_DID_MEMORY_FUNC_TYPEDEFS
+/*
+ * The following typedef's are signatures of malloc, free, realloc, strdup and
+ * calloc respectively. Function pointers of these types can be passed to the
+ * curl_global_init_mem() function to set user defined memory management
+ * callback routines.
+ */
+typedef void *(*curl_malloc_callback)(size_t size);
+typedef void (*curl_free_callback)(void *ptr);
+typedef void *(*curl_realloc_callback)(void *ptr, size_t size);
+typedef char *(*curl_strdup_callback)(const char *str);
+typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size);
+
+#define CURL_DID_MEMORY_FUNC_TYPEDEFS
+#endif
+
+/* the kind of data that is passed to information_callback*/
+typedef enum {
+ CURLINFO_TEXT = 0,
+ CURLINFO_HEADER_IN, /* 1 */
+ CURLINFO_HEADER_OUT, /* 2 */
+ CURLINFO_DATA_IN, /* 3 */
+ CURLINFO_DATA_OUT, /* 4 */
+ CURLINFO_SSL_DATA_IN, /* 5 */
+ CURLINFO_SSL_DATA_OUT, /* 6 */
+ CURLINFO_END
+} curl_infotype;
+
+typedef int (*curl_debug_callback)
+ (CURL *handle, /* the handle/transfer this concerns */
+ curl_infotype type, /* what kind of data */
+ char *data, /* points to the data */
+ size_t size, /* size of the data pointed to */
+ void *userptr); /* whatever the user please */
+
+/* All possible error codes from all sorts of curl functions. Future versions
+ may return other values, stay prepared.
+
+ Always add new return codes last. Never *EVER* remove any. The return
+ codes must remain the same!
+ */
+
+typedef enum {
+ CURLE_OK = 0,
+ CURLE_UNSUPPORTED_PROTOCOL, /* 1 */
+ CURLE_FAILED_INIT, /* 2 */
+ CURLE_URL_MALFORMAT, /* 3 */
+ CURLE_NOT_BUILT_IN, /* 4 - [was obsoleted in August 2007 for
+ 7.17.0, reused in April 2011 for 7.21.5] */
+ CURLE_COULDNT_RESOLVE_PROXY, /* 5 */
+ CURLE_COULDNT_RESOLVE_HOST, /* 6 */
+ CURLE_COULDNT_CONNECT, /* 7 */
+ CURLE_WEIRD_SERVER_REPLY, /* 8 */
+ CURLE_REMOTE_ACCESS_DENIED, /* 9 a service was denied by the server
+ due to lack of access - when login fails
+ this is not returned. */
+ CURLE_FTP_ACCEPT_FAILED, /* 10 - [was obsoleted in April 2006 for
+ 7.15.4, reused in Dec 2011 for 7.24.0]*/
+ CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */
+ CURLE_FTP_ACCEPT_TIMEOUT, /* 12 - timeout occurred accepting server
+ [was obsoleted in August 2007 for 7.17.0,
+ reused in Dec 2011 for 7.24.0]*/
+ CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */
+ CURLE_FTP_WEIRD_227_FORMAT, /* 14 */
+ CURLE_FTP_CANT_GET_HOST, /* 15 */
+ CURLE_HTTP2, /* 16 - A problem in the http2 framing layer.
+ [was obsoleted in August 2007 for 7.17.0,
+ reused in July 2014 for 7.38.0] */
+ CURLE_FTP_COULDNT_SET_TYPE, /* 17 */
+ CURLE_PARTIAL_FILE, /* 18 */
+ CURLE_FTP_COULDNT_RETR_FILE, /* 19 */
+ CURLE_OBSOLETE20, /* 20 - NOT USED */
+ CURLE_QUOTE_ERROR, /* 21 - quote command failure */
+ CURLE_HTTP_RETURNED_ERROR, /* 22 */
+ CURLE_WRITE_ERROR, /* 23 */
+ CURLE_OBSOLETE24, /* 24 - NOT USED */
+ CURLE_UPLOAD_FAILED, /* 25 - failed upload "command" */
+ CURLE_READ_ERROR, /* 26 - couldn't open/read from file */
+ CURLE_OUT_OF_MEMORY, /* 27 */
+ /* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error
+ instead of a memory allocation error if CURL_DOES_CONVERSIONS
+ is defined
+ */
+ CURLE_OPERATION_TIMEDOUT, /* 28 - the timeout time was reached */
+ CURLE_OBSOLETE29, /* 29 - NOT USED */
+ CURLE_FTP_PORT_FAILED, /* 30 - FTP PORT operation failed */
+ CURLE_FTP_COULDNT_USE_REST, /* 31 - the REST command failed */
+ CURLE_OBSOLETE32, /* 32 - NOT USED */
+ CURLE_RANGE_ERROR, /* 33 - RANGE "command" didn't work */
+ CURLE_HTTP_POST_ERROR, /* 34 */
+ CURLE_SSL_CONNECT_ERROR, /* 35 - wrong when connecting with SSL */
+ CURLE_BAD_DOWNLOAD_RESUME, /* 36 - couldn't resume download */
+ CURLE_FILE_COULDNT_READ_FILE, /* 37 */
+ CURLE_LDAP_CANNOT_BIND, /* 38 */
+ CURLE_LDAP_SEARCH_FAILED, /* 39 */
+ CURLE_OBSOLETE40, /* 40 - NOT USED */
+ CURLE_FUNCTION_NOT_FOUND, /* 41 - NOT USED starting with 7.53.0 */
+ CURLE_ABORTED_BY_CALLBACK, /* 42 */
+ CURLE_BAD_FUNCTION_ARGUMENT, /* 43 */
+ CURLE_OBSOLETE44, /* 44 - NOT USED */
+ CURLE_INTERFACE_FAILED, /* 45 - CURLOPT_INTERFACE failed */
+ CURLE_OBSOLETE46, /* 46 - NOT USED */
+ CURLE_TOO_MANY_REDIRECTS, /* 47 - catch endless re-direct loops */
+ CURLE_UNKNOWN_OPTION, /* 48 - User specified an unknown option */
+ CURLE_TELNET_OPTION_SYNTAX, /* 49 - Malformed telnet option */
+ CURLE_OBSOLETE50, /* 50 - NOT USED */
+ CURLE_OBSOLETE51, /* 51 - NOT USED */
+ CURLE_GOT_NOTHING, /* 52 - when this is a specific error */
+ CURLE_SSL_ENGINE_NOTFOUND, /* 53 - SSL crypto engine not found */
+ CURLE_SSL_ENGINE_SETFAILED, /* 54 - can not set SSL crypto engine as
+ default */
+ CURLE_SEND_ERROR, /* 55 - failed sending network data */
+ CURLE_RECV_ERROR, /* 56 - failure in receiving network data */
+ CURLE_OBSOLETE57, /* 57 - NOT IN USE */
+ CURLE_SSL_CERTPROBLEM, /* 58 - problem with the local certificate */
+ CURLE_SSL_CIPHER, /* 59 - couldn't use specified cipher */
+ CURLE_PEER_FAILED_VERIFICATION, /* 60 - peer's certificate or fingerprint
+ wasn't verified fine */
+ CURLE_BAD_CONTENT_ENCODING, /* 61 - Unrecognized/bad encoding */
+ CURLE_LDAP_INVALID_URL, /* 62 - Invalid LDAP URL */
+ CURLE_FILESIZE_EXCEEDED, /* 63 - Maximum file size exceeded */
+ CURLE_USE_SSL_FAILED, /* 64 - Requested FTP SSL level failed */
+ CURLE_SEND_FAIL_REWIND, /* 65 - Sending the data requires a rewind
+ that failed */
+ CURLE_SSL_ENGINE_INITFAILED, /* 66 - failed to initialise ENGINE */
+ CURLE_LOGIN_DENIED, /* 67 - user, password or similar was not
+ accepted and we failed to login */
+ CURLE_TFTP_NOTFOUND, /* 68 - file not found on server */
+ CURLE_TFTP_PERM, /* 69 - permission problem on server */
+ CURLE_REMOTE_DISK_FULL, /* 70 - out of disk space on server */
+ CURLE_TFTP_ILLEGAL, /* 71 - Illegal TFTP operation */
+ CURLE_TFTP_UNKNOWNID, /* 72 - Unknown transfer ID */
+ CURLE_REMOTE_FILE_EXISTS, /* 73 - File already exists */
+ CURLE_TFTP_NOSUCHUSER, /* 74 - No such user */
+ CURLE_CONV_FAILED, /* 75 - conversion failed */
+ CURLE_CONV_REQD, /* 76 - caller must register conversion
+ callbacks using curl_easy_setopt options
+ CURLOPT_CONV_FROM_NETWORK_FUNCTION,
+ CURLOPT_CONV_TO_NETWORK_FUNCTION, and
+ CURLOPT_CONV_FROM_UTF8_FUNCTION */
+ CURLE_SSL_CACERT_BADFILE, /* 77 - could not load CACERT file, missing
+ or wrong format */
+ CURLE_REMOTE_FILE_NOT_FOUND, /* 78 - remote file not found */
+ CURLE_SSH, /* 79 - error from the SSH layer, somewhat
+ generic so the error message will be of
+ interest when this has happened */
+
+ CURLE_SSL_SHUTDOWN_FAILED, /* 80 - Failed to shut down the SSL
+ connection */
+ CURLE_AGAIN, /* 81 - socket is not ready for send/recv,
+ wait till it's ready and try again (Added
+ in 7.18.2) */
+ CURLE_SSL_CRL_BADFILE, /* 82 - could not load CRL file, missing or
+ wrong format (Added in 7.19.0) */
+ CURLE_SSL_ISSUER_ERROR, /* 83 - Issuer check failed. (Added in
+ 7.19.0) */
+ CURLE_FTP_PRET_FAILED, /* 84 - a PRET command failed */
+ CURLE_RTSP_CSEQ_ERROR, /* 85 - mismatch of RTSP CSeq numbers */
+ CURLE_RTSP_SESSION_ERROR, /* 86 - mismatch of RTSP Session Ids */
+ CURLE_FTP_BAD_FILE_LIST, /* 87 - unable to parse FTP file list */
+ CURLE_CHUNK_FAILED, /* 88 - chunk callback reported error */
+ CURLE_NO_CONNECTION_AVAILABLE, /* 89 - No connection available, the
+ session will be queued */
+ CURLE_SSL_PINNEDPUBKEYNOTMATCH, /* 90 - specified pinned public key did not
+ match */
+ CURLE_SSL_INVALIDCERTSTATUS, /* 91 - invalid certificate status */
+ CURLE_HTTP2_STREAM, /* 92 - stream error in HTTP/2 framing layer
+ */
+ CURLE_RECURSIVE_API_CALL, /* 93 - an api function was called from
+ inside a callback */
+ CURLE_AUTH_ERROR, /* 94 - an authentication function returned an
+ error */
+ CURLE_HTTP3, /* 95 - An HTTP/3 layer problem */
+ CURLE_QUIC_CONNECT_ERROR, /* 96 - QUIC connection error */
+ CURLE_PROXY, /* 97 - proxy handshake error */
+ CURL_LAST /* never use! */
+} CURLcode;
+
+#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
+ the obsolete stuff removed! */
+
+/* Previously obsolete error code re-used in 7.38.0 */
+#define CURLE_OBSOLETE16 CURLE_HTTP2
+
+/* Previously obsolete error codes re-used in 7.24.0 */
+#define CURLE_OBSOLETE10 CURLE_FTP_ACCEPT_FAILED
+#define CURLE_OBSOLETE12 CURLE_FTP_ACCEPT_TIMEOUT
+
+/* compatibility with older names */
+#define CURLOPT_ENCODING CURLOPT_ACCEPT_ENCODING
+#define CURLE_FTP_WEIRD_SERVER_REPLY CURLE_WEIRD_SERVER_REPLY
+
+/* The following were added in 7.62.0 */
+#define CURLE_SSL_CACERT CURLE_PEER_FAILED_VERIFICATION
+
+/* The following were added in 7.21.5, April 2011 */
+#define CURLE_UNKNOWN_TELNET_OPTION CURLE_UNKNOWN_OPTION
+
+/* The following were added in 7.17.1 */
+/* These are scheduled to disappear by 2009 */
+#define CURLE_SSL_PEER_CERTIFICATE CURLE_PEER_FAILED_VERIFICATION
+
+/* The following were added in 7.17.0 */
+/* These are scheduled to disappear by 2009 */
+#define CURLE_OBSOLETE CURLE_OBSOLETE50 /* no one should be using this! */
+#define CURLE_BAD_PASSWORD_ENTERED CURLE_OBSOLETE46
+#define CURLE_BAD_CALLING_ORDER CURLE_OBSOLETE44
+#define CURLE_FTP_USER_PASSWORD_INCORRECT CURLE_OBSOLETE10
+#define CURLE_FTP_CANT_RECONNECT CURLE_OBSOLETE16
+#define CURLE_FTP_COULDNT_GET_SIZE CURLE_OBSOLETE32
+#define CURLE_FTP_COULDNT_SET_ASCII CURLE_OBSOLETE29
+#define CURLE_FTP_WEIRD_USER_REPLY CURLE_OBSOLETE12
+#define CURLE_FTP_WRITE_ERROR CURLE_OBSOLETE20
+#define CURLE_LIBRARY_NOT_FOUND CURLE_OBSOLETE40
+#define CURLE_MALFORMAT_USER CURLE_OBSOLETE24
+#define CURLE_SHARE_IN_USE CURLE_OBSOLETE57
+#define CURLE_URL_MALFORMAT_USER CURLE_NOT_BUILT_IN
+
+#define CURLE_FTP_ACCESS_DENIED CURLE_REMOTE_ACCESS_DENIED
+#define CURLE_FTP_COULDNT_SET_BINARY CURLE_FTP_COULDNT_SET_TYPE
+#define CURLE_FTP_QUOTE_ERROR CURLE_QUOTE_ERROR
+#define CURLE_TFTP_DISKFULL CURLE_REMOTE_DISK_FULL
+#define CURLE_TFTP_EXISTS CURLE_REMOTE_FILE_EXISTS
+#define CURLE_HTTP_RANGE_ERROR CURLE_RANGE_ERROR
+#define CURLE_FTP_SSL_FAILED CURLE_USE_SSL_FAILED
+
+/* The following were added earlier */
+
+#define CURLE_OPERATION_TIMEOUTED CURLE_OPERATION_TIMEDOUT
+
+#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR
+#define CURLE_HTTP_PORT_FAILED CURLE_INTERFACE_FAILED
+#define CURLE_FTP_COULDNT_STOR_FILE CURLE_UPLOAD_FAILED
+
+#define CURLE_FTP_PARTIAL_FILE CURLE_PARTIAL_FILE
+#define CURLE_FTP_BAD_DOWNLOAD_RESUME CURLE_BAD_DOWNLOAD_RESUME
+
+/* This was the error code 50 in 7.7.3 and a few earlier versions, this
+ is no longer used by libcurl but is instead #defined here only to not
+ make programs break */
+#define CURLE_ALREADY_COMPLETE 99999
+
+/* Provide defines for really old option names */
+#define CURLOPT_FILE CURLOPT_WRITEDATA /* name changed in 7.9.7 */
+#define CURLOPT_INFILE CURLOPT_READDATA /* name changed in 7.9.7 */
+#define CURLOPT_WRITEHEADER CURLOPT_HEADERDATA
+
+/* Since long deprecated options with no code in the lib that does anything
+ with them. */
+#define CURLOPT_WRITEINFO CURLOPT_OBSOLETE40
+#define CURLOPT_CLOSEPOLICY CURLOPT_OBSOLETE72
+
+#endif /*!CURL_NO_OLDIES*/
+
+/*
+ * Proxy error codes. Returned in CURLINFO_PROXY_ERROR if CURLE_PROXY was
+ * return for the transfers.
+ */
+typedef enum {
+ CURLPX_OK,
+ CURLPX_BAD_ADDRESS_TYPE,
+ CURLPX_BAD_VERSION,
+ CURLPX_CLOSED,
+ CURLPX_GSSAPI,
+ CURLPX_GSSAPI_PERMSG,
+ CURLPX_GSSAPI_PROTECTION,
+ CURLPX_IDENTD,
+ CURLPX_IDENTD_DIFFER,
+ CURLPX_LONG_HOSTNAME,
+ CURLPX_LONG_PASSWD,
+ CURLPX_LONG_USER,
+ CURLPX_NO_AUTH,
+ CURLPX_RECV_ADDRESS,
+ CURLPX_RECV_AUTH,
+ CURLPX_RECV_CONNECT,
+ CURLPX_RECV_REQACK,
+ CURLPX_REPLY_ADDRESS_TYPE_NOT_SUPPORTED,
+ CURLPX_REPLY_COMMAND_NOT_SUPPORTED,
+ CURLPX_REPLY_CONNECTION_REFUSED,
+ CURLPX_REPLY_GENERAL_SERVER_FAILURE,
+ CURLPX_REPLY_HOST_UNREACHABLE,
+ CURLPX_REPLY_NETWORK_UNREACHABLE,
+ CURLPX_REPLY_NOT_ALLOWED,
+ CURLPX_REPLY_TTL_EXPIRED,
+ CURLPX_REPLY_UNASSIGNED,
+ CURLPX_REQUEST_FAILED,
+ CURLPX_RESOLVE_HOST,
+ CURLPX_SEND_AUTH,
+ CURLPX_SEND_CONNECT,
+ CURLPX_SEND_REQUEST,
+ CURLPX_UNKNOWN_FAIL,
+ CURLPX_UNKNOWN_MODE,
+ CURLPX_USER_REJECTED,
+ CURLPX_LAST /* never use */
+} CURLproxycode;
+
+/* This prototype applies to all conversion callbacks */
+typedef CURLcode (*curl_conv_callback)(char *buffer, size_t length);
+
+typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl, /* easy handle */
+ void *ssl_ctx, /* actually an OpenSSL
+ or WolfSSL SSL_CTX,
+ or an mbedTLS
+ mbedtls_ssl_config */
+ void *userptr);
+
+typedef enum {
+ CURLPROXY_HTTP = 0, /* added in 7.10, new in 7.19.4 default is to use
+ CONNECT HTTP/1.1 */
+ CURLPROXY_HTTP_1_0 = 1, /* added in 7.19.4, force to use CONNECT
+ HTTP/1.0 */
+ CURLPROXY_HTTPS = 2, /* added in 7.52.0 */
+ CURLPROXY_SOCKS4 = 4, /* support added in 7.15.2, enum existed already
+ in 7.10 */
+ CURLPROXY_SOCKS5 = 5, /* added in 7.10 */
+ CURLPROXY_SOCKS4A = 6, /* added in 7.18.0 */
+ CURLPROXY_SOCKS5_HOSTNAME = 7 /* Use the SOCKS5 protocol but pass along the
+ host name rather than the IP address. added
+ in 7.18.0 */
+} curl_proxytype; /* this enum was added in 7.10 */
+
+/*
+ * Bitmasks for CURLOPT_HTTPAUTH and CURLOPT_PROXYAUTH options:
+ *
+ * CURLAUTH_NONE - No HTTP authentication
+ * CURLAUTH_BASIC - HTTP Basic authentication (default)
+ * CURLAUTH_DIGEST - HTTP Digest authentication
+ * CURLAUTH_NEGOTIATE - HTTP Negotiate (SPNEGO) authentication
+ * CURLAUTH_GSSNEGOTIATE - Alias for CURLAUTH_NEGOTIATE (deprecated)
+ * CURLAUTH_NTLM - HTTP NTLM authentication
+ * CURLAUTH_DIGEST_IE - HTTP Digest authentication with IE flavour
+ * CURLAUTH_NTLM_WB - HTTP NTLM authentication delegated to winbind helper
+ * CURLAUTH_BEARER - HTTP Bearer token authentication
+ * CURLAUTH_ONLY - Use together with a single other type to force no
+ * authentication or just that single type
+ * CURLAUTH_ANY - All fine types set
+ * CURLAUTH_ANYSAFE - All fine types except Basic
+ */
+
+#define CURLAUTH_NONE ((unsigned long)0)
+#define CURLAUTH_BASIC (((unsigned long)1)<<0)
+#define CURLAUTH_DIGEST (((unsigned long)1)<<1)
+#define CURLAUTH_NEGOTIATE (((unsigned long)1)<<2)
+/* Deprecated since the advent of CURLAUTH_NEGOTIATE */
+#define CURLAUTH_GSSNEGOTIATE CURLAUTH_NEGOTIATE
+/* Used for CURLOPT_SOCKS5_AUTH to stay terminologically correct */
+#define CURLAUTH_GSSAPI CURLAUTH_NEGOTIATE
+#define CURLAUTH_NTLM (((unsigned long)1)<<3)
+#define CURLAUTH_DIGEST_IE (((unsigned long)1)<<4)
+#define CURLAUTH_NTLM_WB (((unsigned long)1)<<5)
+#define CURLAUTH_BEARER (((unsigned long)1)<<6)
+#define CURLAUTH_AWS_SIGV4 (((unsigned long)1)<<7)
+#define CURLAUTH_ONLY (((unsigned long)1)<<31)
+#define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE)
+#define CURLAUTH_ANYSAFE (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE))
+
+#define CURLSSH_AUTH_ANY ~0 /* all types supported by the server */
+#define CURLSSH_AUTH_NONE 0 /* none allowed, silly but complete */
+#define CURLSSH_AUTH_PUBLICKEY (1<<0) /* public/private key files */
+#define CURLSSH_AUTH_PASSWORD (1<<1) /* password */
+#define CURLSSH_AUTH_HOST (1<<2) /* host key files */
+#define CURLSSH_AUTH_KEYBOARD (1<<3) /* keyboard interactive */
+#define CURLSSH_AUTH_AGENT (1<<4) /* agent (ssh-agent, pageant...) */
+#define CURLSSH_AUTH_GSSAPI (1<<5) /* gssapi (kerberos, ...) */
+#define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY
+
+#define CURLGSSAPI_DELEGATION_NONE 0 /* no delegation (default) */
+#define CURLGSSAPI_DELEGATION_POLICY_FLAG (1<<0) /* if permitted by policy */
+#define CURLGSSAPI_DELEGATION_FLAG (1<<1) /* delegate always */
+
+#define CURL_ERROR_SIZE 256
+
+enum curl_khtype {
+ CURLKHTYPE_UNKNOWN,
+ CURLKHTYPE_RSA1,
+ CURLKHTYPE_RSA,
+ CURLKHTYPE_DSS,
+ CURLKHTYPE_ECDSA,
+ CURLKHTYPE_ED25519
+};
+
+struct curl_khkey {
+ const char *key; /* points to a null-terminated string encoded with base64
+ if len is zero, otherwise to the "raw" data */
+ size_t len;
+ enum curl_khtype keytype;
+};
+
+/* this is the set of return values expected from the curl_sshkeycallback
+ callback */
+enum curl_khstat {
+ CURLKHSTAT_FINE_ADD_TO_FILE,
+ CURLKHSTAT_FINE,
+ CURLKHSTAT_REJECT, /* reject the connection, return an error */
+ CURLKHSTAT_DEFER, /* do not accept it, but we can't answer right now so
+ this causes a CURLE_DEFER error but otherwise the
+ connection will be left intact etc */
+ CURLKHSTAT_FINE_REPLACE, /* accept and replace the wrong key*/
+ CURLKHSTAT_LAST /* not for use, only a marker for last-in-list */
+};
+
+/* this is the set of status codes pass in to the callback */
+enum curl_khmatch {
+ CURLKHMATCH_OK, /* match */
+ CURLKHMATCH_MISMATCH, /* host found, key mismatch! */
+ CURLKHMATCH_MISSING, /* no matching host/key found */
+ CURLKHMATCH_LAST /* not for use, only a marker for last-in-list */
+};
+
+typedef int
+ (*curl_sshkeycallback) (CURL *easy, /* easy handle */
+ const struct curl_khkey *knownkey, /* known */
+ const struct curl_khkey *foundkey, /* found */
+ enum curl_khmatch, /* libcurl's view on the keys */
+ void *clientp); /* custom pointer passed from app */
+
+/* parameter for the CURLOPT_USE_SSL option */
+typedef enum {
+ CURLUSESSL_NONE, /* do not attempt to use SSL */
+ CURLUSESSL_TRY, /* try using SSL, proceed anyway otherwise */
+ CURLUSESSL_CONTROL, /* SSL for the control connection or fail */
+ CURLUSESSL_ALL, /* SSL for all communication or fail */
+ CURLUSESSL_LAST /* not an option, never use */
+} curl_usessl;
+
+/* Definition of bits for the CURLOPT_SSL_OPTIONS argument: */
+
+/* - ALLOW_BEAST tells libcurl to allow the BEAST SSL vulnerability in the
+ name of improving interoperability with older servers. Some SSL libraries
+ have introduced work-arounds for this flaw but those work-arounds sometimes
+ make the SSL communication fail. To regain functionality with those broken
+ servers, a user can this way allow the vulnerability back. */
+#define CURLSSLOPT_ALLOW_BEAST (1<<0)
+
+/* - NO_REVOKE tells libcurl to disable certificate revocation checks for those
+ SSL backends where such behavior is present. */
+#define CURLSSLOPT_NO_REVOKE (1<<1)
+
+/* - NO_PARTIALCHAIN tells libcurl to *NOT* accept a partial certificate chain
+ if possible. The OpenSSL backend has this ability. */
+#define CURLSSLOPT_NO_PARTIALCHAIN (1<<2)
+
+/* - REVOKE_BEST_EFFORT tells libcurl to ignore certificate revocation offline
+ checks and ignore missing revocation list for those SSL backends where such
+ behavior is present. */
+#define CURLSSLOPT_REVOKE_BEST_EFFORT (1<<3)
+
+/* - CURLSSLOPT_NATIVE_CA tells libcurl to use standard certificate store of
+ operating system. Currently implemented under MS-Windows. */
+#define CURLSSLOPT_NATIVE_CA (1<<4)
+
+/* The default connection attempt delay in milliseconds for happy eyeballs.
+ CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3 and happy-eyeballs-timeout-ms.d document
+ this value, keep them in sync. */
+#define CURL_HET_DEFAULT 200L
+
+/* The default connection upkeep interval in milliseconds. */
+#define CURL_UPKEEP_INTERVAL_DEFAULT 60000L
+
+#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
+ the obsolete stuff removed! */
+
+/* Backwards compatibility with older names */
+/* These are scheduled to disappear by 2009 */
+
+#define CURLFTPSSL_NONE CURLUSESSL_NONE
+#define CURLFTPSSL_TRY CURLUSESSL_TRY
+#define CURLFTPSSL_CONTROL CURLUSESSL_CONTROL
+#define CURLFTPSSL_ALL CURLUSESSL_ALL
+#define CURLFTPSSL_LAST CURLUSESSL_LAST
+#define curl_ftpssl curl_usessl
+#endif /*!CURL_NO_OLDIES*/
+
+/* parameter for the CURLOPT_FTP_SSL_CCC option */
+typedef enum {
+ CURLFTPSSL_CCC_NONE, /* do not send CCC */
+ CURLFTPSSL_CCC_PASSIVE, /* Let the server initiate the shutdown */
+ CURLFTPSSL_CCC_ACTIVE, /* Initiate the shutdown */
+ CURLFTPSSL_CCC_LAST /* not an option, never use */
+} curl_ftpccc;
+
+/* parameter for the CURLOPT_FTPSSLAUTH option */
+typedef enum {
+ CURLFTPAUTH_DEFAULT, /* let libcurl decide */
+ CURLFTPAUTH_SSL, /* use "AUTH SSL" */
+ CURLFTPAUTH_TLS, /* use "AUTH TLS" */
+ CURLFTPAUTH_LAST /* not an option, never use */
+} curl_ftpauth;
+
+/* parameter for the CURLOPT_FTP_CREATE_MISSING_DIRS option */
+typedef enum {
+ CURLFTP_CREATE_DIR_NONE, /* do NOT create missing dirs! */
+ CURLFTP_CREATE_DIR, /* (FTP/SFTP) if CWD fails, try MKD and then CWD
+ again if MKD succeeded, for SFTP this does
+ similar magic */
+ CURLFTP_CREATE_DIR_RETRY, /* (FTP only) if CWD fails, try MKD and then CWD
+ again even if MKD failed! */
+ CURLFTP_CREATE_DIR_LAST /* not an option, never use */
+} curl_ftpcreatedir;
+
+/* parameter for the CURLOPT_FTP_FILEMETHOD option */
+typedef enum {
+ CURLFTPMETHOD_DEFAULT, /* let libcurl pick */
+ CURLFTPMETHOD_MULTICWD, /* single CWD operation for each path part */
+ CURLFTPMETHOD_NOCWD, /* no CWD at all */
+ CURLFTPMETHOD_SINGLECWD, /* one CWD to full dir, then work on file */
+ CURLFTPMETHOD_LAST /* not an option, never use */
+} curl_ftpmethod;
+
+/* bitmask defines for CURLOPT_HEADEROPT */
+#define CURLHEADER_UNIFIED 0
+#define CURLHEADER_SEPARATE (1<<0)
+
+/* CURLALTSVC_* are bits for the CURLOPT_ALTSVC_CTRL option */
+#define CURLALTSVC_READONLYFILE (1<<2)
+#define CURLALTSVC_H1 (1<<3)
+#define CURLALTSVC_H2 (1<<4)
+#define CURLALTSVC_H3 (1<<5)
+
+
+struct curl_hstsentry {
+ char *name;
+ size_t namelen;
+ unsigned int includeSubDomains:1;
+ char expire[18]; /* YYYYMMDD HH:MM:SS [null-terminated] */
+};
+
+struct curl_index {
+ size_t index; /* the provided entry's "index" or count */
+ size_t total; /* total number of entries to save */
+};
+
+typedef enum {
+ CURLSTS_OK,
+ CURLSTS_DONE,
+ CURLSTS_FAIL
+} CURLSTScode;
+
+typedef CURLSTScode (*curl_hstsread_callback)(CURL *easy,
+ struct curl_hstsentry *e,
+ void *userp);
+typedef CURLSTScode (*curl_hstswrite_callback)(CURL *easy,
+ struct curl_hstsentry *e,
+ struct curl_index *i,
+ void *userp);
+
+/* CURLHSTS_* are bits for the CURLOPT_HSTS option */
+#define CURLHSTS_ENABLE (long)(1<<0)
+#define CURLHSTS_READONLYFILE (long)(1<<1)
+
+/* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */
+#define CURLPROTO_HTTP (1<<0)
+#define CURLPROTO_HTTPS (1<<1)
+#define CURLPROTO_FTP (1<<2)
+#define CURLPROTO_FTPS (1<<3)
+#define CURLPROTO_SCP (1<<4)
+#define CURLPROTO_SFTP (1<<5)
+#define CURLPROTO_TELNET (1<<6)
+#define CURLPROTO_LDAP (1<<7)
+#define CURLPROTO_LDAPS (1<<8)
+#define CURLPROTO_DICT (1<<9)
+#define CURLPROTO_FILE (1<<10)
+#define CURLPROTO_TFTP (1<<11)
+#define CURLPROTO_IMAP (1<<12)
+#define CURLPROTO_IMAPS (1<<13)
+#define CURLPROTO_POP3 (1<<14)
+#define CURLPROTO_POP3S (1<<15)
+#define CURLPROTO_SMTP (1<<16)
+#define CURLPROTO_SMTPS (1<<17)
+#define CURLPROTO_RTSP (1<<18)
+#define CURLPROTO_RTMP (1<<19)
+#define CURLPROTO_RTMPT (1<<20)
+#define CURLPROTO_RTMPE (1<<21)
+#define CURLPROTO_RTMPTE (1<<22)
+#define CURLPROTO_RTMPS (1<<23)
+#define CURLPROTO_RTMPTS (1<<24)
+#define CURLPROTO_GOPHER (1<<25)
+#define CURLPROTO_SMB (1<<26)
+#define CURLPROTO_SMBS (1<<27)
+#define CURLPROTO_MQTT (1<<28)
+#define CURLPROTO_GOPHERS (1<<29)
+#define CURLPROTO_ALL (~0) /* enable everything */
+
+/* long may be 32 or 64 bits, but we should never depend on anything else
+ but 32 */
+#define CURLOPTTYPE_LONG 0
+#define CURLOPTTYPE_OBJECTPOINT 10000
+#define CURLOPTTYPE_FUNCTIONPOINT 20000
+#define CURLOPTTYPE_OFF_T 30000
+#define CURLOPTTYPE_BLOB 40000
+
+/* *STRINGPOINT is an alias for OBJECTPOINT to allow tools to extract the
+ string options from the header file */
+
+
+#define CURLOPT(na,t,nu) na = t + nu
+
+/* CURLOPT aliases that make no run-time difference */
+
+/* 'char *' argument to a string with a trailing zero */
+#define CURLOPTTYPE_STRINGPOINT CURLOPTTYPE_OBJECTPOINT
+
+/* 'struct curl_slist *' argument */
+#define CURLOPTTYPE_SLISTPOINT CURLOPTTYPE_OBJECTPOINT
+
+/* 'void *' argument passed untouched to callback */
+#define CURLOPTTYPE_CBPOINT CURLOPTTYPE_OBJECTPOINT
+
+/* 'long' argument with a set of values/bitmask */
+#define CURLOPTTYPE_VALUES CURLOPTTYPE_LONG
+
+/*
+ * All CURLOPT_* values.
+ */
+
+typedef enum {
+ /* This is the FILE * or void * the regular output should be written to. */
+ CURLOPT(CURLOPT_WRITEDATA, CURLOPTTYPE_CBPOINT, 1),
+
+ /* The full URL to get/put */
+ CURLOPT(CURLOPT_URL, CURLOPTTYPE_STRINGPOINT, 2),
+
+ /* Port number to connect to, if other than default. */
+ CURLOPT(CURLOPT_PORT, CURLOPTTYPE_LONG, 3),
+
+ /* Name of proxy to use. */
+ CURLOPT(CURLOPT_PROXY, CURLOPTTYPE_STRINGPOINT, 4),
+
+ /* "user:password;options" to use when fetching. */
+ CURLOPT(CURLOPT_USERPWD, CURLOPTTYPE_STRINGPOINT, 5),
+
+ /* "user:password" to use with proxy. */
+ CURLOPT(CURLOPT_PROXYUSERPWD, CURLOPTTYPE_STRINGPOINT, 6),
+
+ /* Range to get, specified as an ASCII string. */
+ CURLOPT(CURLOPT_RANGE, CURLOPTTYPE_STRINGPOINT, 7),
+
+ /* not used */
+
+ /* Specified file stream to upload from (use as input): */
+ CURLOPT(CURLOPT_READDATA, CURLOPTTYPE_CBPOINT, 9),
+
+ /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE
+ * bytes big. */
+ CURLOPT(CURLOPT_ERRORBUFFER, CURLOPTTYPE_OBJECTPOINT, 10),
+
+ /* Function that will be called to store the output (instead of fwrite). The
+ * parameters will use fwrite() syntax, make sure to follow them. */
+ CURLOPT(CURLOPT_WRITEFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 11),
+
+ /* Function that will be called to read the input (instead of fread). The
+ * parameters will use fread() syntax, make sure to follow them. */
+ CURLOPT(CURLOPT_READFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 12),
+
+ /* Time-out the read operation after this amount of seconds */
+ CURLOPT(CURLOPT_TIMEOUT, CURLOPTTYPE_LONG, 13),
+
+ /* If the CURLOPT_INFILE is used, this can be used to inform libcurl about
+ * how large the file being sent really is. That allows better error
+ * checking and better verifies that the upload was successful. -1 means
+ * unknown size.
+ *
+ * For large file support, there is also a _LARGE version of the key
+ * which takes an off_t type, allowing platforms with larger off_t
+ * sizes to handle larger files. See below for INFILESIZE_LARGE.
+ */
+ CURLOPT(CURLOPT_INFILESIZE, CURLOPTTYPE_LONG, 14),
+
+ /* POST static input fields. */
+ CURLOPT(CURLOPT_POSTFIELDS, CURLOPTTYPE_OBJECTPOINT, 15),
+
+ /* Set the referrer page (needed by some CGIs) */
+ CURLOPT(CURLOPT_REFERER, CURLOPTTYPE_STRINGPOINT, 16),
+
+ /* Set the FTP PORT string (interface name, named or numerical IP address)
+ Use i.e '-' to use default address. */
+ CURLOPT(CURLOPT_FTPPORT, CURLOPTTYPE_STRINGPOINT, 17),
+
+ /* Set the User-Agent string (examined by some CGIs) */
+ CURLOPT(CURLOPT_USERAGENT, CURLOPTTYPE_STRINGPOINT, 18),
+
+ /* If the download receives less than "low speed limit" bytes/second
+ * during "low speed time" seconds, the operations is aborted.
+ * You could i.e if you have a pretty high speed connection, abort if
+ * it is less than 2000 bytes/sec during 20 seconds.
+ */
+
+ /* Set the "low speed limit" */
+ CURLOPT(CURLOPT_LOW_SPEED_LIMIT, CURLOPTTYPE_LONG, 19),
+
+ /* Set the "low speed time" */
+ CURLOPT(CURLOPT_LOW_SPEED_TIME, CURLOPTTYPE_LONG, 20),
+
+ /* Set the continuation offset.
+ *
+ * Note there is also a _LARGE version of this key which uses
+ * off_t types, allowing for large file offsets on platforms which
+ * use larger-than-32-bit off_t's. Look below for RESUME_FROM_LARGE.
+ */
+ CURLOPT(CURLOPT_RESUME_FROM, CURLOPTTYPE_LONG, 21),
+
+ /* Set cookie in request: */
+ CURLOPT(CURLOPT_COOKIE, CURLOPTTYPE_STRINGPOINT, 22),
+
+ /* This points to a linked list of headers, struct curl_slist kind. This
+ list is also used for RTSP (in spite of its name) */
+ CURLOPT(CURLOPT_HTTPHEADER, CURLOPTTYPE_SLISTPOINT, 23),
+
+ /* This points to a linked list of post entries, struct curl_httppost */
+ CURLOPT(CURLOPT_HTTPPOST, CURLOPTTYPE_OBJECTPOINT, 24),
+
+ /* name of the file keeping your private SSL-certificate */
+ CURLOPT(CURLOPT_SSLCERT, CURLOPTTYPE_STRINGPOINT, 25),
+
+ /* password for the SSL or SSH private key */
+ CURLOPT(CURLOPT_KEYPASSWD, CURLOPTTYPE_STRINGPOINT, 26),
+
+ /* send TYPE parameter? */
+ CURLOPT(CURLOPT_CRLF, CURLOPTTYPE_LONG, 27),
+
+ /* send linked-list of QUOTE commands */
+ CURLOPT(CURLOPT_QUOTE, CURLOPTTYPE_SLISTPOINT, 28),
+
+ /* send FILE * or void * to store headers to, if you use a callback it
+ is simply passed to the callback unmodified */
+ CURLOPT(CURLOPT_HEADERDATA, CURLOPTTYPE_CBPOINT, 29),
+
+ /* point to a file to read the initial cookies from, also enables
+ "cookie awareness" */
+ CURLOPT(CURLOPT_COOKIEFILE, CURLOPTTYPE_STRINGPOINT, 31),
+
+ /* What version to specifically try to use.
+ See CURL_SSLVERSION defines below. */
+ CURLOPT(CURLOPT_SSLVERSION, CURLOPTTYPE_VALUES, 32),
+
+ /* What kind of HTTP time condition to use, see defines */
+ CURLOPT(CURLOPT_TIMECONDITION, CURLOPTTYPE_VALUES, 33),
+
+ /* Time to use with the above condition. Specified in number of seconds
+ since 1 Jan 1970 */
+ CURLOPT(CURLOPT_TIMEVALUE, CURLOPTTYPE_LONG, 34),
+
+ /* 35 = OBSOLETE */
+
+ /* Custom request, for customizing the get command like
+ HTTP: DELETE, TRACE and others
+ FTP: to use a different list command
+ */
+ CURLOPT(CURLOPT_CUSTOMREQUEST, CURLOPTTYPE_STRINGPOINT, 36),
+
+ /* FILE handle to use instead of stderr */
+ CURLOPT(CURLOPT_STDERR, CURLOPTTYPE_OBJECTPOINT, 37),
+
+ /* 38 is not used */
+
+ /* send linked-list of post-transfer QUOTE commands */
+ CURLOPT(CURLOPT_POSTQUOTE, CURLOPTTYPE_SLISTPOINT, 39),
+
+ /* OBSOLETE, do not use! */
+ CURLOPT(CURLOPT_OBSOLETE40, CURLOPTTYPE_OBJECTPOINT, 40),
+
+ /* talk a lot */
+ CURLOPT(CURLOPT_VERBOSE, CURLOPTTYPE_LONG, 41),
+
+ /* throw the header out too */
+ CURLOPT(CURLOPT_HEADER, CURLOPTTYPE_LONG, 42),
+
+ /* shut off the progress meter */
+ CURLOPT(CURLOPT_NOPROGRESS, CURLOPTTYPE_LONG, 43),
+
+ /* use HEAD to get http document */
+ CURLOPT(CURLOPT_NOBODY, CURLOPTTYPE_LONG, 44),
+
+ /* no output on http error codes >= 400 */
+ CURLOPT(CURLOPT_FAILONERROR, CURLOPTTYPE_LONG, 45),
+
+ /* this is an upload */
+ CURLOPT(CURLOPT_UPLOAD, CURLOPTTYPE_LONG, 46),
+
+ /* HTTP POST method */
+ CURLOPT(CURLOPT_POST, CURLOPTTYPE_LONG, 47),
+
+ /* bare names when listing directories */
+ CURLOPT(CURLOPT_DIRLISTONLY, CURLOPTTYPE_LONG, 48),
+
+ /* Append instead of overwrite on upload! */
+ CURLOPT(CURLOPT_APPEND, CURLOPTTYPE_LONG, 50),
+
+ /* Specify whether to read the user+password from the .netrc or the URL.
+ * This must be one of the CURL_NETRC_* enums below. */
+ CURLOPT(CURLOPT_NETRC, CURLOPTTYPE_VALUES, 51),
+
+ /* use Location: Luke! */
+ CURLOPT(CURLOPT_FOLLOWLOCATION, CURLOPTTYPE_LONG, 52),
+
+ /* transfer data in text/ASCII format */
+ CURLOPT(CURLOPT_TRANSFERTEXT, CURLOPTTYPE_LONG, 53),
+
+ /* HTTP PUT */
+ CURLOPT(CURLOPT_PUT, CURLOPTTYPE_LONG, 54),
+
+ /* 55 = OBSOLETE */
+
+ /* DEPRECATED
+ * Function that will be called instead of the internal progress display
+ * function. This function should be defined as the curl_progress_callback
+ * prototype defines. */
+ CURLOPT(CURLOPT_PROGRESSFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 56),
+
+ /* Data passed to the CURLOPT_PROGRESSFUNCTION and CURLOPT_XFERINFOFUNCTION
+ callbacks */
+ CURLOPT(CURLOPT_XFERINFODATA, CURLOPTTYPE_CBPOINT, 57),
+#define CURLOPT_PROGRESSDATA CURLOPT_XFERINFODATA
+
+ /* We want the referrer field set automatically when following locations */
+ CURLOPT(CURLOPT_AUTOREFERER, CURLOPTTYPE_LONG, 58),
+
+ /* Port of the proxy, can be set in the proxy string as well with:
+ "[host]:[port]" */
+ CURLOPT(CURLOPT_PROXYPORT, CURLOPTTYPE_LONG, 59),
+
+ /* size of the POST input data, if strlen() is not good to use */
+ CURLOPT(CURLOPT_POSTFIELDSIZE, CURLOPTTYPE_LONG, 60),
+
+ /* tunnel non-http operations through a HTTP proxy */
+ CURLOPT(CURLOPT_HTTPPROXYTUNNEL, CURLOPTTYPE_LONG, 61),
+
+ /* Set the interface string to use as outgoing network interface */
+ CURLOPT(CURLOPT_INTERFACE, CURLOPTTYPE_STRINGPOINT, 62),
+
+ /* Set the krb4/5 security level, this also enables krb4/5 awareness. This
+ * is a string, 'clear', 'safe', 'confidential' or 'private'. If the string
+ * is set but doesn't match one of these, 'private' will be used. */
+ CURLOPT(CURLOPT_KRBLEVEL, CURLOPTTYPE_STRINGPOINT, 63),
+
+ /* Set if we should verify the peer in ssl handshake, set 1 to verify. */
+ CURLOPT(CURLOPT_SSL_VERIFYPEER, CURLOPTTYPE_LONG, 64),
+
+ /* The CApath or CAfile used to validate the peer certificate
+ this option is used only if SSL_VERIFYPEER is true */
+ CURLOPT(CURLOPT_CAINFO, CURLOPTTYPE_STRINGPOINT, 65),
+
+ /* 66 = OBSOLETE */
+ /* 67 = OBSOLETE */
+
+ /* Maximum number of http redirects to follow */
+ CURLOPT(CURLOPT_MAXREDIRS, CURLOPTTYPE_LONG, 68),
+
+ /* Pass a long set to 1 to get the date of the requested document (if
+ possible)! Pass a zero to shut it off. */
+ CURLOPT(CURLOPT_FILETIME, CURLOPTTYPE_LONG, 69),
+
+ /* This points to a linked list of telnet options */
+ CURLOPT(CURLOPT_TELNETOPTIONS, CURLOPTTYPE_SLISTPOINT, 70),
+
+ /* Max amount of cached alive connections */
+ CURLOPT(CURLOPT_MAXCONNECTS, CURLOPTTYPE_LONG, 71),
+
+ /* OBSOLETE, do not use! */
+ CURLOPT(CURLOPT_OBSOLETE72, CURLOPTTYPE_LONG, 72),
+
+ /* 73 = OBSOLETE */
+
+ /* Set to explicitly use a new connection for the upcoming transfer.
+ Do not use this unless you're absolutely sure of this, as it makes the
+ operation slower and is less friendly for the network. */
+ CURLOPT(CURLOPT_FRESH_CONNECT, CURLOPTTYPE_LONG, 74),
+
+ /* Set to explicitly forbid the upcoming transfer's connection to be re-used
+ when done. Do not use this unless you're absolutely sure of this, as it
+ makes the operation slower and is less friendly for the network. */
+ CURLOPT(CURLOPT_FORBID_REUSE, CURLOPTTYPE_LONG, 75),
+
+ /* Set to a file name that contains random data for libcurl to use to
+ seed the random engine when doing SSL connects. */
+ CURLOPT(CURLOPT_RANDOM_FILE, CURLOPTTYPE_STRINGPOINT, 76),
+
+ /* Set to the Entropy Gathering Daemon socket pathname */
+ CURLOPT(CURLOPT_EGDSOCKET, CURLOPTTYPE_STRINGPOINT, 77),
+
+ /* Time-out connect operations after this amount of seconds, if connects are
+ OK within this time, then fine... This only aborts the connect phase. */
+ CURLOPT(CURLOPT_CONNECTTIMEOUT, CURLOPTTYPE_LONG, 78),
+
+ /* Function that will be called to store headers (instead of fwrite). The
+ * parameters will use fwrite() syntax, make sure to follow them. */
+ CURLOPT(CURLOPT_HEADERFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 79),
+
+ /* Set this to force the HTTP request to get back to GET. Only really usable
+ if POST, PUT or a custom request have been used first.
+ */
+ CURLOPT(CURLOPT_HTTPGET, CURLOPTTYPE_LONG, 80),
+
+ /* Set if we should verify the Common name from the peer certificate in ssl
+ * handshake, set 1 to check existence, 2 to ensure that it matches the
+ * provided hostname. */
+ CURLOPT(CURLOPT_SSL_VERIFYHOST, CURLOPTTYPE_LONG, 81),
+
+ /* Specify which file name to write all known cookies in after completed
+ operation. Set file name to "-" (dash) to make it go to stdout. */
+ CURLOPT(CURLOPT_COOKIEJAR, CURLOPTTYPE_STRINGPOINT, 82),
+
+ /* Specify which SSL ciphers to use */
+ CURLOPT(CURLOPT_SSL_CIPHER_LIST, CURLOPTTYPE_STRINGPOINT, 83),
+
+ /* Specify which HTTP version to use! This must be set to one of the
+ CURL_HTTP_VERSION* enums set below. */
+ CURLOPT(CURLOPT_HTTP_VERSION, CURLOPTTYPE_VALUES, 84),
+
+ /* Specifically switch on or off the FTP engine's use of the EPSV command. By
+ default, that one will always be attempted before the more traditional
+ PASV command. */
+ CURLOPT(CURLOPT_FTP_USE_EPSV, CURLOPTTYPE_LONG, 85),
+
+ /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") */
+ CURLOPT(CURLOPT_SSLCERTTYPE, CURLOPTTYPE_STRINGPOINT, 86),
+
+ /* name of the file keeping your private SSL-key */
+ CURLOPT(CURLOPT_SSLKEY, CURLOPTTYPE_STRINGPOINT, 87),
+
+ /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") */
+ CURLOPT(CURLOPT_SSLKEYTYPE, CURLOPTTYPE_STRINGPOINT, 88),
+
+ /* crypto engine for the SSL-sub system */
+ CURLOPT(CURLOPT_SSLENGINE, CURLOPTTYPE_STRINGPOINT, 89),
+
+ /* set the crypto engine for the SSL-sub system as default
+ the param has no meaning...
+ */
+ CURLOPT(CURLOPT_SSLENGINE_DEFAULT, CURLOPTTYPE_LONG, 90),
+
+ /* Non-zero value means to use the global dns cache */
+ /* DEPRECATED, do not use! */
+ CURLOPT(CURLOPT_DNS_USE_GLOBAL_CACHE, CURLOPTTYPE_LONG, 91),
+
+ /* DNS cache timeout */
+ CURLOPT(CURLOPT_DNS_CACHE_TIMEOUT, CURLOPTTYPE_LONG, 92),
+
+ /* send linked-list of pre-transfer QUOTE commands */
+ CURLOPT(CURLOPT_PREQUOTE, CURLOPTTYPE_SLISTPOINT, 93),
+
+ /* set the debug function */
+ CURLOPT(CURLOPT_DEBUGFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 94),
+
+ /* set the data for the debug function */
+ CURLOPT(CURLOPT_DEBUGDATA, CURLOPTTYPE_CBPOINT, 95),
+
+ /* mark this as start of a cookie session */
+ CURLOPT(CURLOPT_COOKIESESSION, CURLOPTTYPE_LONG, 96),
+
+ /* The CApath directory used to validate the peer certificate
+ this option is used only if SSL_VERIFYPEER is true */
+ CURLOPT(CURLOPT_CAPATH, CURLOPTTYPE_STRINGPOINT, 97),
+
+ /* Instruct libcurl to use a smaller receive buffer */
+ CURLOPT(CURLOPT_BUFFERSIZE, CURLOPTTYPE_LONG, 98),
+
+ /* Instruct libcurl to not use any signal/alarm handlers, even when using
+ timeouts. This option is useful for multi-threaded applications.
+ See libcurl-the-guide for more background information. */
+ CURLOPT(CURLOPT_NOSIGNAL, CURLOPTTYPE_LONG, 99),
+
+ /* Provide a CURLShare for mutexing non-ts data */
+ CURLOPT(CURLOPT_SHARE, CURLOPTTYPE_OBJECTPOINT, 100),
+
+ /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default),
+ CURLPROXY_HTTPS, CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and
+ CURLPROXY_SOCKS5. */
+ CURLOPT(CURLOPT_PROXYTYPE, CURLOPTTYPE_VALUES, 101),
+
+ /* Set the Accept-Encoding string. Use this to tell a server you would like
+ the response to be compressed. Before 7.21.6, this was known as
+ CURLOPT_ENCODING */
+ CURLOPT(CURLOPT_ACCEPT_ENCODING, CURLOPTTYPE_STRINGPOINT, 102),
+
+ /* Set pointer to private data */
+ CURLOPT(CURLOPT_PRIVATE, CURLOPTTYPE_OBJECTPOINT, 103),
+
+ /* Set aliases for HTTP 200 in the HTTP Response header */
+ CURLOPT(CURLOPT_HTTP200ALIASES, CURLOPTTYPE_SLISTPOINT, 104),
+
+ /* Continue to send authentication (user+password) when following locations,
+ even when hostname changed. This can potentially send off the name
+ and password to whatever host the server decides. */
+ CURLOPT(CURLOPT_UNRESTRICTED_AUTH, CURLOPTTYPE_LONG, 105),
+
+ /* Specifically switch on or off the FTP engine's use of the EPRT command (
+ it also disables the LPRT attempt). By default, those ones will always be
+ attempted before the good old traditional PORT command. */
+ CURLOPT(CURLOPT_FTP_USE_EPRT, CURLOPTTYPE_LONG, 106),
+
+ /* Set this to a bitmask value to enable the particular authentications
+ methods you like. Use this in combination with CURLOPT_USERPWD.
+ Note that setting multiple bits may cause extra network round-trips. */
+ CURLOPT(CURLOPT_HTTPAUTH, CURLOPTTYPE_VALUES, 107),
+
+ /* Set the ssl context callback function, currently only for OpenSSL or
+ WolfSSL ssl_ctx, or mbedTLS mbedtls_ssl_config in the second argument.
+ The function must match the curl_ssl_ctx_callback prototype. */
+ CURLOPT(CURLOPT_SSL_CTX_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 108),
+
+ /* Set the userdata for the ssl context callback function's third
+ argument */
+ CURLOPT(CURLOPT_SSL_CTX_DATA, CURLOPTTYPE_CBPOINT, 109),
+
+ /* FTP Option that causes missing dirs to be created on the remote server.
+ In 7.19.4 we introduced the convenience enums for this option using the
+ CURLFTP_CREATE_DIR prefix.
+ */
+ CURLOPT(CURLOPT_FTP_CREATE_MISSING_DIRS, CURLOPTTYPE_LONG, 110),
+
+ /* Set this to a bitmask value to enable the particular authentications
+ methods you like. Use this in combination with CURLOPT_PROXYUSERPWD.
+ Note that setting multiple bits may cause extra network round-trips. */
+ CURLOPT(CURLOPT_PROXYAUTH, CURLOPTTYPE_VALUES, 111),
+
+ /* FTP option that changes the timeout, in seconds, associated with
+ getting a response. This is different from transfer timeout time and
+ essentially places a demand on the FTP server to acknowledge commands
+ in a timely manner. */
+ CURLOPT(CURLOPT_FTP_RESPONSE_TIMEOUT, CURLOPTTYPE_LONG, 112),
+#define CURLOPT_SERVER_RESPONSE_TIMEOUT CURLOPT_FTP_RESPONSE_TIMEOUT
+
+ /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to
+ tell libcurl to resolve names to those IP versions only. This only has
+ affect on systems with support for more than one, i.e IPv4 _and_ IPv6. */
+ CURLOPT(CURLOPT_IPRESOLVE, CURLOPTTYPE_VALUES, 113),
+
+ /* Set this option to limit the size of a file that will be downloaded from
+ an HTTP or FTP server.
+
+ Note there is also _LARGE version which adds large file support for
+ platforms which have larger off_t sizes. See MAXFILESIZE_LARGE below. */
+ CURLOPT(CURLOPT_MAXFILESIZE, CURLOPTTYPE_LONG, 114),
+
+ /* See the comment for INFILESIZE above, but in short, specifies
+ * the size of the file being uploaded. -1 means unknown.
+ */
+ CURLOPT(CURLOPT_INFILESIZE_LARGE, CURLOPTTYPE_OFF_T, 115),
+
+ /* Sets the continuation offset. There is also a CURLOPTTYPE_LONG version
+ * of this; look above for RESUME_FROM.
+ */
+ CURLOPT(CURLOPT_RESUME_FROM_LARGE, CURLOPTTYPE_OFF_T, 116),
+
+ /* Sets the maximum size of data that will be downloaded from
+ * an HTTP or FTP server. See MAXFILESIZE above for the LONG version.
+ */
+ CURLOPT(CURLOPT_MAXFILESIZE_LARGE, CURLOPTTYPE_OFF_T, 117),
+
+ /* Set this option to the file name of your .netrc file you want libcurl
+ to parse (using the CURLOPT_NETRC option). If not set, libcurl will do
+ a poor attempt to find the user's home directory and check for a .netrc
+ file in there. */
+ CURLOPT(CURLOPT_NETRC_FILE, CURLOPTTYPE_STRINGPOINT, 118),
+
+ /* Enable SSL/TLS for FTP, pick one of:
+ CURLUSESSL_TRY - try using SSL, proceed anyway otherwise
+ CURLUSESSL_CONTROL - SSL for the control connection or fail
+ CURLUSESSL_ALL - SSL for all communication or fail
+ */
+ CURLOPT(CURLOPT_USE_SSL, CURLOPTTYPE_VALUES, 119),
+
+ /* The _LARGE version of the standard POSTFIELDSIZE option */
+ CURLOPT(CURLOPT_POSTFIELDSIZE_LARGE, CURLOPTTYPE_OFF_T, 120),
+
+ /* Enable/disable the TCP Nagle algorithm */
+ CURLOPT(CURLOPT_TCP_NODELAY, CURLOPTTYPE_LONG, 121),
+
+ /* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
+ /* 123 OBSOLETE. Gone in 7.16.0 */
+ /* 124 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
+ /* 125 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
+ /* 126 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
+ /* 127 OBSOLETE. Gone in 7.16.0 */
+ /* 128 OBSOLETE. Gone in 7.16.0 */
+
+ /* When FTP over SSL/TLS is selected (with CURLOPT_USE_SSL), this option
+ can be used to change libcurl's default action which is to first try
+ "AUTH SSL" and then "AUTH TLS" in this order, and proceed when a OK
+ response has been received.
+
+ Available parameters are:
+ CURLFTPAUTH_DEFAULT - let libcurl decide
+ CURLFTPAUTH_SSL - try "AUTH SSL" first, then TLS
+ CURLFTPAUTH_TLS - try "AUTH TLS" first, then SSL
+ */
+ CURLOPT(CURLOPT_FTPSSLAUTH, CURLOPTTYPE_VALUES, 129),
+
+ CURLOPT(CURLOPT_IOCTLFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 130),
+ CURLOPT(CURLOPT_IOCTLDATA, CURLOPTTYPE_CBPOINT, 131),
+
+ /* 132 OBSOLETE. Gone in 7.16.0 */
+ /* 133 OBSOLETE. Gone in 7.16.0 */
+
+ /* null-terminated string for pass on to the FTP server when asked for
+ "account" info */
+ CURLOPT(CURLOPT_FTP_ACCOUNT, CURLOPTTYPE_STRINGPOINT, 134),
+
+ /* feed cookie into cookie engine */
+ CURLOPT(CURLOPT_COOKIELIST, CURLOPTTYPE_STRINGPOINT, 135),
+
+ /* ignore Content-Length */
+ CURLOPT(CURLOPT_IGNORE_CONTENT_LENGTH, CURLOPTTYPE_LONG, 136),
+
+ /* Set to non-zero to skip the IP address received in a 227 PASV FTP server
+ response. Typically used for FTP-SSL purposes but is not restricted to
+ that. libcurl will then instead use the same IP address it used for the
+ control connection. */
+ CURLOPT(CURLOPT_FTP_SKIP_PASV_IP, CURLOPTTYPE_LONG, 137),
+
+ /* Select "file method" to use when doing FTP, see the curl_ftpmethod
+ above. */
+ CURLOPT(CURLOPT_FTP_FILEMETHOD, CURLOPTTYPE_VALUES, 138),
+
+ /* Local port number to bind the socket to */
+ CURLOPT(CURLOPT_LOCALPORT, CURLOPTTYPE_LONG, 139),
+
+ /* Number of ports to try, including the first one set with LOCALPORT.
+ Thus, setting it to 1 will make no additional attempts but the first.
+ */
+ CURLOPT(CURLOPT_LOCALPORTRANGE, CURLOPTTYPE_LONG, 140),
+
+ /* no transfer, set up connection and let application use the socket by
+ extracting it with CURLINFO_LASTSOCKET */
+ CURLOPT(CURLOPT_CONNECT_ONLY, CURLOPTTYPE_LONG, 141),
+
+ /* Function that will be called to convert from the
+ network encoding (instead of using the iconv calls in libcurl) */
+ CURLOPT(CURLOPT_CONV_FROM_NETWORK_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 142),
+
+ /* Function that will be called to convert to the
+ network encoding (instead of using the iconv calls in libcurl) */
+ CURLOPT(CURLOPT_CONV_TO_NETWORK_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 143),
+
+ /* Function that will be called to convert from UTF8
+ (instead of using the iconv calls in libcurl)
+ Note that this is used only for SSL certificate processing */
+ CURLOPT(CURLOPT_CONV_FROM_UTF8_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 144),
+
+ /* if the connection proceeds too quickly then need to slow it down */
+ /* limit-rate: maximum number of bytes per second to send or receive */
+ CURLOPT(CURLOPT_MAX_SEND_SPEED_LARGE, CURLOPTTYPE_OFF_T, 145),
+ CURLOPT(CURLOPT_MAX_RECV_SPEED_LARGE, CURLOPTTYPE_OFF_T, 146),
+
+ /* Pointer to command string to send if USER/PASS fails. */
+ CURLOPT(CURLOPT_FTP_ALTERNATIVE_TO_USER, CURLOPTTYPE_STRINGPOINT, 147),
+
+ /* callback function for setting socket options */
+ CURLOPT(CURLOPT_SOCKOPTFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 148),
+ CURLOPT(CURLOPT_SOCKOPTDATA, CURLOPTTYPE_CBPOINT, 149),
+
+ /* set to 0 to disable session ID re-use for this transfer, default is
+ enabled (== 1) */
+ CURLOPT(CURLOPT_SSL_SESSIONID_CACHE, CURLOPTTYPE_LONG, 150),
+
+ /* allowed SSH authentication methods */
+ CURLOPT(CURLOPT_SSH_AUTH_TYPES, CURLOPTTYPE_VALUES, 151),
+
+ /* Used by scp/sftp to do public/private key authentication */
+ CURLOPT(CURLOPT_SSH_PUBLIC_KEYFILE, CURLOPTTYPE_STRINGPOINT, 152),
+ CURLOPT(CURLOPT_SSH_PRIVATE_KEYFILE, CURLOPTTYPE_STRINGPOINT, 153),
+
+ /* Send CCC (Clear Command Channel) after authentication */
+ CURLOPT(CURLOPT_FTP_SSL_CCC, CURLOPTTYPE_LONG, 154),
+
+ /* Same as TIMEOUT and CONNECTTIMEOUT, but with ms resolution */
+ CURLOPT(CURLOPT_TIMEOUT_MS, CURLOPTTYPE_LONG, 155),
+ CURLOPT(CURLOPT_CONNECTTIMEOUT_MS, CURLOPTTYPE_LONG, 156),
+
+ /* set to zero to disable the libcurl's decoding and thus pass the raw body
+ data to the application even when it is encoded/compressed */
+ CURLOPT(CURLOPT_HTTP_TRANSFER_DECODING, CURLOPTTYPE_LONG, 157),
+ CURLOPT(CURLOPT_HTTP_CONTENT_DECODING, CURLOPTTYPE_LONG, 158),
+
+ /* Permission used when creating new files and directories on the remote
+ server for protocols that support it, SFTP/SCP/FILE */
+ CURLOPT(CURLOPT_NEW_FILE_PERMS, CURLOPTTYPE_LONG, 159),
+ CURLOPT(CURLOPT_NEW_DIRECTORY_PERMS, CURLOPTTYPE_LONG, 160),
+
+ /* Set the behavior of POST when redirecting. Values must be set to one
+ of CURL_REDIR* defines below. This used to be called CURLOPT_POST301 */
+ CURLOPT(CURLOPT_POSTREDIR, CURLOPTTYPE_VALUES, 161),
+
+ /* used by scp/sftp to verify the host's public key */
+ CURLOPT(CURLOPT_SSH_HOST_PUBLIC_KEY_MD5, CURLOPTTYPE_STRINGPOINT, 162),
+
+ /* Callback function for opening socket (instead of socket(2)). Optionally,
+ callback is able change the address or refuse to connect returning
+ CURL_SOCKET_BAD. The callback should have type
+ curl_opensocket_callback */
+ CURLOPT(CURLOPT_OPENSOCKETFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 163),
+ CURLOPT(CURLOPT_OPENSOCKETDATA, CURLOPTTYPE_CBPOINT, 164),
+
+ /* POST volatile input fields. */
+ CURLOPT(CURLOPT_COPYPOSTFIELDS, CURLOPTTYPE_OBJECTPOINT, 165),
+
+ /* set transfer mode (;type=) when doing FTP via an HTTP proxy */
+ CURLOPT(CURLOPT_PROXY_TRANSFER_MODE, CURLOPTTYPE_LONG, 166),
+
+ /* Callback function for seeking in the input stream */
+ CURLOPT(CURLOPT_SEEKFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 167),
+ CURLOPT(CURLOPT_SEEKDATA, CURLOPTTYPE_CBPOINT, 168),
+
+ /* CRL file */
+ CURLOPT(CURLOPT_CRLFILE, CURLOPTTYPE_STRINGPOINT, 169),
+
+ /* Issuer certificate */
+ CURLOPT(CURLOPT_ISSUERCERT, CURLOPTTYPE_STRINGPOINT, 170),
+
+ /* (IPv6) Address scope */
+ CURLOPT(CURLOPT_ADDRESS_SCOPE, CURLOPTTYPE_LONG, 171),
+
+ /* Collect certificate chain info and allow it to get retrievable with
+ CURLINFO_CERTINFO after the transfer is complete. */
+ CURLOPT(CURLOPT_CERTINFO, CURLOPTTYPE_LONG, 172),
+
+ /* "name" and "pwd" to use when fetching. */
+ CURLOPT(CURLOPT_USERNAME, CURLOPTTYPE_STRINGPOINT, 173),
+ CURLOPT(CURLOPT_PASSWORD, CURLOPTTYPE_STRINGPOINT, 174),
+
+ /* "name" and "pwd" to use with Proxy when fetching. */
+ CURLOPT(CURLOPT_PROXYUSERNAME, CURLOPTTYPE_STRINGPOINT, 175),
+ CURLOPT(CURLOPT_PROXYPASSWORD, CURLOPTTYPE_STRINGPOINT, 176),
+
+ /* Comma separated list of hostnames defining no-proxy zones. These should
+ match both hostnames directly, and hostnames within a domain. For
+ example, local.com will match local.com and www.local.com, but NOT
+ notlocal.com or www.notlocal.com. For compatibility with other
+ implementations of this, .local.com will be considered to be the same as
+ local.com. A single * is the only valid wildcard, and effectively
+ disables the use of proxy. */
+ CURLOPT(CURLOPT_NOPROXY, CURLOPTTYPE_STRINGPOINT, 177),
+
+ /* block size for TFTP transfers */
+ CURLOPT(CURLOPT_TFTP_BLKSIZE, CURLOPTTYPE_LONG, 178),
+
+ /* Socks Service */
+ /* DEPRECATED, do not use! */
+ CURLOPT(CURLOPT_SOCKS5_GSSAPI_SERVICE, CURLOPTTYPE_STRINGPOINT, 179),
+
+ /* Socks Service */
+ CURLOPT(CURLOPT_SOCKS5_GSSAPI_NEC, CURLOPTTYPE_LONG, 180),
+
+ /* set the bitmask for the protocols that are allowed to be used for the
+ transfer, which thus helps the app which takes URLs from users or other
+ external inputs and want to restrict what protocol(s) to deal
+ with. Defaults to CURLPROTO_ALL. */
+ CURLOPT(CURLOPT_PROTOCOLS, CURLOPTTYPE_LONG, 181),
+
+ /* set the bitmask for the protocols that libcurl is allowed to follow to,
+ as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
+ to be set in both bitmasks to be allowed to get redirected to. */
+ CURLOPT(CURLOPT_REDIR_PROTOCOLS, CURLOPTTYPE_LONG, 182),
+
+ /* set the SSH knownhost file name to use */
+ CURLOPT(CURLOPT_SSH_KNOWNHOSTS, CURLOPTTYPE_STRINGPOINT, 183),
+
+ /* set the SSH host key callback, must point to a curl_sshkeycallback
+ function */
+ CURLOPT(CURLOPT_SSH_KEYFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 184),
+
+ /* set the SSH host key callback custom pointer */
+ CURLOPT(CURLOPT_SSH_KEYDATA, CURLOPTTYPE_CBPOINT, 185),
+
+ /* set the SMTP mail originator */
+ CURLOPT(CURLOPT_MAIL_FROM, CURLOPTTYPE_STRINGPOINT, 186),
+
+ /* set the list of SMTP mail receiver(s) */
+ CURLOPT(CURLOPT_MAIL_RCPT, CURLOPTTYPE_SLISTPOINT, 187),
+
+ /* FTP: send PRET before PASV */
+ CURLOPT(CURLOPT_FTP_USE_PRET, CURLOPTTYPE_LONG, 188),
+
+ /* RTSP request method (OPTIONS, SETUP, PLAY, etc...) */
+ CURLOPT(CURLOPT_RTSP_REQUEST, CURLOPTTYPE_VALUES, 189),
+
+ /* The RTSP session identifier */
+ CURLOPT(CURLOPT_RTSP_SESSION_ID, CURLOPTTYPE_STRINGPOINT, 190),
+
+ /* The RTSP stream URI */
+ CURLOPT(CURLOPT_RTSP_STREAM_URI, CURLOPTTYPE_STRINGPOINT, 191),
+
+ /* The Transport: header to use in RTSP requests */
+ CURLOPT(CURLOPT_RTSP_TRANSPORT, CURLOPTTYPE_STRINGPOINT, 192),
+
+ /* Manually initialize the client RTSP CSeq for this handle */
+ CURLOPT(CURLOPT_RTSP_CLIENT_CSEQ, CURLOPTTYPE_LONG, 193),
+
+ /* Manually initialize the server RTSP CSeq for this handle */
+ CURLOPT(CURLOPT_RTSP_SERVER_CSEQ, CURLOPTTYPE_LONG, 194),
+
+ /* The stream to pass to INTERLEAVEFUNCTION. */
+ CURLOPT(CURLOPT_INTERLEAVEDATA, CURLOPTTYPE_CBPOINT, 195),
+
+ /* Let the application define a custom write method for RTP data */
+ CURLOPT(CURLOPT_INTERLEAVEFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 196),
+
+ /* Turn on wildcard matching */
+ CURLOPT(CURLOPT_WILDCARDMATCH, CURLOPTTYPE_LONG, 197),
+
+ /* Directory matching callback called before downloading of an
+ individual file (chunk) started */
+ CURLOPT(CURLOPT_CHUNK_BGN_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 198),
+
+ /* Directory matching callback called after the file (chunk)
+ was downloaded, or skipped */
+ CURLOPT(CURLOPT_CHUNK_END_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 199),
+
+ /* Change match (fnmatch-like) callback for wildcard matching */
+ CURLOPT(CURLOPT_FNMATCH_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 200),
+
+ /* Let the application define custom chunk data pointer */
+ CURLOPT(CURLOPT_CHUNK_DATA, CURLOPTTYPE_CBPOINT, 201),
+
+ /* FNMATCH_FUNCTION user pointer */
+ CURLOPT(CURLOPT_FNMATCH_DATA, CURLOPTTYPE_CBPOINT, 202),
+
+ /* send linked-list of name:port:address sets */
+ CURLOPT(CURLOPT_RESOLVE, CURLOPTTYPE_SLISTPOINT, 203),
+
+ /* Set a username for authenticated TLS */
+ CURLOPT(CURLOPT_TLSAUTH_USERNAME, CURLOPTTYPE_STRINGPOINT, 204),
+
+ /* Set a password for authenticated TLS */
+ CURLOPT(CURLOPT_TLSAUTH_PASSWORD, CURLOPTTYPE_STRINGPOINT, 205),
+
+ /* Set authentication type for authenticated TLS */
+ CURLOPT(CURLOPT_TLSAUTH_TYPE, CURLOPTTYPE_STRINGPOINT, 206),
+
+ /* Set to 1 to enable the "TE:" header in HTTP requests to ask for
+ compressed transfer-encoded responses. Set to 0 to disable the use of TE:
+ in outgoing requests. The current default is 0, but it might change in a
+ future libcurl release.
+
+ libcurl will ask for the compressed methods it knows of, and if that
+ isn't any, it will not ask for transfer-encoding at all even if this
+ option is set to 1.
+
+ */
+ CURLOPT(CURLOPT_TRANSFER_ENCODING, CURLOPTTYPE_LONG, 207),
+
+ /* Callback function for closing socket (instead of close(2)). The callback
+ should have type curl_closesocket_callback */
+ CURLOPT(CURLOPT_CLOSESOCKETFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 208),
+ CURLOPT(CURLOPT_CLOSESOCKETDATA, CURLOPTTYPE_CBPOINT, 209),
+
+ /* allow GSSAPI credential delegation */
+ CURLOPT(CURLOPT_GSSAPI_DELEGATION, CURLOPTTYPE_VALUES, 210),
+
+ /* Set the name servers to use for DNS resolution */
+ CURLOPT(CURLOPT_DNS_SERVERS, CURLOPTTYPE_STRINGPOINT, 211),
+
+ /* Time-out accept operations (currently for FTP only) after this amount
+ of milliseconds. */
+ CURLOPT(CURLOPT_ACCEPTTIMEOUT_MS, CURLOPTTYPE_LONG, 212),
+
+ /* Set TCP keepalive */
+ CURLOPT(CURLOPT_TCP_KEEPALIVE, CURLOPTTYPE_LONG, 213),
+
+ /* non-universal keepalive knobs (Linux, AIX, HP-UX, more) */
+ CURLOPT(CURLOPT_TCP_KEEPIDLE, CURLOPTTYPE_LONG, 214),
+ CURLOPT(CURLOPT_TCP_KEEPINTVL, CURLOPTTYPE_LONG, 215),
+
+ /* Enable/disable specific SSL features with a bitmask, see CURLSSLOPT_* */
+ CURLOPT(CURLOPT_SSL_OPTIONS, CURLOPTTYPE_VALUES, 216),
+
+ /* Set the SMTP auth originator */
+ CURLOPT(CURLOPT_MAIL_AUTH, CURLOPTTYPE_STRINGPOINT, 217),
+
+ /* Enable/disable SASL initial response */
+ CURLOPT(CURLOPT_SASL_IR, CURLOPTTYPE_LONG, 218),
+
+ /* Function that will be called instead of the internal progress display
+ * function. This function should be defined as the curl_xferinfo_callback
+ * prototype defines. (Deprecates CURLOPT_PROGRESSFUNCTION) */
+ CURLOPT(CURLOPT_XFERINFOFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 219),
+
+ /* The XOAUTH2 bearer token */
+ CURLOPT(CURLOPT_XOAUTH2_BEARER, CURLOPTTYPE_STRINGPOINT, 220),
+
+ /* Set the interface string to use as outgoing network
+ * interface for DNS requests.
+ * Only supported by the c-ares DNS backend */
+ CURLOPT(CURLOPT_DNS_INTERFACE, CURLOPTTYPE_STRINGPOINT, 221),
+
+ /* Set the local IPv4 address to use for outgoing DNS requests.
+ * Only supported by the c-ares DNS backend */
+ CURLOPT(CURLOPT_DNS_LOCAL_IP4, CURLOPTTYPE_STRINGPOINT, 222),
+
+ /* Set the local IPv6 address to use for outgoing DNS requests.
+ * Only supported by the c-ares DNS backend */
+ CURLOPT(CURLOPT_DNS_LOCAL_IP6, CURLOPTTYPE_STRINGPOINT, 223),
+
+ /* Set authentication options directly */
+ CURLOPT(CURLOPT_LOGIN_OPTIONS, CURLOPTTYPE_STRINGPOINT, 224),
+
+ /* Enable/disable TLS NPN extension (http2 over ssl might fail without) */
+ CURLOPT(CURLOPT_SSL_ENABLE_NPN, CURLOPTTYPE_LONG, 225),
+
+ /* Enable/disable TLS ALPN extension (http2 over ssl might fail without) */
+ CURLOPT(CURLOPT_SSL_ENABLE_ALPN, CURLOPTTYPE_LONG, 226),
+
+ /* Time to wait for a response to a HTTP request containing an
+ * Expect: 100-continue header before sending the data anyway. */
+ CURLOPT(CURLOPT_EXPECT_100_TIMEOUT_MS, CURLOPTTYPE_LONG, 227),
+
+ /* This points to a linked list of headers used for proxy requests only,
+ struct curl_slist kind */
+ CURLOPT(CURLOPT_PROXYHEADER, CURLOPTTYPE_SLISTPOINT, 228),
+
+ /* Pass in a bitmask of "header options" */
+ CURLOPT(CURLOPT_HEADEROPT, CURLOPTTYPE_VALUES, 229),
+
+ /* The public key in DER form used to validate the peer public key
+ this option is used only if SSL_VERIFYPEER is true */
+ CURLOPT(CURLOPT_PINNEDPUBLICKEY, CURLOPTTYPE_STRINGPOINT, 230),
+
+ /* Path to Unix domain socket */
+ CURLOPT(CURLOPT_UNIX_SOCKET_PATH, CURLOPTTYPE_STRINGPOINT, 231),
+
+ /* Set if we should verify the certificate status. */
+ CURLOPT(CURLOPT_SSL_VERIFYSTATUS, CURLOPTTYPE_LONG, 232),
+
+ /* Set if we should enable TLS false start. */
+ CURLOPT(CURLOPT_SSL_FALSESTART, CURLOPTTYPE_LONG, 233),
+
+ /* Do not squash dot-dot sequences */
+ CURLOPT(CURLOPT_PATH_AS_IS, CURLOPTTYPE_LONG, 234),
+
+ /* Proxy Service Name */
+ CURLOPT(CURLOPT_PROXY_SERVICE_NAME, CURLOPTTYPE_STRINGPOINT, 235),
+
+ /* Service Name */
+ CURLOPT(CURLOPT_SERVICE_NAME, CURLOPTTYPE_STRINGPOINT, 236),
+
+ /* Wait/don't wait for pipe/mutex to clarify */
+ CURLOPT(CURLOPT_PIPEWAIT, CURLOPTTYPE_LONG, 237),
+
+ /* Set the protocol used when curl is given a URL without a protocol */
+ CURLOPT(CURLOPT_DEFAULT_PROTOCOL, CURLOPTTYPE_STRINGPOINT, 238),
+
+ /* Set stream weight, 1 - 256 (default is 16) */
+ CURLOPT(CURLOPT_STREAM_WEIGHT, CURLOPTTYPE_LONG, 239),
+
+ /* Set stream dependency on another CURL handle */
+ CURLOPT(CURLOPT_STREAM_DEPENDS, CURLOPTTYPE_OBJECTPOINT, 240),
+
+ /* Set E-xclusive stream dependency on another CURL handle */
+ CURLOPT(CURLOPT_STREAM_DEPENDS_E, CURLOPTTYPE_OBJECTPOINT, 241),
+
+ /* Do not send any tftp option requests to the server */
+ CURLOPT(CURLOPT_TFTP_NO_OPTIONS, CURLOPTTYPE_LONG, 242),
+
+ /* Linked-list of host:port:connect-to-host:connect-to-port,
+ overrides the URL's host:port (only for the network layer) */
+ CURLOPT(CURLOPT_CONNECT_TO, CURLOPTTYPE_SLISTPOINT, 243),
+
+ /* Set TCP Fast Open */
+ CURLOPT(CURLOPT_TCP_FASTOPEN, CURLOPTTYPE_LONG, 244),
+
+ /* Continue to send data if the server responds early with an
+ * HTTP status code >= 300 */
+ CURLOPT(CURLOPT_KEEP_SENDING_ON_ERROR, CURLOPTTYPE_LONG, 245),
+
+ /* The CApath or CAfile used to validate the proxy certificate
+ this option is used only if PROXY_SSL_VERIFYPEER is true */
+ CURLOPT(CURLOPT_PROXY_CAINFO, CURLOPTTYPE_STRINGPOINT, 246),
+
+ /* The CApath directory used to validate the proxy certificate
+ this option is used only if PROXY_SSL_VERIFYPEER is true */
+ CURLOPT(CURLOPT_PROXY_CAPATH, CURLOPTTYPE_STRINGPOINT, 247),
+
+ /* Set if we should verify the proxy in ssl handshake,
+ set 1 to verify. */
+ CURLOPT(CURLOPT_PROXY_SSL_VERIFYPEER, CURLOPTTYPE_LONG, 248),
+
+ /* Set if we should verify the Common name from the proxy certificate in ssl
+ * handshake, set 1 to check existence, 2 to ensure that it matches
+ * the provided hostname. */
+ CURLOPT(CURLOPT_PROXY_SSL_VERIFYHOST, CURLOPTTYPE_LONG, 249),
+
+ /* What version to specifically try to use for proxy.
+ See CURL_SSLVERSION defines below. */
+ CURLOPT(CURLOPT_PROXY_SSLVERSION, CURLOPTTYPE_VALUES, 250),
+
+ /* Set a username for authenticated TLS for proxy */
+ CURLOPT(CURLOPT_PROXY_TLSAUTH_USERNAME, CURLOPTTYPE_STRINGPOINT, 251),
+
+ /* Set a password for authenticated TLS for proxy */
+ CURLOPT(CURLOPT_PROXY_TLSAUTH_PASSWORD, CURLOPTTYPE_STRINGPOINT, 252),
+
+ /* Set authentication type for authenticated TLS for proxy */
+ CURLOPT(CURLOPT_PROXY_TLSAUTH_TYPE, CURLOPTTYPE_STRINGPOINT, 253),
+
+ /* name of the file keeping your private SSL-certificate for proxy */
+ CURLOPT(CURLOPT_PROXY_SSLCERT, CURLOPTTYPE_STRINGPOINT, 254),
+
+ /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") for
+ proxy */
+ CURLOPT(CURLOPT_PROXY_SSLCERTTYPE, CURLOPTTYPE_STRINGPOINT, 255),
+
+ /* name of the file keeping your private SSL-key for proxy */
+ CURLOPT(CURLOPT_PROXY_SSLKEY, CURLOPTTYPE_STRINGPOINT, 256),
+
+ /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") for
+ proxy */
+ CURLOPT(CURLOPT_PROXY_SSLKEYTYPE, CURLOPTTYPE_STRINGPOINT, 257),
+
+ /* password for the SSL private key for proxy */
+ CURLOPT(CURLOPT_PROXY_KEYPASSWD, CURLOPTTYPE_STRINGPOINT, 258),
+
+ /* Specify which SSL ciphers to use for proxy */
+ CURLOPT(CURLOPT_PROXY_SSL_CIPHER_LIST, CURLOPTTYPE_STRINGPOINT, 259),
+
+ /* CRL file for proxy */
+ CURLOPT(CURLOPT_PROXY_CRLFILE, CURLOPTTYPE_STRINGPOINT, 260),
+
+ /* Enable/disable specific SSL features with a bitmask for proxy, see
+ CURLSSLOPT_* */
+ CURLOPT(CURLOPT_PROXY_SSL_OPTIONS, CURLOPTTYPE_LONG, 261),
+
+ /* Name of pre proxy to use. */
+ CURLOPT(CURLOPT_PRE_PROXY, CURLOPTTYPE_STRINGPOINT, 262),
+
+ /* The public key in DER form used to validate the proxy public key
+ this option is used only if PROXY_SSL_VERIFYPEER is true */
+ CURLOPT(CURLOPT_PROXY_PINNEDPUBLICKEY, CURLOPTTYPE_STRINGPOINT, 263),
+
+ /* Path to an abstract Unix domain socket */
+ CURLOPT(CURLOPT_ABSTRACT_UNIX_SOCKET, CURLOPTTYPE_STRINGPOINT, 264),
+
+ /* Suppress proxy CONNECT response headers from user callbacks */
+ CURLOPT(CURLOPT_SUPPRESS_CONNECT_HEADERS, CURLOPTTYPE_LONG, 265),
+
+ /* The request target, instead of extracted from the URL */
+ CURLOPT(CURLOPT_REQUEST_TARGET, CURLOPTTYPE_STRINGPOINT, 266),
+
+ /* bitmask of allowed auth methods for connections to SOCKS5 proxies */
+ CURLOPT(CURLOPT_SOCKS5_AUTH, CURLOPTTYPE_LONG, 267),
+
+ /* Enable/disable SSH compression */
+ CURLOPT(CURLOPT_SSH_COMPRESSION, CURLOPTTYPE_LONG, 268),
+
+ /* Post MIME data. */
+ CURLOPT(CURLOPT_MIMEPOST, CURLOPTTYPE_OBJECTPOINT, 269),
+
+ /* Time to use with the CURLOPT_TIMECONDITION. Specified in number of
+ seconds since 1 Jan 1970. */
+ CURLOPT(CURLOPT_TIMEVALUE_LARGE, CURLOPTTYPE_OFF_T, 270),
+
+ /* Head start in milliseconds to give happy eyeballs. */
+ CURLOPT(CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS, CURLOPTTYPE_LONG, 271),
+
+ /* Function that will be called before a resolver request is made */
+ CURLOPT(CURLOPT_RESOLVER_START_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 272),
+
+ /* User data to pass to the resolver start callback. */
+ CURLOPT(CURLOPT_RESOLVER_START_DATA, CURLOPTTYPE_CBPOINT, 273),
+
+ /* send HAProxy PROXY protocol header? */
+ CURLOPT(CURLOPT_HAPROXYPROTOCOL, CURLOPTTYPE_LONG, 274),
+
+ /* shuffle addresses before use when DNS returns multiple */
+ CURLOPT(CURLOPT_DNS_SHUFFLE_ADDRESSES, CURLOPTTYPE_LONG, 275),
+
+ /* Specify which TLS 1.3 ciphers suites to use */
+ CURLOPT(CURLOPT_TLS13_CIPHERS, CURLOPTTYPE_STRINGPOINT, 276),
+ CURLOPT(CURLOPT_PROXY_TLS13_CIPHERS, CURLOPTTYPE_STRINGPOINT, 277),
+
+ /* Disallow specifying username/login in URL. */
+ CURLOPT(CURLOPT_DISALLOW_USERNAME_IN_URL, CURLOPTTYPE_LONG, 278),
+
+ /* DNS-over-HTTPS URL */
+ CURLOPT(CURLOPT_DOH_URL, CURLOPTTYPE_STRINGPOINT, 279),
+
+ /* Preferred buffer size to use for uploads */
+ CURLOPT(CURLOPT_UPLOAD_BUFFERSIZE, CURLOPTTYPE_LONG, 280),
+
+ /* Time in ms between connection upkeep calls for long-lived connections. */
+ CURLOPT(CURLOPT_UPKEEP_INTERVAL_MS, CURLOPTTYPE_LONG, 281),
+
+ /* Specify URL using CURL URL API. */
+ CURLOPT(CURLOPT_CURLU, CURLOPTTYPE_OBJECTPOINT, 282),
+
+ /* add trailing data just after no more data is available */
+ CURLOPT(CURLOPT_TRAILERFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 283),
+
+ /* pointer to be passed to HTTP_TRAILER_FUNCTION */
+ CURLOPT(CURLOPT_TRAILERDATA, CURLOPTTYPE_CBPOINT, 284),
+
+ /* set this to 1L to allow HTTP/0.9 responses or 0L to disallow */
+ CURLOPT(CURLOPT_HTTP09_ALLOWED, CURLOPTTYPE_LONG, 285),
+
+ /* alt-svc control bitmask */
+ CURLOPT(CURLOPT_ALTSVC_CTRL, CURLOPTTYPE_LONG, 286),
+
+ /* alt-svc cache file name to possibly read from/write to */
+ CURLOPT(CURLOPT_ALTSVC, CURLOPTTYPE_STRINGPOINT, 287),
+
+ /* maximum age of a connection to consider it for reuse (in seconds) */
+ CURLOPT(CURLOPT_MAXAGE_CONN, CURLOPTTYPE_LONG, 288),
+
+ /* SASL authorisation identity */
+ CURLOPT(CURLOPT_SASL_AUTHZID, CURLOPTTYPE_STRINGPOINT, 289),
+
+ /* allow RCPT TO command to fail for some recipients */
+ CURLOPT(CURLOPT_MAIL_RCPT_ALLLOWFAILS, CURLOPTTYPE_LONG, 290),
+
+ /* the private SSL-certificate as a "blob" */
+ CURLOPT(CURLOPT_SSLCERT_BLOB, CURLOPTTYPE_BLOB, 291),
+ CURLOPT(CURLOPT_SSLKEY_BLOB, CURLOPTTYPE_BLOB, 292),
+ CURLOPT(CURLOPT_PROXY_SSLCERT_BLOB, CURLOPTTYPE_BLOB, 293),
+ CURLOPT(CURLOPT_PROXY_SSLKEY_BLOB, CURLOPTTYPE_BLOB, 294),
+ CURLOPT(CURLOPT_ISSUERCERT_BLOB, CURLOPTTYPE_BLOB, 295),
+
+ /* Issuer certificate for proxy */
+ CURLOPT(CURLOPT_PROXY_ISSUERCERT, CURLOPTTYPE_STRINGPOINT, 296),
+ CURLOPT(CURLOPT_PROXY_ISSUERCERT_BLOB, CURLOPTTYPE_BLOB, 297),
+
+ /* the EC curves requested by the TLS client (RFC 8422, 5.1);
+ * OpenSSL support via 'set_groups'/'set_curves':
+ * https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set1_groups.html
+ */
+ CURLOPT(CURLOPT_SSL_EC_CURVES, CURLOPTTYPE_STRINGPOINT, 298),
+
+ /* HSTS bitmask */
+ CURLOPT(CURLOPT_HSTS_CTRL, CURLOPTTYPE_LONG, 299),
+ /* HSTS file name */
+ CURLOPT(CURLOPT_HSTS, CURLOPTTYPE_STRINGPOINT, 300),
+
+ /* HSTS read callback */
+ CURLOPT(CURLOPT_HSTSREADFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 301),
+ CURLOPT(CURLOPT_HSTSREADDATA, CURLOPTTYPE_CBPOINT, 302),
+
+ /* HSTS write callback */
+ CURLOPT(CURLOPT_HSTSWRITEFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 303),
+ CURLOPT(CURLOPT_HSTSWRITEDATA, CURLOPTTYPE_CBPOINT, 304),
+
+ /* Provider for V4 signature */
+ CURLOPT(CURLOPT_AWS_SIGV4, CURLOPTTYPE_STRINGPOINT, 305),
+
+ CURLOPT_LASTENTRY /* the last unused */
+} CURLoption;
+
+#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
+ the obsolete stuff removed! */
+
+/* Backwards compatibility with older names */
+/* These are scheduled to disappear by 2011 */
+
+/* This was added in version 7.19.1 */
+#define CURLOPT_POST301 CURLOPT_POSTREDIR
+
+/* These are scheduled to disappear by 2009 */
+
+/* The following were added in 7.17.0 */
+#define CURLOPT_SSLKEYPASSWD CURLOPT_KEYPASSWD
+#define CURLOPT_FTPAPPEND CURLOPT_APPEND
+#define CURLOPT_FTPLISTONLY CURLOPT_DIRLISTONLY
+#define CURLOPT_FTP_SSL CURLOPT_USE_SSL
+
+/* The following were added earlier */
+
+#define CURLOPT_SSLCERTPASSWD CURLOPT_KEYPASSWD
+#define CURLOPT_KRB4LEVEL CURLOPT_KRBLEVEL
+
+#else
+/* This is set if CURL_NO_OLDIES is defined at compile-time */
+#undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */
+#endif
+
+
+ /* Below here follows defines for the CURLOPT_IPRESOLVE option. If a host
+ name resolves addresses using more than one IP protocol version, this
+ option might be handy to force libcurl to use a specific IP version. */
+#define CURL_IPRESOLVE_WHATEVER 0 /* default, resolves addresses to all IP
+ versions that your system allows */
+#define CURL_IPRESOLVE_V4 1 /* resolve to IPv4 addresses */
+#define CURL_IPRESOLVE_V6 2 /* resolve to IPv6 addresses */
+
+ /* three convenient "aliases" that follow the name scheme better */
+#define CURLOPT_RTSPHEADER CURLOPT_HTTPHEADER
+
+ /* These enums are for use with the CURLOPT_HTTP_VERSION option. */
+enum {
+ CURL_HTTP_VERSION_NONE, /* setting this means we don't care, and that we'd
+ like the library to choose the best possible
+ for us! */
+ CURL_HTTP_VERSION_1_0, /* please use HTTP 1.0 in the request */
+ CURL_HTTP_VERSION_1_1, /* please use HTTP 1.1 in the request */
+ CURL_HTTP_VERSION_2_0, /* please use HTTP 2 in the request */
+ CURL_HTTP_VERSION_2TLS, /* use version 2 for HTTPS, version 1.1 for HTTP */
+ CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE, /* please use HTTP 2 without HTTP/1.1
+ Upgrade */
+ CURL_HTTP_VERSION_3 = 30, /* Makes use of explicit HTTP/3 without fallback.
+ Use CURLOPT_ALTSVC to enable HTTP/3 upgrade */
+ CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */
+};
+
+/* Convenience definition simple because the name of the version is HTTP/2 and
+ not 2.0. The 2_0 version of the enum name was set while the version was
+ still planned to be 2.0 and we stick to it for compatibility. */
+#define CURL_HTTP_VERSION_2 CURL_HTTP_VERSION_2_0
+
+/*
+ * Public API enums for RTSP requests
+ */
+enum {
+ CURL_RTSPREQ_NONE, /* first in list */
+ CURL_RTSPREQ_OPTIONS,
+ CURL_RTSPREQ_DESCRIBE,
+ CURL_RTSPREQ_ANNOUNCE,
+ CURL_RTSPREQ_SETUP,
+ CURL_RTSPREQ_PLAY,
+ CURL_RTSPREQ_PAUSE,
+ CURL_RTSPREQ_TEARDOWN,
+ CURL_RTSPREQ_GET_PARAMETER,
+ CURL_RTSPREQ_SET_PARAMETER,
+ CURL_RTSPREQ_RECORD,
+ CURL_RTSPREQ_RECEIVE,
+ CURL_RTSPREQ_LAST /* last in list */
+};
+
+ /* These enums are for use with the CURLOPT_NETRC option. */
+enum CURL_NETRC_OPTION {
+ CURL_NETRC_IGNORED, /* The .netrc will never be read.
+ * This is the default. */
+ CURL_NETRC_OPTIONAL, /* A user:password in the URL will be preferred
+ * to one in the .netrc. */
+ CURL_NETRC_REQUIRED, /* A user:password in the URL will be ignored.
+ * Unless one is set programmatically, the .netrc
+ * will be queried. */
+ CURL_NETRC_LAST
+};
+
+enum {
+ CURL_SSLVERSION_DEFAULT,
+ CURL_SSLVERSION_TLSv1, /* TLS 1.x */
+ CURL_SSLVERSION_SSLv2,
+ CURL_SSLVERSION_SSLv3,
+ CURL_SSLVERSION_TLSv1_0,
+ CURL_SSLVERSION_TLSv1_1,
+ CURL_SSLVERSION_TLSv1_2,
+ CURL_SSLVERSION_TLSv1_3,
+
+ CURL_SSLVERSION_LAST /* never use, keep last */
+};
+
+enum {
+ CURL_SSLVERSION_MAX_NONE = 0,
+ CURL_SSLVERSION_MAX_DEFAULT = (CURL_SSLVERSION_TLSv1 << 16),
+ CURL_SSLVERSION_MAX_TLSv1_0 = (CURL_SSLVERSION_TLSv1_0 << 16),
+ CURL_SSLVERSION_MAX_TLSv1_1 = (CURL_SSLVERSION_TLSv1_1 << 16),
+ CURL_SSLVERSION_MAX_TLSv1_2 = (CURL_SSLVERSION_TLSv1_2 << 16),
+ CURL_SSLVERSION_MAX_TLSv1_3 = (CURL_SSLVERSION_TLSv1_3 << 16),
+
+ /* never use, keep last */
+ CURL_SSLVERSION_MAX_LAST = (CURL_SSLVERSION_LAST << 16)
+};
+
+enum CURL_TLSAUTH {
+ CURL_TLSAUTH_NONE,
+ CURL_TLSAUTH_SRP,
+ CURL_TLSAUTH_LAST /* never use, keep last */
+};
+
+/* symbols to use with CURLOPT_POSTREDIR.
+ CURL_REDIR_POST_301, CURL_REDIR_POST_302 and CURL_REDIR_POST_303
+ can be bitwise ORed so that CURL_REDIR_POST_301 | CURL_REDIR_POST_302
+ | CURL_REDIR_POST_303 == CURL_REDIR_POST_ALL */
+
+#define CURL_REDIR_GET_ALL 0
+#define CURL_REDIR_POST_301 1
+#define CURL_REDIR_POST_302 2
+#define CURL_REDIR_POST_303 4
+#define CURL_REDIR_POST_ALL \
+ (CURL_REDIR_POST_301|CURL_REDIR_POST_302|CURL_REDIR_POST_303)
+
+typedef enum {
+ CURL_TIMECOND_NONE,
+
+ CURL_TIMECOND_IFMODSINCE,
+ CURL_TIMECOND_IFUNMODSINCE,
+ CURL_TIMECOND_LASTMOD,
+
+ CURL_TIMECOND_LAST
+} curl_TimeCond;
+
+/* Special size_t value signaling a null-terminated string. */
+#define CURL_ZERO_TERMINATED ((size_t) -1)
+
+/* curl_strequal() and curl_strnequal() are subject for removal in a future
+ release */
+CURL_EXTERN int curl_strequal(const char *s1, const char *s2);
+CURL_EXTERN int curl_strnequal(const char *s1, const char *s2, size_t n);
+
+/* Mime/form handling support. */
+typedef struct curl_mime curl_mime; /* Mime context. */
+typedef struct curl_mimepart curl_mimepart; /* Mime part context. */
+
+/*
+ * NAME curl_mime_init()
+ *
+ * DESCRIPTION
+ *
+ * Create a mime context and return its handle. The easy parameter is the
+ * target handle.
+ */
+CURL_EXTERN curl_mime *curl_mime_init(CURL *easy);
+
+/*
+ * NAME curl_mime_free()
+ *
+ * DESCRIPTION
+ *
+ * release a mime handle and its substructures.
+ */
+CURL_EXTERN void curl_mime_free(curl_mime *mime);
+
+/*
+ * NAME curl_mime_addpart()
+ *
+ * DESCRIPTION
+ *
+ * Append a new empty part to the given mime context and return a handle to
+ * the created part.
+ */
+CURL_EXTERN curl_mimepart *curl_mime_addpart(curl_mime *mime);
+
+/*
+ * NAME curl_mime_name()
+ *
+ * DESCRIPTION
+ *
+ * Set mime/form part name.
+ */
+CURL_EXTERN CURLcode curl_mime_name(curl_mimepart *part, const char *name);
+
+/*
+ * NAME curl_mime_filename()
+ *
+ * DESCRIPTION
+ *
+ * Set mime part remote file name.
+ */
+CURL_EXTERN CURLcode curl_mime_filename(curl_mimepart *part,
+ const char *filename);
+
+/*
+ * NAME curl_mime_type()
+ *
+ * DESCRIPTION
+ *
+ * Set mime part type.
+ */
+CURL_EXTERN CURLcode curl_mime_type(curl_mimepart *part, const char *mimetype);
+
+/*
+ * NAME curl_mime_encoder()
+ *
+ * DESCRIPTION
+ *
+ * Set mime data transfer encoder.
+ */
+CURL_EXTERN CURLcode curl_mime_encoder(curl_mimepart *part,
+ const char *encoding);
+
+/*
+ * NAME curl_mime_data()
+ *
+ * DESCRIPTION
+ *
+ * Set mime part data source from memory data,
+ */
+CURL_EXTERN CURLcode curl_mime_data(curl_mimepart *part,
+ const char *data, size_t datasize);
+
+/*
+ * NAME curl_mime_filedata()
+ *
+ * DESCRIPTION
+ *
+ * Set mime part data source from named file.
+ */
+CURL_EXTERN CURLcode curl_mime_filedata(curl_mimepart *part,
+ const char *filename);
+
+/*
+ * NAME curl_mime_data_cb()
+ *
+ * DESCRIPTION
+ *
+ * Set mime part data source from callback function.
+ */
+CURL_EXTERN CURLcode curl_mime_data_cb(curl_mimepart *part,
+ curl_off_t datasize,
+ curl_read_callback readfunc,
+ curl_seek_callback seekfunc,
+ curl_free_callback freefunc,
+ void *arg);
+
+/*
+ * NAME curl_mime_subparts()
+ *
+ * DESCRIPTION
+ *
+ * Set mime part data source from subparts.
+ */
+CURL_EXTERN CURLcode curl_mime_subparts(curl_mimepart *part,
+ curl_mime *subparts);
+/*
+ * NAME curl_mime_headers()
+ *
+ * DESCRIPTION
+ *
+ * Set mime part headers.
+ */
+CURL_EXTERN CURLcode curl_mime_headers(curl_mimepart *part,
+ struct curl_slist *headers,
+ int take_ownership);
+
+typedef enum {
+ CURLFORM_NOTHING, /********* the first one is unused ************/
+ CURLFORM_COPYNAME,
+ CURLFORM_PTRNAME,
+ CURLFORM_NAMELENGTH,
+ CURLFORM_COPYCONTENTS,
+ CURLFORM_PTRCONTENTS,
+ CURLFORM_CONTENTSLENGTH,
+ CURLFORM_FILECONTENT,
+ CURLFORM_ARRAY,
+ CURLFORM_OBSOLETE,
+ CURLFORM_FILE,
+
+ CURLFORM_BUFFER,
+ CURLFORM_BUFFERPTR,
+ CURLFORM_BUFFERLENGTH,
+
+ CURLFORM_CONTENTTYPE,
+ CURLFORM_CONTENTHEADER,
+ CURLFORM_FILENAME,
+ CURLFORM_END,
+ CURLFORM_OBSOLETE2,
+
+ CURLFORM_STREAM,
+ CURLFORM_CONTENTLEN, /* added in 7.46.0, provide a curl_off_t length */
+
+ CURLFORM_LASTENTRY /* the last unused */
+} CURLformoption;
+
+/* structure to be used as parameter for CURLFORM_ARRAY */
+struct curl_forms {
+ CURLformoption option;
+ const char *value;
+};
+
+/* use this for multipart formpost building */
+/* Returns code for curl_formadd()
+ *
+ * Returns:
+ * CURL_FORMADD_OK on success
+ * CURL_FORMADD_MEMORY if the FormInfo allocation fails
+ * CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form
+ * CURL_FORMADD_NULL if a null pointer was given for a char
+ * CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed
+ * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used
+ * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or error)
+ * CURL_FORMADD_MEMORY if a curl_httppost struct cannot be allocated
+ * CURL_FORMADD_MEMORY if some allocation for string copying failed.
+ * CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array
+ *
+ ***************************************************************************/
+typedef enum {
+ CURL_FORMADD_OK, /* first, no error */
+
+ CURL_FORMADD_MEMORY,
+ CURL_FORMADD_OPTION_TWICE,
+ CURL_FORMADD_NULL,
+ CURL_FORMADD_UNKNOWN_OPTION,
+ CURL_FORMADD_INCOMPLETE,
+ CURL_FORMADD_ILLEGAL_ARRAY,
+ CURL_FORMADD_DISABLED, /* libcurl was built with this disabled */
+
+ CURL_FORMADD_LAST /* last */
+} CURLFORMcode;
+
+/*
+ * NAME curl_formadd()
+ *
+ * DESCRIPTION
+ *
+ * Pretty advanced function for building multi-part formposts. Each invoke
+ * adds one part that together construct a full post. Then use
+ * CURLOPT_HTTPPOST to send it off to libcurl.
+ */
+CURL_EXTERN CURLFORMcode curl_formadd(struct curl_httppost **httppost,
+ struct curl_httppost **last_post,
+ ...);
+
+/*
+ * callback function for curl_formget()
+ * The void *arg pointer will be the one passed as second argument to
+ * curl_formget().
+ * The character buffer passed to it must not be freed.
+ * Should return the buffer length passed to it as the argument "len" on
+ * success.
+ */
+typedef size_t (*curl_formget_callback)(void *arg, const char *buf,
+ size_t len);
+
+/*
+ * NAME curl_formget()
+ *
+ * DESCRIPTION
+ *
+ * Serialize a curl_httppost struct built with curl_formadd().
+ * Accepts a void pointer as second argument which will be passed to
+ * the curl_formget_callback function.
+ * Returns 0 on success.
+ */
+CURL_EXTERN int curl_formget(struct curl_httppost *form, void *arg,
+ curl_formget_callback append);
+/*
+ * NAME curl_formfree()
+ *
+ * DESCRIPTION
+ *
+ * Free a multipart formpost previously built with curl_formadd().
+ */
+CURL_EXTERN void curl_formfree(struct curl_httppost *form);
+
+/*
+ * NAME curl_getenv()
+ *
+ * DESCRIPTION
+ *
+ * Returns a malloc()'ed string that MUST be curl_free()ed after usage is
+ * complete. DEPRECATED - see lib/README.curlx
+ */
+CURL_EXTERN char *curl_getenv(const char *variable);
+
+/*
+ * NAME curl_version()
+ *
+ * DESCRIPTION
+ *
+ * Returns a static ascii string of the libcurl version.
+ */
+CURL_EXTERN char *curl_version(void);
+
+/*
+ * NAME curl_easy_escape()
+ *
+ * DESCRIPTION
+ *
+ * Escapes URL strings (converts all letters consider illegal in URLs to their
+ * %XX versions). This function returns a new allocated string or NULL if an
+ * error occurred.
+ */
+CURL_EXTERN char *curl_easy_escape(CURL *handle,
+ const char *string,
+ int length);
+
+/* the previous version: */
+CURL_EXTERN char *curl_escape(const char *string,
+ int length);
+
+
+/*
+ * NAME curl_easy_unescape()
+ *
+ * DESCRIPTION
+ *
+ * Unescapes URL encoding in strings (converts all %XX codes to their 8bit
+ * versions). This function returns a new allocated string or NULL if an error
+ * occurred.
+ * Conversion Note: On non-ASCII platforms the ASCII %XX codes are
+ * converted into the host encoding.
+ */
+CURL_EXTERN char *curl_easy_unescape(CURL *handle,
+ const char *string,
+ int length,
+ int *outlength);
+
+/* the previous version */
+CURL_EXTERN char *curl_unescape(const char *string,
+ int length);
+
+/*
+ * NAME curl_free()
+ *
+ * DESCRIPTION
+ *
+ * Provided for de-allocation in the same translation unit that did the
+ * allocation. Added in libcurl 7.10
+ */
+CURL_EXTERN void curl_free(void *p);
+
+/*
+ * NAME curl_global_init()
+ *
+ * DESCRIPTION
+ *
+ * curl_global_init() should be invoked exactly once for each application that
+ * uses libcurl and before any call of other libcurl functions.
+ *
+ * This function is not thread-safe!
+ */
+CURL_EXTERN CURLcode curl_global_init(long flags);
+
+/*
+ * NAME curl_global_init_mem()
+ *
+ * DESCRIPTION
+ *
+ * curl_global_init() or curl_global_init_mem() should be invoked exactly once
+ * for each application that uses libcurl. This function can be used to
+ * initialize libcurl and set user defined memory management callback
+ * functions. Users can implement memory management routines to check for
+ * memory leaks, check for mis-use of the curl library etc. User registered
+ * callback routines will be invoked by this library instead of the system
+ * memory management routines like malloc, free etc.
+ */
+CURL_EXTERN CURLcode curl_global_init_mem(long flags,
+ curl_malloc_callback m,
+ curl_free_callback f,
+ curl_realloc_callback r,
+ curl_strdup_callback s,
+ curl_calloc_callback c);
+
+/*
+ * NAME curl_global_cleanup()
+ *
+ * DESCRIPTION
+ *
+ * curl_global_cleanup() should be invoked exactly once for each application
+ * that uses libcurl
+ */
+CURL_EXTERN void curl_global_cleanup(void);
+
+/* linked-list structure for the CURLOPT_QUOTE option (and other) */
+struct curl_slist {
+ char *data;
+ struct curl_slist *next;
+};
+
+/*
+ * NAME curl_global_sslset()
+ *
+ * DESCRIPTION
+ *
+ * When built with multiple SSL backends, curl_global_sslset() allows to
+ * choose one. This function can only be called once, and it must be called
+ * *before* curl_global_init().
+ *
+ * The backend can be identified by the id (e.g. CURLSSLBACKEND_OPENSSL). The
+ * backend can also be specified via the name parameter (passing -1 as id).
+ * If both id and name are specified, the name will be ignored. If neither id
+ * nor name are specified, the function will fail with
+ * CURLSSLSET_UNKNOWN_BACKEND and set the "avail" pointer to the
+ * NULL-terminated list of available backends.
+ *
+ * Upon success, the function returns CURLSSLSET_OK.
+ *
+ * If the specified SSL backend is not available, the function returns
+ * CURLSSLSET_UNKNOWN_BACKEND and sets the "avail" pointer to a NULL-terminated
+ * list of available SSL backends.
+ *
+ * The SSL backend can be set only once. If it has already been set, a
+ * subsequent attempt to change it will result in a CURLSSLSET_TOO_LATE.
+ */
+
+struct curl_ssl_backend {
+ curl_sslbackend id;
+ const char *name;
+};
+typedef struct curl_ssl_backend curl_ssl_backend;
+
+typedef enum {
+ CURLSSLSET_OK = 0,
+ CURLSSLSET_UNKNOWN_BACKEND,
+ CURLSSLSET_TOO_LATE,
+ CURLSSLSET_NO_BACKENDS /* libcurl was built without any SSL support */
+} CURLsslset;
+
+CURL_EXTERN CURLsslset curl_global_sslset(curl_sslbackend id, const char *name,
+ const curl_ssl_backend ***avail);
+
+/*
+ * NAME curl_slist_append()
+ *
+ * DESCRIPTION
+ *
+ * Appends a string to a linked list. If no list exists, it will be created
+ * first. Returns the new list, after appending.
+ */
+CURL_EXTERN struct curl_slist *curl_slist_append(struct curl_slist *,
+ const char *);
+
+/*
+ * NAME curl_slist_free_all()
+ *
+ * DESCRIPTION
+ *
+ * free a previously built curl_slist.
+ */
+CURL_EXTERN void curl_slist_free_all(struct curl_slist *);
+
+/*
+ * NAME curl_getdate()
+ *
+ * DESCRIPTION
+ *
+ * Returns the time, in seconds since 1 Jan 1970 of the time string given in
+ * the first argument. The time argument in the second parameter is unused
+ * and should be set to NULL.
+ */
+CURL_EXTERN time_t curl_getdate(const char *p, const time_t *unused);
+
+/* info about the certificate chain, only for OpenSSL, GnuTLS, Schannel, NSS
+ and GSKit builds. Asked for with CURLOPT_CERTINFO / CURLINFO_CERTINFO */
+struct curl_certinfo {
+ int num_of_certs; /* number of certificates with information */
+ struct curl_slist **certinfo; /* for each index in this array, there's a
+ linked list with textual information in the
+ format "name: value" */
+};
+
+/* Information about the SSL library used and the respective internal SSL
+ handle, which can be used to obtain further information regarding the
+ connection. Asked for with CURLINFO_TLS_SSL_PTR or CURLINFO_TLS_SESSION. */
+struct curl_tlssessioninfo {
+ curl_sslbackend backend;
+ void *internals;
+};
+
+#define CURLINFO_STRING 0x100000
+#define CURLINFO_LONG 0x200000
+#define CURLINFO_DOUBLE 0x300000
+#define CURLINFO_SLIST 0x400000
+#define CURLINFO_PTR 0x400000 /* same as SLIST */
+#define CURLINFO_SOCKET 0x500000
+#define CURLINFO_OFF_T 0x600000
+#define CURLINFO_MASK 0x0fffff
+#define CURLINFO_TYPEMASK 0xf00000
+
+typedef enum {
+ CURLINFO_NONE, /* first, never use this */
+ CURLINFO_EFFECTIVE_URL = CURLINFO_STRING + 1,
+ CURLINFO_RESPONSE_CODE = CURLINFO_LONG + 2,
+ CURLINFO_TOTAL_TIME = CURLINFO_DOUBLE + 3,
+ CURLINFO_NAMELOOKUP_TIME = CURLINFO_DOUBLE + 4,
+ CURLINFO_CONNECT_TIME = CURLINFO_DOUBLE + 5,
+ CURLINFO_PRETRANSFER_TIME = CURLINFO_DOUBLE + 6,
+ CURLINFO_SIZE_UPLOAD = CURLINFO_DOUBLE + 7,
+ CURLINFO_SIZE_UPLOAD_T = CURLINFO_OFF_T + 7,
+ CURLINFO_SIZE_DOWNLOAD = CURLINFO_DOUBLE + 8,
+ CURLINFO_SIZE_DOWNLOAD_T = CURLINFO_OFF_T + 8,
+ CURLINFO_SPEED_DOWNLOAD = CURLINFO_DOUBLE + 9,
+ CURLINFO_SPEED_DOWNLOAD_T = CURLINFO_OFF_T + 9,
+ CURLINFO_SPEED_UPLOAD = CURLINFO_DOUBLE + 10,
+ CURLINFO_SPEED_UPLOAD_T = CURLINFO_OFF_T + 10,
+ CURLINFO_HEADER_SIZE = CURLINFO_LONG + 11,
+ CURLINFO_REQUEST_SIZE = CURLINFO_LONG + 12,
+ CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG + 13,
+ CURLINFO_FILETIME = CURLINFO_LONG + 14,
+ CURLINFO_FILETIME_T = CURLINFO_OFF_T + 14,
+ CURLINFO_CONTENT_LENGTH_DOWNLOAD = CURLINFO_DOUBLE + 15,
+ CURLINFO_CONTENT_LENGTH_DOWNLOAD_T = CURLINFO_OFF_T + 15,
+ CURLINFO_CONTENT_LENGTH_UPLOAD = CURLINFO_DOUBLE + 16,
+ CURLINFO_CONTENT_LENGTH_UPLOAD_T = CURLINFO_OFF_T + 16,
+ CURLINFO_STARTTRANSFER_TIME = CURLINFO_DOUBLE + 17,
+ CURLINFO_CONTENT_TYPE = CURLINFO_STRING + 18,
+ CURLINFO_REDIRECT_TIME = CURLINFO_DOUBLE + 19,
+ CURLINFO_REDIRECT_COUNT = CURLINFO_LONG + 20,
+ CURLINFO_PRIVATE = CURLINFO_STRING + 21,
+ CURLINFO_HTTP_CONNECTCODE = CURLINFO_LONG + 22,
+ CURLINFO_HTTPAUTH_AVAIL = CURLINFO_LONG + 23,
+ CURLINFO_PROXYAUTH_AVAIL = CURLINFO_LONG + 24,
+ CURLINFO_OS_ERRNO = CURLINFO_LONG + 25,
+ CURLINFO_NUM_CONNECTS = CURLINFO_LONG + 26,
+ CURLINFO_SSL_ENGINES = CURLINFO_SLIST + 27,
+ CURLINFO_COOKIELIST = CURLINFO_SLIST + 28,
+ CURLINFO_LASTSOCKET = CURLINFO_LONG + 29,
+ CURLINFO_FTP_ENTRY_PATH = CURLINFO_STRING + 30,
+ CURLINFO_REDIRECT_URL = CURLINFO_STRING + 31,
+ CURLINFO_PRIMARY_IP = CURLINFO_STRING + 32,
+ CURLINFO_APPCONNECT_TIME = CURLINFO_DOUBLE + 33,
+ CURLINFO_CERTINFO = CURLINFO_PTR + 34,
+ CURLINFO_CONDITION_UNMET = CURLINFO_LONG + 35,
+ CURLINFO_RTSP_SESSION_ID = CURLINFO_STRING + 36,
+ CURLINFO_RTSP_CLIENT_CSEQ = CURLINFO_LONG + 37,
+ CURLINFO_RTSP_SERVER_CSEQ = CURLINFO_LONG + 38,
+ CURLINFO_RTSP_CSEQ_RECV = CURLINFO_LONG + 39,
+ CURLINFO_PRIMARY_PORT = CURLINFO_LONG + 40,
+ CURLINFO_LOCAL_IP = CURLINFO_STRING + 41,
+ CURLINFO_LOCAL_PORT = CURLINFO_LONG + 42,
+ CURLINFO_TLS_SESSION = CURLINFO_PTR + 43,
+ CURLINFO_ACTIVESOCKET = CURLINFO_SOCKET + 44,
+ CURLINFO_TLS_SSL_PTR = CURLINFO_PTR + 45,
+ CURLINFO_HTTP_VERSION = CURLINFO_LONG + 46,
+ CURLINFO_PROXY_SSL_VERIFYRESULT = CURLINFO_LONG + 47,
+ CURLINFO_PROTOCOL = CURLINFO_LONG + 48,
+ CURLINFO_SCHEME = CURLINFO_STRING + 49,
+ CURLINFO_TOTAL_TIME_T = CURLINFO_OFF_T + 50,
+ CURLINFO_NAMELOOKUP_TIME_T = CURLINFO_OFF_T + 51,
+ CURLINFO_CONNECT_TIME_T = CURLINFO_OFF_T + 52,
+ CURLINFO_PRETRANSFER_TIME_T = CURLINFO_OFF_T + 53,
+ CURLINFO_STARTTRANSFER_TIME_T = CURLINFO_OFF_T + 54,
+ CURLINFO_REDIRECT_TIME_T = CURLINFO_OFF_T + 55,
+ CURLINFO_APPCONNECT_TIME_T = CURLINFO_OFF_T + 56,
+ CURLINFO_RETRY_AFTER = CURLINFO_OFF_T + 57,
+ CURLINFO_EFFECTIVE_METHOD = CURLINFO_STRING + 58,
+ CURLINFO_PROXY_ERROR = CURLINFO_LONG + 59,
+
+ CURLINFO_LASTONE = 59
+} CURLINFO;
+
+/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
+ CURLINFO_HTTP_CODE */
+#define CURLINFO_HTTP_CODE CURLINFO_RESPONSE_CODE
+
+typedef enum {
+ CURLCLOSEPOLICY_NONE, /* first, never use this */
+
+ CURLCLOSEPOLICY_OLDEST,
+ CURLCLOSEPOLICY_LEAST_RECENTLY_USED,
+ CURLCLOSEPOLICY_LEAST_TRAFFIC,
+ CURLCLOSEPOLICY_SLOWEST,
+ CURLCLOSEPOLICY_CALLBACK,
+
+ CURLCLOSEPOLICY_LAST /* last, never use this */
+} curl_closepolicy;
+
+#define CURL_GLOBAL_SSL (1<<0) /* no purpose since since 7.57.0 */
+#define CURL_GLOBAL_WIN32 (1<<1)
+#define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32)
+#define CURL_GLOBAL_NOTHING 0
+#define CURL_GLOBAL_DEFAULT CURL_GLOBAL_ALL
+#define CURL_GLOBAL_ACK_EINTR (1<<2)
+
+
+/*****************************************************************************
+ * Setup defines, protos etc for the sharing stuff.
+ */
+
+/* Different data locks for a single share */
+typedef enum {
+ CURL_LOCK_DATA_NONE = 0,
+ /* CURL_LOCK_DATA_SHARE is used internally to say that
+ * the locking is just made to change the internal state of the share
+ * itself.
+ */
+ CURL_LOCK_DATA_SHARE,
+ CURL_LOCK_DATA_COOKIE,
+ CURL_LOCK_DATA_DNS,
+ CURL_LOCK_DATA_SSL_SESSION,
+ CURL_LOCK_DATA_CONNECT,
+ CURL_LOCK_DATA_PSL,
+ CURL_LOCK_DATA_LAST
+} curl_lock_data;
+
+/* Different lock access types */
+typedef enum {
+ CURL_LOCK_ACCESS_NONE = 0, /* unspecified action */
+ CURL_LOCK_ACCESS_SHARED = 1, /* for read perhaps */
+ CURL_LOCK_ACCESS_SINGLE = 2, /* for write perhaps */
+ CURL_LOCK_ACCESS_LAST /* never use */
+} curl_lock_access;
+
+typedef void (*curl_lock_function)(CURL *handle,
+ curl_lock_data data,
+ curl_lock_access locktype,
+ void *userptr);
+typedef void (*curl_unlock_function)(CURL *handle,
+ curl_lock_data data,
+ void *userptr);
+
+
+typedef enum {
+ CURLSHE_OK, /* all is fine */
+ CURLSHE_BAD_OPTION, /* 1 */
+ CURLSHE_IN_USE, /* 2 */
+ CURLSHE_INVALID, /* 3 */
+ CURLSHE_NOMEM, /* 4 out of memory */
+ CURLSHE_NOT_BUILT_IN, /* 5 feature not present in lib */
+ CURLSHE_LAST /* never use */
+} CURLSHcode;
+
+typedef enum {
+ CURLSHOPT_NONE, /* don't use */
+ CURLSHOPT_SHARE, /* specify a data type to share */
+ CURLSHOPT_UNSHARE, /* specify which data type to stop sharing */
+ CURLSHOPT_LOCKFUNC, /* pass in a 'curl_lock_function' pointer */
+ CURLSHOPT_UNLOCKFUNC, /* pass in a 'curl_unlock_function' pointer */
+ CURLSHOPT_USERDATA, /* pass in a user data pointer used in the lock/unlock
+ callback functions */
+ CURLSHOPT_LAST /* never use */
+} CURLSHoption;
+
+CURL_EXTERN CURLSH *curl_share_init(void);
+CURL_EXTERN CURLSHcode curl_share_setopt(CURLSH *, CURLSHoption option, ...);
+CURL_EXTERN CURLSHcode curl_share_cleanup(CURLSH *);
+
+/****************************************************************************
+ * Structures for querying information about the curl library at runtime.
+ */
+
+typedef enum {
+ CURLVERSION_FIRST,
+ CURLVERSION_SECOND,
+ CURLVERSION_THIRD,
+ CURLVERSION_FOURTH,
+ CURLVERSION_FIFTH,
+ CURLVERSION_SIXTH,
+ CURLVERSION_SEVENTH,
+ CURLVERSION_EIGHTH,
+ CURLVERSION_NINTH,
+ CURLVERSION_LAST /* never actually use this */
+} CURLversion;
+
+/* The 'CURLVERSION_NOW' is the symbolic name meant to be used by
+ basically all programs ever that want to get version information. It is
+ meant to be a built-in version number for what kind of struct the caller
+ expects. If the struct ever changes, we redefine the NOW to another enum
+ from above. */
+#define CURLVERSION_NOW CURLVERSION_NINTH
+
+struct curl_version_info_data {
+ CURLversion age; /* age of the returned struct */
+ const char *version; /* LIBCURL_VERSION */
+ unsigned int version_num; /* LIBCURL_VERSION_NUM */
+ const char *host; /* OS/host/cpu/machine when configured */
+ int features; /* bitmask, see defines below */
+ const char *ssl_version; /* human readable string */
+ long ssl_version_num; /* not used anymore, always 0 */
+ const char *libz_version; /* human readable string */
+ /* protocols is terminated by an entry with a NULL protoname */
+ const char * const *protocols;
+
+ /* The fields below this were added in CURLVERSION_SECOND */
+ const char *ares;
+ int ares_num;
+
+ /* This field was added in CURLVERSION_THIRD */
+ const char *libidn;
+
+ /* These field were added in CURLVERSION_FOURTH */
+
+ /* Same as '_libiconv_version' if built with HAVE_ICONV */
+ int iconv_ver_num;
+
+ const char *libssh_version; /* human readable string */
+
+ /* These fields were added in CURLVERSION_FIFTH */
+ unsigned int brotli_ver_num; /* Numeric Brotli version
+ (MAJOR << 24) | (MINOR << 12) | PATCH */
+ const char *brotli_version; /* human readable string. */
+
+ /* These fields were added in CURLVERSION_SIXTH */
+ unsigned int nghttp2_ver_num; /* Numeric nghttp2 version
+ (MAJOR << 16) | (MINOR << 8) | PATCH */
+ const char *nghttp2_version; /* human readable string. */
+ const char *quic_version; /* human readable quic (+ HTTP/3) library +
+ version or NULL */
+
+ /* These fields were added in CURLVERSION_SEVENTH */
+ const char *cainfo; /* the built-in default CURLOPT_CAINFO, might
+ be NULL */
+ const char *capath; /* the built-in default CURLOPT_CAPATH, might
+ be NULL */
+
+ /* These fields were added in CURLVERSION_EIGHTH */
+ unsigned int zstd_ver_num; /* Numeric Zstd version
+ (MAJOR << 24) | (MINOR << 12) | PATCH */
+ const char *zstd_version; /* human readable string. */
+
+ /* These fields were added in CURLVERSION_NINTH */
+ const char *hyper_version; /* human readable string. */
+};
+typedef struct curl_version_info_data curl_version_info_data;
+
+#define CURL_VERSION_IPV6 (1<<0) /* IPv6-enabled */
+#define CURL_VERSION_KERBEROS4 (1<<1) /* Kerberos V4 auth is supported
+ (deprecated) */
+#define CURL_VERSION_SSL (1<<2) /* SSL options are present */
+#define CURL_VERSION_LIBZ (1<<3) /* libz features are present */
+#define CURL_VERSION_NTLM (1<<4) /* NTLM auth is supported */
+#define CURL_VERSION_GSSNEGOTIATE (1<<5) /* Negotiate auth is supported
+ (deprecated) */
+#define CURL_VERSION_DEBUG (1<<6) /* Built with debug capabilities */
+#define CURL_VERSION_ASYNCHDNS (1<<7) /* Asynchronous DNS resolves */
+#define CURL_VERSION_SPNEGO (1<<8) /* SPNEGO auth is supported */
+#define CURL_VERSION_LARGEFILE (1<<9) /* Supports files larger than 2GB */
+#define CURL_VERSION_IDN (1<<10) /* Internationized Domain Names are
+ supported */
+#define CURL_VERSION_SSPI (1<<11) /* Built against Windows SSPI */
+#define CURL_VERSION_CONV (1<<12) /* Character conversions supported */
+#define CURL_VERSION_CURLDEBUG (1<<13) /* Debug memory tracking supported */
+#define CURL_VERSION_TLSAUTH_SRP (1<<14) /* TLS-SRP auth is supported */
+#define CURL_VERSION_NTLM_WB (1<<15) /* NTLM delegation to winbind helper
+ is supported */
+#define CURL_VERSION_HTTP2 (1<<16) /* HTTP2 support built-in */
+#define CURL_VERSION_GSSAPI (1<<17) /* Built against a GSS-API library */
+#define CURL_VERSION_KERBEROS5 (1<<18) /* Kerberos V5 auth is supported */
+#define CURL_VERSION_UNIX_SOCKETS (1<<19) /* Unix domain sockets support */
+#define CURL_VERSION_PSL (1<<20) /* Mozilla's Public Suffix List, used
+ for cookie domain verification */
+#define CURL_VERSION_HTTPS_PROXY (1<<21) /* HTTPS-proxy support built-in */
+#define CURL_VERSION_MULTI_SSL (1<<22) /* Multiple SSL backends available */
+#define CURL_VERSION_BROTLI (1<<23) /* Brotli features are present. */
+#define CURL_VERSION_ALTSVC (1<<24) /* Alt-Svc handling built-in */
+#define CURL_VERSION_HTTP3 (1<<25) /* HTTP3 support built-in */
+#define CURL_VERSION_ZSTD (1<<26) /* zstd features are present */
+#define CURL_VERSION_UNICODE (1<<27) /* Unicode support on Windows */
+#define CURL_VERSION_HSTS (1<<28) /* HSTS is supported */
+
+ /*
+ * NAME curl_version_info()
+ *
+ * DESCRIPTION
+ *
+ * This function returns a pointer to a static copy of the version info
+ * struct. See above.
+ */
+CURL_EXTERN curl_version_info_data *curl_version_info(CURLversion);
+
+/*
+ * NAME curl_easy_strerror()
+ *
+ * DESCRIPTION
+ *
+ * The curl_easy_strerror function may be used to turn a CURLcode value
+ * into the equivalent human readable error string. This is useful
+ * for printing meaningful error messages.
+ */
+CURL_EXTERN const char *curl_easy_strerror(CURLcode);
+
+/*
+ * NAME curl_share_strerror()
+ *
+ * DESCRIPTION
+ *
+ * The curl_share_strerror function may be used to turn a CURLSHcode value
+ * into the equivalent human readable error string. This is useful
+ * for printing meaningful error messages.
+ */
+CURL_EXTERN const char *curl_share_strerror(CURLSHcode);
+
+/*
+ * NAME curl_easy_pause()
+ *
+ * DESCRIPTION
+ *
+ * The curl_easy_pause function pauses or unpauses transfers. Select the new
+ * state by setting the bitmask, use the convenience defines below.
+ *
+ */
+CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask);
+
+#define CURLPAUSE_RECV (1<<0)
+#define CURLPAUSE_RECV_CONT (0)
+
+#define CURLPAUSE_SEND (1<<2)
+#define CURLPAUSE_SEND_CONT (0)
+
+#define CURLPAUSE_ALL (CURLPAUSE_RECV|CURLPAUSE_SEND)
+#define CURLPAUSE_CONT (CURLPAUSE_RECV_CONT|CURLPAUSE_SEND_CONT)
+
+#ifdef __cplusplus
+}
+#endif
+
+/* unfortunately, the easy.h and multi.h include files need options and info
+ stuff before they can be included! */
+#include "easy.h" /* nothing in curl is fun without the easy stuff */
+#include "multi.h"
+#include "urlapi.h"
+#include "options.h"
+
+/* the typechecker doesn't work in C++ (yet) */
+#if defined(__GNUC__) && defined(__GNUC_MINOR__) && \
+ ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && \
+ !defined(__cplusplus) && !defined(CURL_DISABLE_TYPECHECK)
+#include "typecheck-gcc.h"
+#else
+#if defined(__STDC__) && (__STDC__ >= 1)
+/* This preprocessor magic that replaces a call with the exact same call is
+ only done to make sure application authors pass exactly three arguments
+ to these functions. */
+#define curl_easy_setopt(handle,opt,param) curl_easy_setopt(handle,opt,param)
+#define curl_easy_getinfo(handle,info,arg) curl_easy_getinfo(handle,info,arg)
+#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param)
+#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param)
+#endif /* __STDC__ >= 1 */
+#endif /* gcc >= 4.3 && !__cplusplus */
+
+#endif /* CURLINC_CURL_H */
diff --git a/csgo2/libcurl/inc/curl/curlver.h b/csgo2/libcurl/inc/curl/curlver.h
new file mode 100644
index 0000000..d61bb1c
--- /dev/null
+++ b/csgo2/libcurl/inc/curl/curlver.h
@@ -0,0 +1,77 @@
+#ifndef CURLINC_CURLVER_H
+#define CURLINC_CURLVER_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* This header file contains nothing but libcurl version info, generated by
+ a script at release-time. This was made its own header file in 7.11.2 */
+
+/* This is the global package copyright */
+#define LIBCURL_COPYRIGHT "1996 - 2020 Daniel Stenberg, ."
+
+/* This is the version number of the libcurl package from which this header
+ file origins: */
+#define LIBCURL_VERSION "7.75.0-DEV"
+
+/* The numeric version number is also available "in parts" by using these
+ defines: */
+#define LIBCURL_VERSION_MAJOR 7
+#define LIBCURL_VERSION_MINOR 75
+#define LIBCURL_VERSION_PATCH 0
+
+/* This is the numeric version of the libcurl version number, meant for easier
+ parsing and comparisons by programs. The LIBCURL_VERSION_NUM define will
+ always follow this syntax:
+
+ 0xXXYYZZ
+
+ Where XX, YY and ZZ are the main version, release and patch numbers in
+ hexadecimal (using 8 bits each). All three numbers are always represented
+ using two digits. 1.2 would appear as "0x010200" while version 9.11.7
+ appears as "0x090b07".
+
+ This 6-digit (24 bits) hexadecimal number does not show pre-release number,
+ and it is always a greater number in a more recent release. It makes
+ comparisons with greater than and less than work.
+
+ Note: This define is the full hex number and _does not_ use the
+ CURL_VERSION_BITS() macro since curl's own configure script greps for it
+ and needs it to contain the full number.
+*/
+#define LIBCURL_VERSION_NUM 0x074b00
+
+/*
+ * This is the date and time when the full source package was created. The
+ * timestamp is not stored in git, as the timestamp is properly set in the
+ * tarballs by the maketgz script.
+ *
+ * The format of the date follows this template:
+ *
+ * "2007-11-23"
+ */
+#define LIBCURL_TIMESTAMP "[unreleased]"
+
+#define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|(z))
+#define CURL_AT_LEAST_VERSION(x,y,z) \
+ (LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z))
+
+#endif /* CURLINC_CURLVER_H */
diff --git a/csgo2/libcurl/inc/curl/easy.h b/csgo2/libcurl/inc/curl/easy.h
new file mode 100644
index 0000000..2dbfb26
--- /dev/null
+++ b/csgo2/libcurl/inc/curl/easy.h
@@ -0,0 +1,123 @@
+#ifndef CURLINC_EASY_H
+#define CURLINC_EASY_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Flag bits in the curl_blob struct: */
+#define CURL_BLOB_COPY 1 /* tell libcurl to copy the data */
+#define CURL_BLOB_NOCOPY 0 /* tell libcurl to NOT copy the data */
+
+struct curl_blob {
+ void *data;
+ size_t len;
+ unsigned int flags; /* bit 0 is defined, the rest are reserved and should be
+ left zeroes */
+};
+
+CURL_EXTERN CURL *curl_easy_init(void);
+CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...);
+CURL_EXTERN CURLcode curl_easy_perform(CURL *curl);
+CURL_EXTERN void curl_easy_cleanup(CURL *curl);
+
+/*
+ * NAME curl_easy_getinfo()
+ *
+ * DESCRIPTION
+ *
+ * Request internal information from the curl session with this function. The
+ * third argument MUST be a pointer to a long, a pointer to a char * or a
+ * pointer to a double (as the documentation describes elsewhere). The data
+ * pointed to will be filled in accordingly and can be relied upon only if the
+ * function returns CURLE_OK. This function is intended to get used *AFTER* a
+ * performed transfer, all results from this function are undefined until the
+ * transfer is completed.
+ */
+CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...);
+
+
+/*
+ * NAME curl_easy_duphandle()
+ *
+ * DESCRIPTION
+ *
+ * Creates a new curl session handle with the same options set for the handle
+ * passed in. Duplicating a handle could only be a matter of cloning data and
+ * options, internal state info and things like persistent connections cannot
+ * be transferred. It is useful in multithreaded applications when you can run
+ * curl_easy_duphandle() for each new thread to avoid a series of identical
+ * curl_easy_setopt() invokes in every thread.
+ */
+CURL_EXTERN CURL *curl_easy_duphandle(CURL *curl);
+
+/*
+ * NAME curl_easy_reset()
+ *
+ * DESCRIPTION
+ *
+ * Re-initializes a CURL handle to the default values. This puts back the
+ * handle to the same state as it was in when it was just created.
+ *
+ * It does keep: live connections, the Session ID cache, the DNS cache and the
+ * cookies.
+ */
+CURL_EXTERN void curl_easy_reset(CURL *curl);
+
+/*
+ * NAME curl_easy_recv()
+ *
+ * DESCRIPTION
+ *
+ * Receives data from the connected socket. Use after successful
+ * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
+ */
+CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen,
+ size_t *n);
+
+/*
+ * NAME curl_easy_send()
+ *
+ * DESCRIPTION
+ *
+ * Sends data over the connected socket. Use after successful
+ * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
+ */
+CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer,
+ size_t buflen, size_t *n);
+
+
+/*
+ * NAME curl_easy_upkeep()
+ *
+ * DESCRIPTION
+ *
+ * Performs connection upkeep for the given session handle.
+ */
+CURL_EXTERN CURLcode curl_easy_upkeep(CURL *curl);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/csgo2/libcurl/inc/curl/mprintf.h b/csgo2/libcurl/inc/curl/mprintf.h
new file mode 100644
index 0000000..3549552
--- /dev/null
+++ b/csgo2/libcurl/inc/curl/mprintf.h
@@ -0,0 +1,50 @@
+#ifndef CURLINC_MPRINTF_H
+#define CURLINC_MPRINTF_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include
+#include /* needed for FILE */
+#include "curl.h" /* for CURL_EXTERN */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+CURL_EXTERN int curl_mprintf(const char *format, ...);
+CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...);
+CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...);
+CURL_EXTERN int curl_msnprintf(char *buffer, size_t maxlength,
+ const char *format, ...);
+CURL_EXTERN int curl_mvprintf(const char *format, va_list args);
+CURL_EXTERN int curl_mvfprintf(FILE *fd, const char *format, va_list args);
+CURL_EXTERN int curl_mvsprintf(char *buffer, const char *format, va_list args);
+CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength,
+ const char *format, va_list args);
+CURL_EXTERN char *curl_maprintf(const char *format, ...);
+CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CURLINC_MPRINTF_H */
diff --git a/csgo2/libcurl/inc/curl/multi.h b/csgo2/libcurl/inc/curl/multi.h
new file mode 100644
index 0000000..37f9829
--- /dev/null
+++ b/csgo2/libcurl/inc/curl/multi.h
@@ -0,0 +1,456 @@
+#ifndef CURLINC_MULTI_H
+#define CURLINC_MULTI_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/*
+ This is an "external" header file. Don't give away any internals here!
+
+ GOALS
+
+ o Enable a "pull" interface. The application that uses libcurl decides where
+ and when to ask libcurl to get/send data.
+
+ o Enable multiple simultaneous transfers in the same thread without making it
+ complicated for the application.
+
+ o Enable the application to select() on its own file descriptors and curl's
+ file descriptors simultaneous easily.
+
+*/
+
+/*
+ * This header file should not really need to include "curl.h" since curl.h
+ * itself includes this file and we expect user applications to do #include
+ * without the need for especially including multi.h.
+ *
+ * For some reason we added this include here at one point, and rather than to
+ * break existing (wrongly written) libcurl applications, we leave it as-is
+ * but with this warning attached.
+ */
+#include "curl.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER)
+typedef struct Curl_multi CURLM;
+#else
+typedef void CURLM;
+#endif
+
+typedef enum {
+ CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or
+ curl_multi_socket*() soon */
+ CURLM_OK,
+ CURLM_BAD_HANDLE, /* the passed-in handle is not a valid CURLM handle */
+ CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */
+ CURLM_OUT_OF_MEMORY, /* if you ever get this, you're in deep sh*t */
+ CURLM_INTERNAL_ERROR, /* this is a libcurl bug */
+ CURLM_BAD_SOCKET, /* the passed in socket argument did not match */
+ CURLM_UNKNOWN_OPTION, /* curl_multi_setopt() with unsupported option */
+ CURLM_ADDED_ALREADY, /* an easy handle already added to a multi handle was
+ attempted to get added - again */
+ CURLM_RECURSIVE_API_CALL, /* an api function was called from inside a
+ callback */
+ CURLM_WAKEUP_FAILURE, /* wakeup is unavailable or failed */
+ CURLM_BAD_FUNCTION_ARGUMENT, /* function called with a bad parameter */
+ CURLM_LAST
+} CURLMcode;
+
+/* just to make code nicer when using curl_multi_socket() you can now check
+ for CURLM_CALL_MULTI_SOCKET too in the same style it works for
+ curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */
+#define CURLM_CALL_MULTI_SOCKET CURLM_CALL_MULTI_PERFORM
+
+/* bitmask bits for CURLMOPT_PIPELINING */
+#define CURLPIPE_NOTHING 0L
+#define CURLPIPE_HTTP1 1L
+#define CURLPIPE_MULTIPLEX 2L
+
+typedef enum {
+ CURLMSG_NONE, /* first, not used */
+ CURLMSG_DONE, /* This easy handle has completed. 'result' contains
+ the CURLcode of the transfer */
+ CURLMSG_LAST /* last, not used */
+} CURLMSG;
+
+struct CURLMsg {
+ CURLMSG msg; /* what this message means */
+ CURL *easy_handle; /* the handle it concerns */
+ union {
+ void *whatever; /* message-specific data */
+ CURLcode result; /* return code for transfer */
+ } data;
+};
+typedef struct CURLMsg CURLMsg;
+
+/* Based on poll(2) structure and values.
+ * We don't use pollfd and POLL* constants explicitly
+ * to cover platforms without poll(). */
+#define CURL_WAIT_POLLIN 0x0001
+#define CURL_WAIT_POLLPRI 0x0002
+#define CURL_WAIT_POLLOUT 0x0004
+
+struct curl_waitfd {
+ curl_socket_t fd;
+ short events;
+ short revents; /* not supported yet */
+};
+
+/*
+ * Name: curl_multi_init()
+ *
+ * Desc: inititalize multi-style curl usage
+ *
+ * Returns: a new CURLM handle to use in all 'curl_multi' functions.
+ */
+CURL_EXTERN CURLM *curl_multi_init(void);
+
+/*
+ * Name: curl_multi_add_handle()
+ *
+ * Desc: add a standard curl handle to the multi stack
+ *
+ * Returns: CURLMcode type, general multi error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_add_handle(CURLM *multi_handle,
+ CURL *curl_handle);
+
+ /*
+ * Name: curl_multi_remove_handle()
+ *
+ * Desc: removes a curl handle from the multi stack again
+ *
+ * Returns: CURLMcode type, general multi error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
+ CURL *curl_handle);
+
+ /*
+ * Name: curl_multi_fdset()
+ *
+ * Desc: Ask curl for its fd_set sets. The app can use these to select() or
+ * poll() on. We want curl_multi_perform() called as soon as one of
+ * them are ready.
+ *
+ * Returns: CURLMcode type, general multi error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle,
+ fd_set *read_fd_set,
+ fd_set *write_fd_set,
+ fd_set *exc_fd_set,
+ int *max_fd);
+
+/*
+ * Name: curl_multi_wait()
+ *
+ * Desc: Poll on all fds within a CURLM set as well as any
+ * additional fds passed to the function.
+ *
+ * Returns: CURLMcode type, general multi error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_wait(CURLM *multi_handle,
+ struct curl_waitfd extra_fds[],
+ unsigned int extra_nfds,
+ int timeout_ms,
+ int *ret);
+
+/*
+ * Name: curl_multi_poll()
+ *
+ * Desc: Poll on all fds within a CURLM set as well as any
+ * additional fds passed to the function.
+ *
+ * Returns: CURLMcode type, general multi error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_poll(CURLM *multi_handle,
+ struct curl_waitfd extra_fds[],
+ unsigned int extra_nfds,
+ int timeout_ms,
+ int *ret);
+
+/*
+ * Name: curl_multi_wakeup()
+ *
+ * Desc: wakes up a sleeping curl_multi_poll call.
+ *
+ * Returns: CURLMcode type, general multi error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_wakeup(CURLM *multi_handle);
+
+ /*
+ * Name: curl_multi_perform()
+ *
+ * Desc: When the app thinks there's data available for curl it calls this
+ * function to read/write whatever there is right now. This returns
+ * as soon as the reads and writes are done. This function does not
+ * require that there actually is data available for reading or that
+ * data can be written, it can be called just in case. It returns
+ * the number of handles that still transfer data in the second
+ * argument's integer-pointer.
+ *
+ * Returns: CURLMcode type, general multi error code. *NOTE* that this only
+ * returns errors etc regarding the whole multi stack. There might
+ * still have occurred problems on individual transfers even when
+ * this returns OK.
+ */
+CURL_EXTERN CURLMcode curl_multi_perform(CURLM *multi_handle,
+ int *running_handles);
+
+ /*
+ * Name: curl_multi_cleanup()
+ *
+ * Desc: Cleans up and removes a whole multi stack. It does not free or
+ * touch any individual easy handles in any way. We need to define
+ * in what state those handles will be if this function is called
+ * in the middle of a transfer.
+ *
+ * Returns: CURLMcode type, general multi error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle);
+
+/*
+ * Name: curl_multi_info_read()
+ *
+ * Desc: Ask the multi handle if there's any messages/informationals from
+ * the individual transfers. Messages include informationals such as
+ * error code from the transfer or just the fact that a transfer is
+ * completed. More details on these should be written down as well.
+ *
+ * Repeated calls to this function will return a new struct each
+ * time, until a special "end of msgs" struct is returned as a signal
+ * that there is no more to get at this point.
+ *
+ * The data the returned pointer points to will not survive calling
+ * curl_multi_cleanup().
+ *
+ * The 'CURLMsg' struct is meant to be very simple and only contain
+ * very basic information. If more involved information is wanted,
+ * we will provide the particular "transfer handle" in that struct
+ * and that should/could/would be used in subsequent
+ * curl_easy_getinfo() calls (or similar). The point being that we
+ * must never expose complex structs to applications, as then we'll
+ * undoubtably get backwards compatibility problems in the future.
+ *
+ * Returns: A pointer to a filled-in struct, or NULL if it failed or ran out
+ * of structs. It also writes the number of messages left in the
+ * queue (after this read) in the integer the second argument points
+ * to.
+ */
+CURL_EXTERN CURLMsg *curl_multi_info_read(CURLM *multi_handle,
+ int *msgs_in_queue);
+
+/*
+ * Name: curl_multi_strerror()
+ *
+ * Desc: The curl_multi_strerror function may be used to turn a CURLMcode
+ * value into the equivalent human readable error string. This is
+ * useful for printing meaningful error messages.
+ *
+ * Returns: A pointer to a null-terminated error message.
+ */
+CURL_EXTERN const char *curl_multi_strerror(CURLMcode);
+
+/*
+ * Name: curl_multi_socket() and
+ * curl_multi_socket_all()
+ *
+ * Desc: An alternative version of curl_multi_perform() that allows the
+ * application to pass in one of the file descriptors that have been
+ * detected to have "action" on them and let libcurl perform.
+ * See man page for details.
+ */
+#define CURL_POLL_NONE 0
+#define CURL_POLL_IN 1
+#define CURL_POLL_OUT 2
+#define CURL_POLL_INOUT 3
+#define CURL_POLL_REMOVE 4
+
+#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD
+
+#define CURL_CSELECT_IN 0x01
+#define CURL_CSELECT_OUT 0x02
+#define CURL_CSELECT_ERR 0x04
+
+typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */
+ curl_socket_t s, /* socket */
+ int what, /* see above */
+ void *userp, /* private callback
+ pointer */
+ void *socketp); /* private socket
+ pointer */
+/*
+ * Name: curl_multi_timer_callback
+ *
+ * Desc: Called by libcurl whenever the library detects a change in the
+ * maximum number of milliseconds the app is allowed to wait before
+ * curl_multi_socket() or curl_multi_perform() must be called
+ * (to allow libcurl's timed events to take place).
+ *
+ * Returns: The callback should return zero.
+ */
+typedef int (*curl_multi_timer_callback)(CURLM *multi, /* multi handle */
+ long timeout_ms, /* see above */
+ void *userp); /* private callback
+ pointer */
+
+CURL_EXTERN CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s,
+ int *running_handles);
+
+CURL_EXTERN CURLMcode curl_multi_socket_action(CURLM *multi_handle,
+ curl_socket_t s,
+ int ev_bitmask,
+ int *running_handles);
+
+CURL_EXTERN CURLMcode curl_multi_socket_all(CURLM *multi_handle,
+ int *running_handles);
+
+#ifndef CURL_ALLOW_OLD_MULTI_SOCKET
+/* This macro below was added in 7.16.3 to push users who recompile to use
+ the new curl_multi_socket_action() instead of the old curl_multi_socket()
+*/
+#define curl_multi_socket(x,y,z) curl_multi_socket_action(x,y,0,z)
+#endif
+
+/*
+ * Name: curl_multi_timeout()
+ *
+ * Desc: Returns the maximum number of milliseconds the app is allowed to
+ * wait before curl_multi_socket() or curl_multi_perform() must be
+ * called (to allow libcurl's timed events to take place).
+ *
+ * Returns: CURLM error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_timeout(CURLM *multi_handle,
+ long *milliseconds);
+
+typedef enum {
+ /* This is the socket callback function pointer */
+ CURLOPT(CURLMOPT_SOCKETFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 1),
+
+ /* This is the argument passed to the socket callback */
+ CURLOPT(CURLMOPT_SOCKETDATA, CURLOPTTYPE_OBJECTPOINT, 2),
+
+ /* set to 1 to enable pipelining for this multi handle */
+ CURLOPT(CURLMOPT_PIPELINING, CURLOPTTYPE_LONG, 3),
+
+ /* This is the timer callback function pointer */
+ CURLOPT(CURLMOPT_TIMERFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 4),
+
+ /* This is the argument passed to the timer callback */
+ CURLOPT(CURLMOPT_TIMERDATA, CURLOPTTYPE_OBJECTPOINT, 5),
+
+ /* maximum number of entries in the connection cache */
+ CURLOPT(CURLMOPT_MAXCONNECTS, CURLOPTTYPE_LONG, 6),
+
+ /* maximum number of (pipelining) connections to one host */
+ CURLOPT(CURLMOPT_MAX_HOST_CONNECTIONS, CURLOPTTYPE_LONG, 7),
+
+ /* maximum number of requests in a pipeline */
+ CURLOPT(CURLMOPT_MAX_PIPELINE_LENGTH, CURLOPTTYPE_LONG, 8),
+
+ /* a connection with a content-length longer than this
+ will not be considered for pipelining */
+ CURLOPT(CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE, CURLOPTTYPE_OFF_T, 9),
+
+ /* a connection with a chunk length longer than this
+ will not be considered for pipelining */
+ CURLOPT(CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE, CURLOPTTYPE_OFF_T, 10),
+
+ /* a list of site names(+port) that are blocked from pipelining */
+ CURLOPT(CURLMOPT_PIPELINING_SITE_BL, CURLOPTTYPE_OBJECTPOINT, 11),
+
+ /* a list of server types that are blocked from pipelining */
+ CURLOPT(CURLMOPT_PIPELINING_SERVER_BL, CURLOPTTYPE_OBJECTPOINT, 12),
+
+ /* maximum number of open connections in total */
+ CURLOPT(CURLMOPT_MAX_TOTAL_CONNECTIONS, CURLOPTTYPE_LONG, 13),
+
+ /* This is the server push callback function pointer */
+ CURLOPT(CURLMOPT_PUSHFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 14),
+
+ /* This is the argument passed to the server push callback */
+ CURLOPT(CURLMOPT_PUSHDATA, CURLOPTTYPE_OBJECTPOINT, 15),
+
+ /* maximum number of concurrent streams to support on a connection */
+ CURLOPT(CURLMOPT_MAX_CONCURRENT_STREAMS, CURLOPTTYPE_LONG, 16),
+
+ CURLMOPT_LASTENTRY /* the last unused */
+} CURLMoption;
+
+
+/*
+ * Name: curl_multi_setopt()
+ *
+ * Desc: Sets options for the multi handle.
+ *
+ * Returns: CURLM error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle,
+ CURLMoption option, ...);
+
+
+/*
+ * Name: curl_multi_assign()
+ *
+ * Desc: This function sets an association in the multi handle between the
+ * given socket and a private pointer of the application. This is
+ * (only) useful for curl_multi_socket uses.
+ *
+ * Returns: CURLM error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle,
+ curl_socket_t sockfd, void *sockp);
+
+
+/*
+ * Name: curl_push_callback
+ *
+ * Desc: This callback gets called when a new stream is being pushed by the
+ * server. It approves or denies the new stream. It can also decide
+ * to completely fail the connection.
+ *
+ * Returns: CURL_PUSH_OK, CURL_PUSH_DENY or CURL_PUSH_ERROROUT
+ */
+#define CURL_PUSH_OK 0
+#define CURL_PUSH_DENY 1
+#define CURL_PUSH_ERROROUT 2 /* added in 7.72.0 */
+
+struct curl_pushheaders; /* forward declaration only */
+
+CURL_EXTERN char *curl_pushheader_bynum(struct curl_pushheaders *h,
+ size_t num);
+CURL_EXTERN char *curl_pushheader_byname(struct curl_pushheaders *h,
+ const char *name);
+
+typedef int (*curl_push_callback)(CURL *parent,
+ CURL *easy,
+ size_t num_headers,
+ struct curl_pushheaders *headers,
+ void *userp);
+
+#ifdef __cplusplus
+} /* end of extern "C" */
+#endif
+
+#endif
diff --git a/csgo2/libcurl/inc/curl/options.h b/csgo2/libcurl/inc/curl/options.h
new file mode 100644
index 0000000..14373b5
--- /dev/null
+++ b/csgo2/libcurl/inc/curl/options.h
@@ -0,0 +1,68 @@
+#ifndef CURLINC_OPTIONS_H
+#define CURLINC_OPTIONS_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2018 - 2020, Daniel Stenberg, , et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ CURLOT_LONG, /* long (a range of values) */
+ CURLOT_VALUES, /* (a defined set or bitmask) */
+ CURLOT_OFF_T, /* curl_off_t (a range of values) */
+ CURLOT_OBJECT, /* pointer (void *) */
+ CURLOT_STRING, /* (char * to zero terminated buffer) */
+ CURLOT_SLIST, /* (struct curl_slist *) */
+ CURLOT_CBPTR, /* (void * passed as-is to a callback) */
+ CURLOT_BLOB, /* blob (struct curl_blob *) */
+ CURLOT_FUNCTION /* function pointer */
+} curl_easytype;
+
+/* Flag bits */
+
+/* "alias" means it is provided for old programs to remain functional,
+ we prefer another name */
+#define CURLOT_FLAG_ALIAS (1<<0)
+
+/* The CURLOPTTYPE_* id ranges can still be used to figure out what type/size
+ to use for curl_easy_setopt() for the given id */
+struct curl_easyoption {
+ const char *name;
+ CURLoption id;
+ curl_easytype type;
+ unsigned int flags;
+};
+
+CURL_EXTERN const struct curl_easyoption *
+curl_easy_option_by_name(const char *name);
+
+CURL_EXTERN const struct curl_easyoption *
+curl_easy_option_by_id (CURLoption id);
+
+CURL_EXTERN const struct curl_easyoption *
+curl_easy_option_next(const struct curl_easyoption *prev);
+
+#ifdef __cplusplus
+} /* end of extern "C" */
+#endif
+#endif /* CURLINC_OPTIONS_H */
diff --git a/csgo2/libcurl/inc/curl/stdcheaders.h b/csgo2/libcurl/inc/curl/stdcheaders.h
new file mode 100644
index 0000000..60596c7
--- /dev/null
+++ b/csgo2/libcurl/inc/curl/stdcheaders.h
@@ -0,0 +1,33 @@
+#ifndef CURLINC_STDCHEADERS_H
+#define CURLINC_STDCHEADERS_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include
+
+size_t fread(void *, size_t, size_t, FILE *);
+size_t fwrite(const void *, size_t, size_t, FILE *);
+
+int strcasecmp(const char *, const char *);
+int strncasecmp(const char *, const char *, size_t);
+
+#endif /* CURLINC_STDCHEADERS_H */
diff --git a/csgo2/libcurl/inc/curl/system.h b/csgo2/libcurl/inc/curl/system.h
new file mode 100644
index 0000000..faf8fcf
--- /dev/null
+++ b/csgo2/libcurl/inc/curl/system.h
@@ -0,0 +1,504 @@
+#ifndef CURLINC_SYSTEM_H
+#define CURLINC_SYSTEM_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Try to keep one section per platform, compiler and architecture, otherwise,
+ * if an existing section is reused for a different one and later on the
+ * original is adjusted, probably the piggybacking one can be adversely
+ * changed.
+ *
+ * In order to differentiate between platforms/compilers/architectures use
+ * only compiler built in predefined preprocessor symbols.
+ *
+ * curl_off_t
+ * ----------
+ *
+ * For any given platform/compiler curl_off_t must be typedef'ed to a 64-bit
+ * wide signed integral data type. The width of this data type must remain
+ * constant and independent of any possible large file support settings.
+ *
+ * As an exception to the above, curl_off_t shall be typedef'ed to a 32-bit
+ * wide signed integral data type if there is no 64-bit type.
+ *
+ * As a general rule, curl_off_t shall not be mapped to off_t. This rule shall
+ * only be violated if off_t is the only 64-bit data type available and the
+ * size of off_t is independent of large file support settings. Keep your
+ * build on the safe side avoiding an off_t gating. If you have a 64-bit
+ * off_t then take for sure that another 64-bit data type exists, dig deeper
+ * and you will find it.
+ *
+ */
+
+#if defined(__DJGPP__) || defined(__GO32__)
+# if defined(__DJGPP__) && (__DJGPP__ > 1)
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# else
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# endif
+# define CURL_TYPEOF_CURL_SOCKLEN_T int
+
+#elif defined(__SALFORDC__)
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# define CURL_TYPEOF_CURL_SOCKLEN_T int
+
+#elif defined(__BORLANDC__)
+# if (__BORLANDC__ < 0x520)
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# else
+# define CURL_TYPEOF_CURL_OFF_T __int64
+# define CURL_FORMAT_CURL_OFF_T "I64d"
+# define CURL_FORMAT_CURL_OFF_TU "I64u"
+# define CURL_SUFFIX_CURL_OFF_T i64
+# define CURL_SUFFIX_CURL_OFF_TU ui64
+# endif
+# define CURL_TYPEOF_CURL_SOCKLEN_T int
+
+#elif defined(__TURBOC__)
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# define CURL_TYPEOF_CURL_SOCKLEN_T int
+
+#elif defined(__WATCOMC__)
+# if defined(__386__)
+# define CURL_TYPEOF_CURL_OFF_T __int64
+# define CURL_FORMAT_CURL_OFF_T "I64d"
+# define CURL_FORMAT_CURL_OFF_TU "I64u"
+# define CURL_SUFFIX_CURL_OFF_T i64
+# define CURL_SUFFIX_CURL_OFF_TU ui64
+# else
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# endif
+# define CURL_TYPEOF_CURL_SOCKLEN_T int
+
+#elif defined(__POCC__)
+# if (__POCC__ < 280)
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# elif defined(_MSC_VER)
+# define CURL_TYPEOF_CURL_OFF_T __int64
+# define CURL_FORMAT_CURL_OFF_T "I64d"
+# define CURL_FORMAT_CURL_OFF_TU "I64u"
+# define CURL_SUFFIX_CURL_OFF_T i64
+# define CURL_SUFFIX_CURL_OFF_TU ui64
+# else
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# endif
+# define CURL_TYPEOF_CURL_SOCKLEN_T int
+
+#elif defined(__LCC__)
+# if defined(__e2k__) /* MCST eLbrus C Compiler */
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+# define CURL_PULL_SYS_TYPES_H 1
+# define CURL_PULL_SYS_SOCKET_H 1
+# else /* Local (or Little) C Compiler */
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# define CURL_TYPEOF_CURL_SOCKLEN_T int
+# endif
+
+#elif defined(__SYMBIAN32__)
+# if defined(__EABI__) /* Treat all ARM compilers equally */
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# elif defined(__CW32__)
+# pragma longlong on
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# elif defined(__VC32__)
+# define CURL_TYPEOF_CURL_OFF_T __int64
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# endif
+# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int
+
+#elif defined(__MWERKS__)
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# define CURL_TYPEOF_CURL_SOCKLEN_T int
+
+#elif defined(_WIN32_WCE)
+# define CURL_TYPEOF_CURL_OFF_T __int64
+# define CURL_FORMAT_CURL_OFF_T "I64d"
+# define CURL_FORMAT_CURL_OFF_TU "I64u"
+# define CURL_SUFFIX_CURL_OFF_T i64
+# define CURL_SUFFIX_CURL_OFF_TU ui64
+# define CURL_TYPEOF_CURL_SOCKLEN_T int
+
+#elif defined(__MINGW32__)
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "I64d"
+# define CURL_FORMAT_CURL_OFF_TU "I64u"
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+# define CURL_PULL_SYS_TYPES_H 1
+# define CURL_PULL_WS2TCPIP_H 1
+
+#elif defined(__VMS)
+# if defined(__VAX)
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# else
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# endif
+# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int
+
+#elif defined(__OS400__)
+# if defined(__ILEC400__)
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+# define CURL_PULL_SYS_TYPES_H 1
+# define CURL_PULL_SYS_SOCKET_H 1
+# endif
+
+#elif defined(__MVS__)
+# if defined(__IBMC__) || defined(__IBMCPP__)
+# if defined(_ILP32)
+# elif defined(_LP64)
+# endif
+# if defined(_LONG_LONG)
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# elif defined(_LP64)
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# else
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# endif
+# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+# define CURL_PULL_SYS_TYPES_H 1
+# define CURL_PULL_SYS_SOCKET_H 1
+# endif
+
+#elif defined(__370__)
+# if defined(__IBMC__) || defined(__IBMCPP__)
+# if defined(_ILP32)
+# elif defined(_LP64)
+# endif
+# if defined(_LONG_LONG)
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# elif defined(_LP64)
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# else
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# endif
+# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+# define CURL_PULL_SYS_TYPES_H 1
+# define CURL_PULL_SYS_SOCKET_H 1
+# endif
+
+#elif defined(TPF)
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# define CURL_TYPEOF_CURL_SOCKLEN_T int
+
+#elif defined(__TINYC__) /* also known as tcc */
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+# define CURL_PULL_SYS_TYPES_H 1
+# define CURL_PULL_SYS_SOCKET_H 1
+
+#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) /* Oracle Solaris Studio */
+# if !defined(__LP64) && (defined(__ILP32) || \
+ defined(__i386) || \
+ defined(__sparcv8) || \
+ defined(__sparcv8plus))
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# elif defined(__LP64) || \
+ defined(__amd64) || defined(__sparcv9)
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# endif
+# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+# define CURL_PULL_SYS_TYPES_H 1
+# define CURL_PULL_SYS_SOCKET_H 1
+
+#elif defined(__xlc__) /* IBM xlc compiler */
+# if !defined(_LP64)
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# else
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# endif
+# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+# define CURL_PULL_SYS_TYPES_H 1
+# define CURL_PULL_SYS_SOCKET_H 1
+
+/* ===================================== */
+/* KEEP MSVC THE PENULTIMATE ENTRY */
+/* ===================================== */
+
+#elif defined(_MSC_VER)
+# if (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64)
+# define CURL_TYPEOF_CURL_OFF_T __int64
+# define CURL_FORMAT_CURL_OFF_T "I64d"
+# define CURL_FORMAT_CURL_OFF_TU "I64u"
+# define CURL_SUFFIX_CURL_OFF_T i64
+# define CURL_SUFFIX_CURL_OFF_TU ui64
+# else
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# endif
+# define CURL_TYPEOF_CURL_SOCKLEN_T int
+
+/* ===================================== */
+/* KEEP GENERIC GCC THE LAST ENTRY */
+/* ===================================== */
+
+#elif defined(__GNUC__) && !defined(_SCO_DS)
+# if !defined(__LP64__) && \
+ (defined(__ILP32__) || defined(__i386__) || defined(__hppa__) || \
+ defined(__ppc__) || defined(__powerpc__) || defined(__arm__) || \
+ defined(__sparc__) || defined(__mips__) || defined(__sh__) || \
+ defined(__XTENSA__) || \
+ (defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ == 4) || \
+ (defined(__LONG_MAX__) && __LONG_MAX__ == 2147483647L))
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# elif defined(__LP64__) || \
+ defined(__x86_64__) || defined(__ppc64__) || defined(__sparc64__) || \
+ defined(__e2k__) || \
+ (defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ == 8) || \
+ (defined(__LONG_MAX__) && __LONG_MAX__ == 9223372036854775807L)
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# endif
+# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+# define CURL_PULL_SYS_TYPES_H 1
+# define CURL_PULL_SYS_SOCKET_H 1
+
+#else
+/* generic "safe guess" on old 32 bit style */
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# define CURL_TYPEOF_CURL_SOCKLEN_T int
+#endif
+
+#ifdef _AIX
+/* AIX needs */
+#define CURL_PULL_SYS_POLL_H
+#endif
+
+
+/* CURL_PULL_WS2TCPIP_H is defined above when inclusion of header file */
+/* ws2tcpip.h is required here to properly make type definitions below. */
+#ifdef CURL_PULL_WS2TCPIP_H
+# include
+# include
+# include
+#endif
+
+/* CURL_PULL_SYS_TYPES_H is defined above when inclusion of header file */
+/* sys/types.h is required here to properly make type definitions below. */
+#ifdef CURL_PULL_SYS_TYPES_H
+# include
+#endif
+
+/* CURL_PULL_SYS_SOCKET_H is defined above when inclusion of header file */
+/* sys/socket.h is required here to properly make type definitions below. */
+#ifdef CURL_PULL_SYS_SOCKET_H
+# include
+#endif
+
+/* CURL_PULL_SYS_POLL_H is defined above when inclusion of header file */
+/* sys/poll.h is required here to properly make type definitions below. */
+#ifdef CURL_PULL_SYS_POLL_H
+# include
+#endif
+
+/* Data type definition of curl_socklen_t. */
+#ifdef CURL_TYPEOF_CURL_SOCKLEN_T
+ typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t;
+#endif
+
+/* Data type definition of curl_off_t. */
+
+#ifdef CURL_TYPEOF_CURL_OFF_T
+ typedef CURL_TYPEOF_CURL_OFF_T curl_off_t;
+#endif
+
+/*
+ * CURL_ISOCPP and CURL_OFF_T_C definitions are done here in order to allow
+ * these to be visible and exported by the external libcurl interface API,
+ * while also making them visible to the library internals, simply including
+ * curl_setup.h, without actually needing to include curl.h internally.
+ * If some day this section would grow big enough, all this should be moved
+ * to its own header file.
+ */
+
+/*
+ * Figure out if we can use the ## preprocessor operator, which is supported
+ * by ISO/ANSI C and C++. Some compilers support it without setting __STDC__
+ * or __cplusplus so we need to carefully check for them too.
+ */
+
+#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \
+ defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \
+ defined(__POCC__) || defined(__SALFORDC__) || defined(__HIGHC__) || \
+ defined(__ILEC400__)
+ /* This compiler is believed to have an ISO compatible preprocessor */
+#define CURL_ISOCPP
+#else
+ /* This compiler is believed NOT to have an ISO compatible preprocessor */
+#undef CURL_ISOCPP
+#endif
+
+/*
+ * Macros for minimum-width signed and unsigned curl_off_t integer constants.
+ */
+
+#if defined(__BORLANDC__) && (__BORLANDC__ == 0x0551)
+# define CURLINC_OFF_T_C_HLPR2(x) x
+# define CURLINC_OFF_T_C_HLPR1(x) CURLINC_OFF_T_C_HLPR2(x)
+# define CURL_OFF_T_C(Val) CURLINC_OFF_T_C_HLPR1(Val) ## \
+ CURLINC_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_T)
+# define CURL_OFF_TU_C(Val) CURLINC_OFF_T_C_HLPR1(Val) ## \
+ CURLINC_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_TU)
+#else
+# ifdef CURL_ISOCPP
+# define CURLINC_OFF_T_C_HLPR2(Val,Suffix) Val ## Suffix
+# else
+# define CURLINC_OFF_T_C_HLPR2(Val,Suffix) Val/**/Suffix
+# endif
+# define CURLINC_OFF_T_C_HLPR1(Val,Suffix) CURLINC_OFF_T_C_HLPR2(Val,Suffix)
+# define CURL_OFF_T_C(Val) CURLINC_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_T)
+# define CURL_OFF_TU_C(Val) CURLINC_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_TU)
+#endif
+
+#endif /* CURLINC_SYSTEM_H */
diff --git a/csgo2/libcurl/inc/curl/typecheck-gcc.h b/csgo2/libcurl/inc/curl/typecheck-gcc.h
new file mode 100644
index 0000000..230f4c1
--- /dev/null
+++ b/csgo2/libcurl/inc/curl/typecheck-gcc.h
@@ -0,0 +1,705 @@
+#ifndef CURLINC_TYPECHECK_GCC_H
+#define CURLINC_TYPECHECK_GCC_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* wraps curl_easy_setopt() with typechecking */
+
+/* To add a new kind of warning, add an
+ * if(curlcheck_sometype_option(_curl_opt))
+ * if(!curlcheck_sometype(value))
+ * _curl_easy_setopt_err_sometype();
+ * block and define curlcheck_sometype_option, curlcheck_sometype and
+ * _curl_easy_setopt_err_sometype below
+ *
+ * NOTE: We use two nested 'if' statements here instead of the && operator, in
+ * order to work around gcc bug #32061. It affects only gcc 4.3.x/4.4.x
+ * when compiling with -Wlogical-op.
+ *
+ * To add an option that uses the same type as an existing option, you'll just
+ * need to extend the appropriate _curl_*_option macro
+ */
+#define curl_easy_setopt(handle, option, value) \
+ __extension__({ \
+ __typeof__(option) _curl_opt = option; \
+ if(__builtin_constant_p(_curl_opt)) { \
+ if(curlcheck_long_option(_curl_opt)) \
+ if(!curlcheck_long(value)) \
+ _curl_easy_setopt_err_long(); \
+ if(curlcheck_off_t_option(_curl_opt)) \
+ if(!curlcheck_off_t(value)) \
+ _curl_easy_setopt_err_curl_off_t(); \
+ if(curlcheck_string_option(_curl_opt)) \
+ if(!curlcheck_string(value)) \
+ _curl_easy_setopt_err_string(); \
+ if(curlcheck_write_cb_option(_curl_opt)) \
+ if(!curlcheck_write_cb(value)) \
+ _curl_easy_setopt_err_write_callback(); \
+ if((_curl_opt) == CURLOPT_RESOLVER_START_FUNCTION) \
+ if(!curlcheck_resolver_start_callback(value)) \
+ _curl_easy_setopt_err_resolver_start_callback(); \
+ if((_curl_opt) == CURLOPT_READFUNCTION) \
+ if(!curlcheck_read_cb(value)) \
+ _curl_easy_setopt_err_read_cb(); \
+ if((_curl_opt) == CURLOPT_IOCTLFUNCTION) \
+ if(!curlcheck_ioctl_cb(value)) \
+ _curl_easy_setopt_err_ioctl_cb(); \
+ if((_curl_opt) == CURLOPT_SOCKOPTFUNCTION) \
+ if(!curlcheck_sockopt_cb(value)) \
+ _curl_easy_setopt_err_sockopt_cb(); \
+ if((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION) \
+ if(!curlcheck_opensocket_cb(value)) \
+ _curl_easy_setopt_err_opensocket_cb(); \
+ if((_curl_opt) == CURLOPT_PROGRESSFUNCTION) \
+ if(!curlcheck_progress_cb(value)) \
+ _curl_easy_setopt_err_progress_cb(); \
+ if((_curl_opt) == CURLOPT_DEBUGFUNCTION) \
+ if(!curlcheck_debug_cb(value)) \
+ _curl_easy_setopt_err_debug_cb(); \
+ if((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION) \
+ if(!curlcheck_ssl_ctx_cb(value)) \
+ _curl_easy_setopt_err_ssl_ctx_cb(); \
+ if(curlcheck_conv_cb_option(_curl_opt)) \
+ if(!curlcheck_conv_cb(value)) \
+ _curl_easy_setopt_err_conv_cb(); \
+ if((_curl_opt) == CURLOPT_SEEKFUNCTION) \
+ if(!curlcheck_seek_cb(value)) \
+ _curl_easy_setopt_err_seek_cb(); \
+ if(curlcheck_cb_data_option(_curl_opt)) \
+ if(!curlcheck_cb_data(value)) \
+ _curl_easy_setopt_err_cb_data(); \
+ if((_curl_opt) == CURLOPT_ERRORBUFFER) \
+ if(!curlcheck_error_buffer(value)) \
+ _curl_easy_setopt_err_error_buffer(); \
+ if((_curl_opt) == CURLOPT_STDERR) \
+ if(!curlcheck_FILE(value)) \
+ _curl_easy_setopt_err_FILE(); \
+ if(curlcheck_postfields_option(_curl_opt)) \
+ if(!curlcheck_postfields(value)) \
+ _curl_easy_setopt_err_postfields(); \
+ if((_curl_opt) == CURLOPT_HTTPPOST) \
+ if(!curlcheck_arr((value), struct curl_httppost)) \
+ _curl_easy_setopt_err_curl_httpost(); \
+ if((_curl_opt) == CURLOPT_MIMEPOST) \
+ if(!curlcheck_ptr((value), curl_mime)) \
+ _curl_easy_setopt_err_curl_mimepost(); \
+ if(curlcheck_slist_option(_curl_opt)) \
+ if(!curlcheck_arr((value), struct curl_slist)) \
+ _curl_easy_setopt_err_curl_slist(); \
+ if((_curl_opt) == CURLOPT_SHARE) \
+ if(!curlcheck_ptr((value), CURLSH)) \
+ _curl_easy_setopt_err_CURLSH(); \
+ } \
+ curl_easy_setopt(handle, _curl_opt, value); \
+ })
+
+/* wraps curl_easy_getinfo() with typechecking */
+#define curl_easy_getinfo(handle, info, arg) \
+ __extension__({ \
+ __typeof__(info) _curl_info = info; \
+ if(__builtin_constant_p(_curl_info)) { \
+ if(curlcheck_string_info(_curl_info)) \
+ if(!curlcheck_arr((arg), char *)) \
+ _curl_easy_getinfo_err_string(); \
+ if(curlcheck_long_info(_curl_info)) \
+ if(!curlcheck_arr((arg), long)) \
+ _curl_easy_getinfo_err_long(); \
+ if(curlcheck_double_info(_curl_info)) \
+ if(!curlcheck_arr((arg), double)) \
+ _curl_easy_getinfo_err_double(); \
+ if(curlcheck_slist_info(_curl_info)) \
+ if(!curlcheck_arr((arg), struct curl_slist *)) \
+ _curl_easy_getinfo_err_curl_slist(); \
+ if(curlcheck_tlssessioninfo_info(_curl_info)) \
+ if(!curlcheck_arr((arg), struct curl_tlssessioninfo *)) \
+ _curl_easy_getinfo_err_curl_tlssesssioninfo(); \
+ if(curlcheck_certinfo_info(_curl_info)) \
+ if(!curlcheck_arr((arg), struct curl_certinfo *)) \
+ _curl_easy_getinfo_err_curl_certinfo(); \
+ if(curlcheck_socket_info(_curl_info)) \
+ if(!curlcheck_arr((arg), curl_socket_t)) \
+ _curl_easy_getinfo_err_curl_socket(); \
+ if(curlcheck_off_t_info(_curl_info)) \
+ if(!curlcheck_arr((arg), curl_off_t)) \
+ _curl_easy_getinfo_err_curl_off_t(); \
+ } \
+ curl_easy_getinfo(handle, _curl_info, arg); \
+ })
+
+/*
+ * For now, just make sure that the functions are called with three arguments
+ */
+#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param)
+#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param)
+
+
+/* the actual warnings, triggered by calling the _curl_easy_setopt_err*
+ * functions */
+
+/* To define a new warning, use _CURL_WARNING(identifier, "message") */
+#define CURLWARNING(id, message) \
+ static void __attribute__((__warning__(message))) \
+ __attribute__((__unused__)) __attribute__((__noinline__)) \
+ id(void) { __asm__(""); }
+
+CURLWARNING(_curl_easy_setopt_err_long,
+ "curl_easy_setopt expects a long argument for this option")
+CURLWARNING(_curl_easy_setopt_err_curl_off_t,
+ "curl_easy_setopt expects a curl_off_t argument for this option")
+CURLWARNING(_curl_easy_setopt_err_string,
+ "curl_easy_setopt expects a "
+ "string ('char *' or char[]) argument for this option"
+ )
+CURLWARNING(_curl_easy_setopt_err_write_callback,
+ "curl_easy_setopt expects a curl_write_callback argument for this option")
+CURLWARNING(_curl_easy_setopt_err_resolver_start_callback,
+ "curl_easy_setopt expects a "
+ "curl_resolver_start_callback argument for this option"
+ )
+CURLWARNING(_curl_easy_setopt_err_read_cb,
+ "curl_easy_setopt expects a curl_read_callback argument for this option")
+CURLWARNING(_curl_easy_setopt_err_ioctl_cb,
+ "curl_easy_setopt expects a curl_ioctl_callback argument for this option")
+CURLWARNING(_curl_easy_setopt_err_sockopt_cb,
+ "curl_easy_setopt expects a curl_sockopt_callback argument for this option")
+CURLWARNING(_curl_easy_setopt_err_opensocket_cb,
+ "curl_easy_setopt expects a "
+ "curl_opensocket_callback argument for this option"
+ )
+CURLWARNING(_curl_easy_setopt_err_progress_cb,
+ "curl_easy_setopt expects a curl_progress_callback argument for this option")
+CURLWARNING(_curl_easy_setopt_err_debug_cb,
+ "curl_easy_setopt expects a curl_debug_callback argument for this option")
+CURLWARNING(_curl_easy_setopt_err_ssl_ctx_cb,
+ "curl_easy_setopt expects a curl_ssl_ctx_callback argument for this option")
+CURLWARNING(_curl_easy_setopt_err_conv_cb,
+ "curl_easy_setopt expects a curl_conv_callback argument for this option")
+CURLWARNING(_curl_easy_setopt_err_seek_cb,
+ "curl_easy_setopt expects a curl_seek_callback argument for this option")
+CURLWARNING(_curl_easy_setopt_err_cb_data,
+ "curl_easy_setopt expects a "
+ "private data pointer as argument for this option")
+CURLWARNING(_curl_easy_setopt_err_error_buffer,
+ "curl_easy_setopt expects a "
+ "char buffer of CURL_ERROR_SIZE as argument for this option")
+CURLWARNING(_curl_easy_setopt_err_FILE,
+ "curl_easy_setopt expects a 'FILE *' argument for this option")
+CURLWARNING(_curl_easy_setopt_err_postfields,
+ "curl_easy_setopt expects a 'void *' or 'char *' argument for this option")
+CURLWARNING(_curl_easy_setopt_err_curl_httpost,
+ "curl_easy_setopt expects a 'struct curl_httppost *' "
+ "argument for this option")
+CURLWARNING(_curl_easy_setopt_err_curl_mimepost,
+ "curl_easy_setopt expects a 'curl_mime *' "
+ "argument for this option")
+CURLWARNING(_curl_easy_setopt_err_curl_slist,
+ "curl_easy_setopt expects a 'struct curl_slist *' argument for this option")
+CURLWARNING(_curl_easy_setopt_err_CURLSH,
+ "curl_easy_setopt expects a CURLSH* argument for this option")
+
+CURLWARNING(_curl_easy_getinfo_err_string,
+ "curl_easy_getinfo expects a pointer to 'char *' for this info")
+CURLWARNING(_curl_easy_getinfo_err_long,
+ "curl_easy_getinfo expects a pointer to long for this info")
+CURLWARNING(_curl_easy_getinfo_err_double,
+ "curl_easy_getinfo expects a pointer to double for this info")
+CURLWARNING(_curl_easy_getinfo_err_curl_slist,
+ "curl_easy_getinfo expects a pointer to 'struct curl_slist *' for this info")
+CURLWARNING(_curl_easy_getinfo_err_curl_tlssesssioninfo,
+ "curl_easy_getinfo expects a pointer to "
+ "'struct curl_tlssessioninfo *' for this info")
+CURLWARNING(_curl_easy_getinfo_err_curl_certinfo,
+ "curl_easy_getinfo expects a pointer to "
+ "'struct curl_certinfo *' for this info")
+CURLWARNING(_curl_easy_getinfo_err_curl_socket,
+ "curl_easy_getinfo expects a pointer to curl_socket_t for this info")
+CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
+ "curl_easy_getinfo expects a pointer to curl_off_t for this info")
+
+/* groups of curl_easy_setops options that take the same type of argument */
+
+/* To add a new option to one of the groups, just add
+ * (option) == CURLOPT_SOMETHING
+ * to the or-expression. If the option takes a long or curl_off_t, you don't
+ * have to do anything
+ */
+
+/* evaluates to true if option takes a long argument */
+#define curlcheck_long_option(option) \
+ (0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT)
+
+#define curlcheck_off_t_option(option) \
+ (((option) > CURLOPTTYPE_OFF_T) && ((option) < CURLOPTTYPE_BLOB))
+
+/* evaluates to true if option takes a char* argument */
+#define curlcheck_string_option(option) \
+ ((option) == CURLOPT_ABSTRACT_UNIX_SOCKET || \
+ (option) == CURLOPT_ACCEPT_ENCODING || \
+ (option) == CURLOPT_ALTSVC || \
+ (option) == CURLOPT_CAINFO || \
+ (option) == CURLOPT_CAPATH || \
+ (option) == CURLOPT_COOKIE || \
+ (option) == CURLOPT_COOKIEFILE || \
+ (option) == CURLOPT_COOKIEJAR || \
+ (option) == CURLOPT_COOKIELIST || \
+ (option) == CURLOPT_CRLFILE || \
+ (option) == CURLOPT_CUSTOMREQUEST || \
+ (option) == CURLOPT_DEFAULT_PROTOCOL || \
+ (option) == CURLOPT_DNS_INTERFACE || \
+ (option) == CURLOPT_DNS_LOCAL_IP4 || \
+ (option) == CURLOPT_DNS_LOCAL_IP6 || \
+ (option) == CURLOPT_DNS_SERVERS || \
+ (option) == CURLOPT_DOH_URL || \
+ (option) == CURLOPT_EGDSOCKET || \
+ (option) == CURLOPT_FTPPORT || \
+ (option) == CURLOPT_FTP_ACCOUNT || \
+ (option) == CURLOPT_FTP_ALTERNATIVE_TO_USER || \
+ (option) == CURLOPT_HSTS || \
+ (option) == CURLOPT_INTERFACE || \
+ (option) == CURLOPT_ISSUERCERT || \
+ (option) == CURLOPT_KEYPASSWD || \
+ (option) == CURLOPT_KRBLEVEL || \
+ (option) == CURLOPT_LOGIN_OPTIONS || \
+ (option) == CURLOPT_MAIL_AUTH || \
+ (option) == CURLOPT_MAIL_FROM || \
+ (option) == CURLOPT_NETRC_FILE || \
+ (option) == CURLOPT_NOPROXY || \
+ (option) == CURLOPT_PASSWORD || \
+ (option) == CURLOPT_PINNEDPUBLICKEY || \
+ (option) == CURLOPT_PRE_PROXY || \
+ (option) == CURLOPT_PROXY || \
+ (option) == CURLOPT_PROXYPASSWORD || \
+ (option) == CURLOPT_PROXYUSERNAME || \
+ (option) == CURLOPT_PROXYUSERPWD || \
+ (option) == CURLOPT_PROXY_CAINFO || \
+ (option) == CURLOPT_PROXY_CAPATH || \
+ (option) == CURLOPT_PROXY_CRLFILE || \
+ (option) == CURLOPT_PROXY_ISSUERCERT || \
+ (option) == CURLOPT_PROXY_KEYPASSWD || \
+ (option) == CURLOPT_PROXY_PINNEDPUBLICKEY || \
+ (option) == CURLOPT_PROXY_SERVICE_NAME || \
+ (option) == CURLOPT_PROXY_SSLCERT || \
+ (option) == CURLOPT_PROXY_SSLCERTTYPE || \
+ (option) == CURLOPT_PROXY_SSLKEY || \
+ (option) == CURLOPT_PROXY_SSLKEYTYPE || \
+ (option) == CURLOPT_PROXY_SSL_CIPHER_LIST || \
+ (option) == CURLOPT_PROXY_TLS13_CIPHERS || \
+ (option) == CURLOPT_PROXY_TLSAUTH_PASSWORD || \
+ (option) == CURLOPT_PROXY_TLSAUTH_TYPE || \
+ (option) == CURLOPT_PROXY_TLSAUTH_USERNAME || \
+ (option) == CURLOPT_RANDOM_FILE || \
+ (option) == CURLOPT_RANGE || \
+ (option) == CURLOPT_REFERER || \
+ (option) == CURLOPT_REQUEST_TARGET || \
+ (option) == CURLOPT_RTSP_SESSION_ID || \
+ (option) == CURLOPT_RTSP_STREAM_URI || \
+ (option) == CURLOPT_RTSP_TRANSPORT || \
+ (option) == CURLOPT_SASL_AUTHZID || \
+ (option) == CURLOPT_SERVICE_NAME || \
+ (option) == CURLOPT_SOCKS5_GSSAPI_SERVICE || \
+ (option) == CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 || \
+ (option) == CURLOPT_SSH_KNOWNHOSTS || \
+ (option) == CURLOPT_SSH_PRIVATE_KEYFILE || \
+ (option) == CURLOPT_SSH_PUBLIC_KEYFILE || \
+ (option) == CURLOPT_SSLCERT || \
+ (option) == CURLOPT_SSLCERTTYPE || \
+ (option) == CURLOPT_SSLENGINE || \
+ (option) == CURLOPT_SSLKEY || \
+ (option) == CURLOPT_SSLKEYTYPE || \
+ (option) == CURLOPT_SSL_CIPHER_LIST || \
+ (option) == CURLOPT_TLS13_CIPHERS || \
+ (option) == CURLOPT_TLSAUTH_PASSWORD || \
+ (option) == CURLOPT_TLSAUTH_TYPE || \
+ (option) == CURLOPT_TLSAUTH_USERNAME || \
+ (option) == CURLOPT_UNIX_SOCKET_PATH || \
+ (option) == CURLOPT_URL || \
+ (option) == CURLOPT_USERAGENT || \
+ (option) == CURLOPT_USERNAME || \
+ (option) == CURLOPT_AWS_SIGV4 || \
+ (option) == CURLOPT_USERPWD || \
+ (option) == CURLOPT_XOAUTH2_BEARER || \
+ (option) == CURLOPT_SSL_EC_CURVES || \
+ 0)
+
+/* evaluates to true if option takes a curl_write_callback argument */
+#define curlcheck_write_cb_option(option) \
+ ((option) == CURLOPT_HEADERFUNCTION || \
+ (option) == CURLOPT_WRITEFUNCTION)
+
+/* evaluates to true if option takes a curl_conv_callback argument */
+#define curlcheck_conv_cb_option(option) \
+ ((option) == CURLOPT_CONV_TO_NETWORK_FUNCTION || \
+ (option) == CURLOPT_CONV_FROM_NETWORK_FUNCTION || \
+ (option) == CURLOPT_CONV_FROM_UTF8_FUNCTION)
+
+/* evaluates to true if option takes a data argument to pass to a callback */
+#define curlcheck_cb_data_option(option) \
+ ((option) == CURLOPT_CHUNK_DATA || \
+ (option) == CURLOPT_CLOSESOCKETDATA || \
+ (option) == CURLOPT_DEBUGDATA || \
+ (option) == CURLOPT_FNMATCH_DATA || \
+ (option) == CURLOPT_HEADERDATA || \
+ (option) == CURLOPT_HSTSREADDATA || \
+ (option) == CURLOPT_HSTSWRITEDATA || \
+ (option) == CURLOPT_INTERLEAVEDATA || \
+ (option) == CURLOPT_IOCTLDATA || \
+ (option) == CURLOPT_OPENSOCKETDATA || \
+ (option) == CURLOPT_PROGRESSDATA || \
+ (option) == CURLOPT_READDATA || \
+ (option) == CURLOPT_SEEKDATA || \
+ (option) == CURLOPT_SOCKOPTDATA || \
+ (option) == CURLOPT_SSH_KEYDATA || \
+ (option) == CURLOPT_SSL_CTX_DATA || \
+ (option) == CURLOPT_WRITEDATA || \
+ (option) == CURLOPT_RESOLVER_START_DATA || \
+ (option) == CURLOPT_TRAILERDATA || \
+ 0)
+
+/* evaluates to true if option takes a POST data argument (void* or char*) */
+#define curlcheck_postfields_option(option) \
+ ((option) == CURLOPT_POSTFIELDS || \
+ (option) == CURLOPT_COPYPOSTFIELDS || \
+ 0)
+
+/* evaluates to true if option takes a struct curl_slist * argument */
+#define curlcheck_slist_option(option) \
+ ((option) == CURLOPT_HTTP200ALIASES || \
+ (option) == CURLOPT_HTTPHEADER || \
+ (option) == CURLOPT_MAIL_RCPT || \
+ (option) == CURLOPT_POSTQUOTE || \
+ (option) == CURLOPT_PREQUOTE || \
+ (option) == CURLOPT_PROXYHEADER || \
+ (option) == CURLOPT_QUOTE || \
+ (option) == CURLOPT_RESOLVE || \
+ (option) == CURLOPT_TELNETOPTIONS || \
+ (option) == CURLOPT_CONNECT_TO || \
+ 0)
+
+/* groups of curl_easy_getinfo infos that take the same type of argument */
+
+/* evaluates to true if info expects a pointer to char * argument */
+#define curlcheck_string_info(info) \
+ (CURLINFO_STRING < (info) && (info) < CURLINFO_LONG && \
+ (info) != CURLINFO_PRIVATE)
+
+/* evaluates to true if info expects a pointer to long argument */
+#define curlcheck_long_info(info) \
+ (CURLINFO_LONG < (info) && (info) < CURLINFO_DOUBLE)
+
+/* evaluates to true if info expects a pointer to double argument */
+#define curlcheck_double_info(info) \
+ (CURLINFO_DOUBLE < (info) && (info) < CURLINFO_SLIST)
+
+/* true if info expects a pointer to struct curl_slist * argument */
+#define curlcheck_slist_info(info) \
+ (((info) == CURLINFO_SSL_ENGINES) || ((info) == CURLINFO_COOKIELIST))
+
+/* true if info expects a pointer to struct curl_tlssessioninfo * argument */
+#define curlcheck_tlssessioninfo_info(info) \
+ (((info) == CURLINFO_TLS_SSL_PTR) || ((info) == CURLINFO_TLS_SESSION))
+
+/* true if info expects a pointer to struct curl_certinfo * argument */
+#define curlcheck_certinfo_info(info) ((info) == CURLINFO_CERTINFO)
+
+/* true if info expects a pointer to struct curl_socket_t argument */
+#define curlcheck_socket_info(info) \
+ (CURLINFO_SOCKET < (info) && (info) < CURLINFO_OFF_T)
+
+/* true if info expects a pointer to curl_off_t argument */
+#define curlcheck_off_t_info(info) \
+ (CURLINFO_OFF_T < (info))
+
+
+/* typecheck helpers -- check whether given expression has requested type*/
+
+/* For pointers, you can use the curlcheck_ptr/curlcheck_arr macros,
+ * otherwise define a new macro. Search for __builtin_types_compatible_p
+ * in the GCC manual.
+ * NOTE: these macros MUST NOT EVALUATE their arguments! The argument is
+ * the actual expression passed to the curl_easy_setopt macro. This
+ * means that you can only apply the sizeof and __typeof__ operators, no
+ * == or whatsoever.
+ */
+
+/* XXX: should evaluate to true if expr is a pointer */
+#define curlcheck_any_ptr(expr) \
+ (sizeof(expr) == sizeof(void *))
+
+/* evaluates to true if expr is NULL */
+/* XXX: must not evaluate expr, so this check is not accurate */
+#define curlcheck_NULL(expr) \
+ (__builtin_types_compatible_p(__typeof__(expr), __typeof__(NULL)))
+
+/* evaluates to true if expr is type*, const type* or NULL */
+#define curlcheck_ptr(expr, type) \
+ (curlcheck_NULL(expr) || \
+ __builtin_types_compatible_p(__typeof__(expr), type *) || \
+ __builtin_types_compatible_p(__typeof__(expr), const type *))
+
+/* evaluates to true if expr is one of type[], type*, NULL or const type* */
+#define curlcheck_arr(expr, type) \
+ (curlcheck_ptr((expr), type) || \
+ __builtin_types_compatible_p(__typeof__(expr), type []))
+
+/* evaluates to true if expr is a string */
+#define curlcheck_string(expr) \
+ (curlcheck_arr((expr), char) || \
+ curlcheck_arr((expr), signed char) || \
+ curlcheck_arr((expr), unsigned char))
+
+/* evaluates to true if expr is a long (no matter the signedness)
+ * XXX: for now, int is also accepted (and therefore short and char, which
+ * are promoted to int when passed to a variadic function) */
+#define curlcheck_long(expr) \
+ (__builtin_types_compatible_p(__typeof__(expr), long) || \
+ __builtin_types_compatible_p(__typeof__(expr), signed long) || \
+ __builtin_types_compatible_p(__typeof__(expr), unsigned long) || \
+ __builtin_types_compatible_p(__typeof__(expr), int) || \
+ __builtin_types_compatible_p(__typeof__(expr), signed int) || \
+ __builtin_types_compatible_p(__typeof__(expr), unsigned int) || \
+ __builtin_types_compatible_p(__typeof__(expr), short) || \
+ __builtin_types_compatible_p(__typeof__(expr), signed short) || \
+ __builtin_types_compatible_p(__typeof__(expr), unsigned short) || \
+ __builtin_types_compatible_p(__typeof__(expr), char) || \
+ __builtin_types_compatible_p(__typeof__(expr), signed char) || \
+ __builtin_types_compatible_p(__typeof__(expr), unsigned char))
+
+/* evaluates to true if expr is of type curl_off_t */
+#define curlcheck_off_t(expr) \
+ (__builtin_types_compatible_p(__typeof__(expr), curl_off_t))
+
+/* evaluates to true if expr is abuffer suitable for CURLOPT_ERRORBUFFER */
+/* XXX: also check size of an char[] array? */
+#define curlcheck_error_buffer(expr) \
+ (curlcheck_NULL(expr) || \
+ __builtin_types_compatible_p(__typeof__(expr), char *) || \
+ __builtin_types_compatible_p(__typeof__(expr), char[]))
+
+/* evaluates to true if expr is of type (const) void* or (const) FILE* */
+#if 0
+#define curlcheck_cb_data(expr) \
+ (curlcheck_ptr((expr), void) || \
+ curlcheck_ptr((expr), FILE))
+#else /* be less strict */
+#define curlcheck_cb_data(expr) \
+ curlcheck_any_ptr(expr)
+#endif
+
+/* evaluates to true if expr is of type FILE* */
+#define curlcheck_FILE(expr) \
+ (curlcheck_NULL(expr) || \
+ (__builtin_types_compatible_p(__typeof__(expr), FILE *)))
+
+/* evaluates to true if expr can be passed as POST data (void* or char*) */
+#define curlcheck_postfields(expr) \
+ (curlcheck_ptr((expr), void) || \
+ curlcheck_arr((expr), char) || \
+ curlcheck_arr((expr), unsigned char))
+
+/* helper: __builtin_types_compatible_p distinguishes between functions and
+ * function pointers, hide it */
+#define curlcheck_cb_compatible(func, type) \
+ (__builtin_types_compatible_p(__typeof__(func), type) || \
+ __builtin_types_compatible_p(__typeof__(func) *, type))
+
+/* evaluates to true if expr is of type curl_resolver_start_callback */
+#define curlcheck_resolver_start_callback(expr) \
+ (curlcheck_NULL(expr) || \
+ curlcheck_cb_compatible((expr), curl_resolver_start_callback))
+
+/* evaluates to true if expr is of type curl_read_callback or "similar" */
+#define curlcheck_read_cb(expr) \
+ (curlcheck_NULL(expr) || \
+ curlcheck_cb_compatible((expr), __typeof__(fread) *) || \
+ curlcheck_cb_compatible((expr), curl_read_callback) || \
+ curlcheck_cb_compatible((expr), _curl_read_callback1) || \
+ curlcheck_cb_compatible((expr), _curl_read_callback2) || \
+ curlcheck_cb_compatible((expr), _curl_read_callback3) || \
+ curlcheck_cb_compatible((expr), _curl_read_callback4) || \
+ curlcheck_cb_compatible((expr), _curl_read_callback5) || \
+ curlcheck_cb_compatible((expr), _curl_read_callback6))
+typedef size_t (*_curl_read_callback1)(char *, size_t, size_t, void *);
+typedef size_t (*_curl_read_callback2)(char *, size_t, size_t, const void *);
+typedef size_t (*_curl_read_callback3)(char *, size_t, size_t, FILE *);
+typedef size_t (*_curl_read_callback4)(void *, size_t, size_t, void *);
+typedef size_t (*_curl_read_callback5)(void *, size_t, size_t, const void *);
+typedef size_t (*_curl_read_callback6)(void *, size_t, size_t, FILE *);
+
+/* evaluates to true if expr is of type curl_write_callback or "similar" */
+#define curlcheck_write_cb(expr) \
+ (curlcheck_read_cb(expr) || \
+ curlcheck_cb_compatible((expr), __typeof__(fwrite) *) || \
+ curlcheck_cb_compatible((expr), curl_write_callback) || \
+ curlcheck_cb_compatible((expr), _curl_write_callback1) || \
+ curlcheck_cb_compatible((expr), _curl_write_callback2) || \
+ curlcheck_cb_compatible((expr), _curl_write_callback3) || \
+ curlcheck_cb_compatible((expr), _curl_write_callback4) || \
+ curlcheck_cb_compatible((expr), _curl_write_callback5) || \
+ curlcheck_cb_compatible((expr), _curl_write_callback6))
+typedef size_t (*_curl_write_callback1)(const char *, size_t, size_t, void *);
+typedef size_t (*_curl_write_callback2)(const char *, size_t, size_t,
+ const void *);
+typedef size_t (*_curl_write_callback3)(const char *, size_t, size_t, FILE *);
+typedef size_t (*_curl_write_callback4)(const void *, size_t, size_t, void *);
+typedef size_t (*_curl_write_callback5)(const void *, size_t, size_t,
+ const void *);
+typedef size_t (*_curl_write_callback6)(const void *, size_t, size_t, FILE *);
+
+/* evaluates to true if expr is of type curl_ioctl_callback or "similar" */
+#define curlcheck_ioctl_cb(expr) \
+ (curlcheck_NULL(expr) || \
+ curlcheck_cb_compatible((expr), curl_ioctl_callback) || \
+ curlcheck_cb_compatible((expr), _curl_ioctl_callback1) || \
+ curlcheck_cb_compatible((expr), _curl_ioctl_callback2) || \
+ curlcheck_cb_compatible((expr), _curl_ioctl_callback3) || \
+ curlcheck_cb_compatible((expr), _curl_ioctl_callback4))
+typedef curlioerr (*_curl_ioctl_callback1)(CURL *, int, void *);
+typedef curlioerr (*_curl_ioctl_callback2)(CURL *, int, const void *);
+typedef curlioerr (*_curl_ioctl_callback3)(CURL *, curliocmd, void *);
+typedef curlioerr (*_curl_ioctl_callback4)(CURL *, curliocmd, const void *);
+
+/* evaluates to true if expr is of type curl_sockopt_callback or "similar" */
+#define curlcheck_sockopt_cb(expr) \
+ (curlcheck_NULL(expr) || \
+ curlcheck_cb_compatible((expr), curl_sockopt_callback) || \
+ curlcheck_cb_compatible((expr), _curl_sockopt_callback1) || \
+ curlcheck_cb_compatible((expr), _curl_sockopt_callback2))
+typedef int (*_curl_sockopt_callback1)(void *, curl_socket_t, curlsocktype);
+typedef int (*_curl_sockopt_callback2)(const void *, curl_socket_t,
+ curlsocktype);
+
+/* evaluates to true if expr is of type curl_opensocket_callback or
+ "similar" */
+#define curlcheck_opensocket_cb(expr) \
+ (curlcheck_NULL(expr) || \
+ curlcheck_cb_compatible((expr), curl_opensocket_callback) || \
+ curlcheck_cb_compatible((expr), _curl_opensocket_callback1) || \
+ curlcheck_cb_compatible((expr), _curl_opensocket_callback2) || \
+ curlcheck_cb_compatible((expr), _curl_opensocket_callback3) || \
+ curlcheck_cb_compatible((expr), _curl_opensocket_callback4))
+typedef curl_socket_t (*_curl_opensocket_callback1)
+ (void *, curlsocktype, struct curl_sockaddr *);
+typedef curl_socket_t (*_curl_opensocket_callback2)
+ (void *, curlsocktype, const struct curl_sockaddr *);
+typedef curl_socket_t (*_curl_opensocket_callback3)
+ (const void *, curlsocktype, struct curl_sockaddr *);
+typedef curl_socket_t (*_curl_opensocket_callback4)
+ (const void *, curlsocktype, const struct curl_sockaddr *);
+
+/* evaluates to true if expr is of type curl_progress_callback or "similar" */
+#define curlcheck_progress_cb(expr) \
+ (curlcheck_NULL(expr) || \
+ curlcheck_cb_compatible((expr), curl_progress_callback) || \
+ curlcheck_cb_compatible((expr), _curl_progress_callback1) || \
+ curlcheck_cb_compatible((expr), _curl_progress_callback2))
+typedef int (*_curl_progress_callback1)(void *,
+ double, double, double, double);
+typedef int (*_curl_progress_callback2)(const void *,
+ double, double, double, double);
+
+/* evaluates to true if expr is of type curl_debug_callback or "similar" */
+#define curlcheck_debug_cb(expr) \
+ (curlcheck_NULL(expr) || \
+ curlcheck_cb_compatible((expr), curl_debug_callback) || \
+ curlcheck_cb_compatible((expr), _curl_debug_callback1) || \
+ curlcheck_cb_compatible((expr), _curl_debug_callback2) || \
+ curlcheck_cb_compatible((expr), _curl_debug_callback3) || \
+ curlcheck_cb_compatible((expr), _curl_debug_callback4) || \
+ curlcheck_cb_compatible((expr), _curl_debug_callback5) || \
+ curlcheck_cb_compatible((expr), _curl_debug_callback6) || \
+ curlcheck_cb_compatible((expr), _curl_debug_callback7) || \
+ curlcheck_cb_compatible((expr), _curl_debug_callback8))
+typedef int (*_curl_debug_callback1) (CURL *,
+ curl_infotype, char *, size_t, void *);
+typedef int (*_curl_debug_callback2) (CURL *,
+ curl_infotype, char *, size_t, const void *);
+typedef int (*_curl_debug_callback3) (CURL *,
+ curl_infotype, const char *, size_t, void *);
+typedef int (*_curl_debug_callback4) (CURL *,
+ curl_infotype, const char *, size_t, const void *);
+typedef int (*_curl_debug_callback5) (CURL *,
+ curl_infotype, unsigned char *, size_t, void *);
+typedef int (*_curl_debug_callback6) (CURL *,
+ curl_infotype, unsigned char *, size_t, const void *);
+typedef int (*_curl_debug_callback7) (CURL *,
+ curl_infotype, const unsigned char *, size_t, void *);
+typedef int (*_curl_debug_callback8) (CURL *,
+ curl_infotype, const unsigned char *, size_t, const void *);
+
+/* evaluates to true if expr is of type curl_ssl_ctx_callback or "similar" */
+/* this is getting even messier... */
+#define curlcheck_ssl_ctx_cb(expr) \
+ (curlcheck_NULL(expr) || \
+ curlcheck_cb_compatible((expr), curl_ssl_ctx_callback) || \
+ curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback1) || \
+ curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback2) || \
+ curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback3) || \
+ curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback4) || \
+ curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback5) || \
+ curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback6) || \
+ curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback7) || \
+ curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback8))
+typedef CURLcode (*_curl_ssl_ctx_callback1)(CURL *, void *, void *);
+typedef CURLcode (*_curl_ssl_ctx_callback2)(CURL *, void *, const void *);
+typedef CURLcode (*_curl_ssl_ctx_callback3)(CURL *, const void *, void *);
+typedef CURLcode (*_curl_ssl_ctx_callback4)(CURL *, const void *,
+ const void *);
+#ifdef HEADER_SSL_H
+/* hack: if we included OpenSSL's ssl.h, we know about SSL_CTX
+ * this will of course break if we're included before OpenSSL headers...
+ */
+typedef CURLcode (*_curl_ssl_ctx_callback5)(CURL *, SSL_CTX, void *);
+typedef CURLcode (*_curl_ssl_ctx_callback6)(CURL *, SSL_CTX, const void *);
+typedef CURLcode (*_curl_ssl_ctx_callback7)(CURL *, const SSL_CTX, void *);
+typedef CURLcode (*_curl_ssl_ctx_callback8)(CURL *, const SSL_CTX,
+ const void *);
+#else
+typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback5;
+typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback6;
+typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback7;
+typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback8;
+#endif
+
+/* evaluates to true if expr is of type curl_conv_callback or "similar" */
+#define curlcheck_conv_cb(expr) \
+ (curlcheck_NULL(expr) || \
+ curlcheck_cb_compatible((expr), curl_conv_callback) || \
+ curlcheck_cb_compatible((expr), _curl_conv_callback1) || \
+ curlcheck_cb_compatible((expr), _curl_conv_callback2) || \
+ curlcheck_cb_compatible((expr), _curl_conv_callback3) || \
+ curlcheck_cb_compatible((expr), _curl_conv_callback4))
+typedef CURLcode (*_curl_conv_callback1)(char *, size_t length);
+typedef CURLcode (*_curl_conv_callback2)(const char *, size_t length);
+typedef CURLcode (*_curl_conv_callback3)(void *, size_t length);
+typedef CURLcode (*_curl_conv_callback4)(const void *, size_t length);
+
+/* evaluates to true if expr is of type curl_seek_callback or "similar" */
+#define curlcheck_seek_cb(expr) \
+ (curlcheck_NULL(expr) || \
+ curlcheck_cb_compatible((expr), curl_seek_callback) || \
+ curlcheck_cb_compatible((expr), _curl_seek_callback1) || \
+ curlcheck_cb_compatible((expr), _curl_seek_callback2))
+typedef CURLcode (*_curl_seek_callback1)(void *, curl_off_t, int);
+typedef CURLcode (*_curl_seek_callback2)(const void *, curl_off_t, int);
+
+
+#endif /* CURLINC_TYPECHECK_GCC_H */
diff --git a/csgo2/libcurl/inc/curl/urlapi.h b/csgo2/libcurl/inc/curl/urlapi.h
new file mode 100644
index 0000000..7343cb6
--- /dev/null
+++ b/csgo2/libcurl/inc/curl/urlapi.h
@@ -0,0 +1,125 @@
+#ifndef CURLINC_URLAPI_H
+#define CURLINC_URLAPI_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2018 - 2020, Daniel Stenberg, , et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* the error codes for the URL API */
+typedef enum {
+ CURLUE_OK,
+ CURLUE_BAD_HANDLE, /* 1 */
+ CURLUE_BAD_PARTPOINTER, /* 2 */
+ CURLUE_MALFORMED_INPUT, /* 3 */
+ CURLUE_BAD_PORT_NUMBER, /* 4 */
+ CURLUE_UNSUPPORTED_SCHEME, /* 5 */
+ CURLUE_URLDECODE, /* 6 */
+ CURLUE_OUT_OF_MEMORY, /* 7 */
+ CURLUE_USER_NOT_ALLOWED, /* 8 */
+ CURLUE_UNKNOWN_PART, /* 9 */
+ CURLUE_NO_SCHEME, /* 10 */
+ CURLUE_NO_USER, /* 11 */
+ CURLUE_NO_PASSWORD, /* 12 */
+ CURLUE_NO_OPTIONS, /* 13 */
+ CURLUE_NO_HOST, /* 14 */
+ CURLUE_NO_PORT, /* 15 */
+ CURLUE_NO_QUERY, /* 16 */
+ CURLUE_NO_FRAGMENT /* 17 */
+} CURLUcode;
+
+typedef enum {
+ CURLUPART_URL,
+ CURLUPART_SCHEME,
+ CURLUPART_USER,
+ CURLUPART_PASSWORD,
+ CURLUPART_OPTIONS,
+ CURLUPART_HOST,
+ CURLUPART_PORT,
+ CURLUPART_PATH,
+ CURLUPART_QUERY,
+ CURLUPART_FRAGMENT,
+ CURLUPART_ZONEID /* added in 7.65.0 */
+} CURLUPart;
+
+#define CURLU_DEFAULT_PORT (1<<0) /* return default port number */
+#define CURLU_NO_DEFAULT_PORT (1<<1) /* act as if no port number was set,
+ if the port number matches the
+ default for the scheme */
+#define CURLU_DEFAULT_SCHEME (1<<2) /* return default scheme if
+ missing */
+#define CURLU_NON_SUPPORT_SCHEME (1<<3) /* allow non-supported scheme */
+#define CURLU_PATH_AS_IS (1<<4) /* leave dot sequences */
+#define CURLU_DISALLOW_USER (1<<5) /* no user+password allowed */
+#define CURLU_URLDECODE (1<<6) /* URL decode on get */
+#define CURLU_URLENCODE (1<<7) /* URL encode on set */
+#define CURLU_APPENDQUERY (1<<8) /* append a form style part */
+#define CURLU_GUESS_SCHEME (1<<9) /* legacy curl-style guessing */
+#define CURLU_NO_AUTHORITY (1<<10) /* Allow empty authority when the
+ scheme is unknown. */
+
+typedef struct Curl_URL CURLU;
+
+/*
+ * curl_url() creates a new CURLU handle and returns a pointer to it.
+ * Must be freed with curl_url_cleanup().
+ */
+CURL_EXTERN CURLU *curl_url(void);
+
+/*
+ * curl_url_cleanup() frees the CURLU handle and related resources used for
+ * the URL parsing. It will not free strings previously returned with the URL
+ * API.
+ */
+CURL_EXTERN void curl_url_cleanup(CURLU *handle);
+
+/*
+ * curl_url_dup() duplicates a CURLU handle and returns a new copy. The new
+ * handle must also be freed with curl_url_cleanup().
+ */
+CURL_EXTERN CURLU *curl_url_dup(CURLU *in);
+
+/*
+ * curl_url_get() extracts a specific part of the URL from a CURLU
+ * handle. Returns error code. The returned pointer MUST be freed with
+ * curl_free() afterwards.
+ */
+CURL_EXTERN CURLUcode curl_url_get(CURLU *handle, CURLUPart what,
+ char **part, unsigned int flags);
+
+/*
+ * curl_url_set() sets a specific part of the URL in a CURLU handle. Returns
+ * error code. The passed in string will be copied. Passing a NULL instead of
+ * a part string, clears that part.
+ */
+CURL_EXTERN CURLUcode curl_url_set(CURLU *handle, CURLUPart what,
+ const char *part, unsigned int flags);
+
+
+#ifdef __cplusplus
+} /* end of extern "C" */
+#endif
+
+#endif /* CURLINC_URLAPI_H */
diff --git a/csgo2/libcurl/lib/_x32/_Debug/libcurld.lib b/csgo2/libcurl/lib/_x32/_Debug/libcurld.lib
new file mode 100644
index 0000000..7bcb49c
Binary files /dev/null and b/csgo2/libcurl/lib/_x32/_Debug/libcurld.lib differ
diff --git a/csgo2/libcurl/lib/_x32/_Debug/libeay32.lib b/csgo2/libcurl/lib/_x32/_Debug/libeay32.lib
new file mode 100644
index 0000000..b77abbf
Binary files /dev/null and b/csgo2/libcurl/lib/_x32/_Debug/libeay32.lib differ
diff --git a/csgo2/libcurl/lib/_x32/_Debug/ssleay32.lib b/csgo2/libcurl/lib/_x32/_Debug/ssleay32.lib
new file mode 100644
index 0000000..3d0ca36
Binary files /dev/null and b/csgo2/libcurl/lib/_x32/_Debug/ssleay32.lib differ
diff --git a/csgo2/libcurl/lib/_x32/_Release/libcurl.lib b/csgo2/libcurl/lib/_x32/_Release/libcurl.lib
new file mode 100644
index 0000000..0f5571b
Binary files /dev/null and b/csgo2/libcurl/lib/_x32/_Release/libcurl.lib differ
diff --git a/csgo2/libcurl/lib/_x32/_Release/libeay32.lib b/csgo2/libcurl/lib/_x32/_Release/libeay32.lib
new file mode 100644
index 0000000..6ba2cdb
Binary files /dev/null and b/csgo2/libcurl/lib/_x32/_Release/libeay32.lib differ
diff --git a/csgo2/libcurl/lib/_x32/_Release/ssleay32.lib b/csgo2/libcurl/lib/_x32/_Release/ssleay32.lib
new file mode 100644
index 0000000..94620fb
Binary files /dev/null and b/csgo2/libcurl/lib/_x32/_Release/ssleay32.lib differ
diff --git a/csgo2/libcurl/lib/_x64/_Debug/libcurld.lib b/csgo2/libcurl/lib/_x64/_Debug/libcurld.lib
new file mode 100644
index 0000000..07de944
Binary files /dev/null and b/csgo2/libcurl/lib/_x64/_Debug/libcurld.lib differ
diff --git a/csgo2/libcurl/lib/_x64/_Debug/libeay32.lib b/csgo2/libcurl/lib/_x64/_Debug/libeay32.lib
new file mode 100644
index 0000000..713a177
Binary files /dev/null and b/csgo2/libcurl/lib/_x64/_Debug/libeay32.lib differ
diff --git a/csgo2/libcurl/lib/_x64/_Debug/ssleay32.lib b/csgo2/libcurl/lib/_x64/_Debug/ssleay32.lib
new file mode 100644
index 0000000..c97e6f3
Binary files /dev/null and b/csgo2/libcurl/lib/_x64/_Debug/ssleay32.lib differ
diff --git a/csgo2/libcurl/lib/_x64/_Release/libcurl.lib b/csgo2/libcurl/lib/_x64/_Release/libcurl.lib
new file mode 100644
index 0000000..6fe4466
Binary files /dev/null and b/csgo2/libcurl/lib/_x64/_Release/libcurl.lib differ
diff --git a/csgo2/libcurl/lib/_x64/_Release/libeay32.lib b/csgo2/libcurl/lib/_x64/_Release/libeay32.lib
new file mode 100644
index 0000000..55aaaac
Binary files /dev/null and b/csgo2/libcurl/lib/_x64/_Release/libeay32.lib differ
diff --git a/csgo2/libcurl/lib/_x64/_Release/ssleay32.lib b/csgo2/libcurl/lib/_x64/_Release/ssleay32.lib
new file mode 100644
index 0000000..3390f04
Binary files /dev/null and b/csgo2/libcurl/lib/_x64/_Release/ssleay32.lib differ
diff --git a/csgo2/libcurl/libcurl.cpp b/csgo2/libcurl/libcurl.cpp
new file mode 100644
index 0000000..1b81c2f
--- /dev/null
+++ b/csgo2/libcurl/libcurl.cpp
@@ -0,0 +1,159 @@
+#include "libcurl.h"
+
+CRITICAL_SECTION curl_critical;
+
+size_t writer(char* data, size_t size, size_t nmemb, std::string* writer_data)
+{
+ size_t sizes = size * nmemb;
+
+ if (NULL == writer_data) {
+ return 0;
+ }
+
+ writer_data->append(data, sizes);
+ return sizes;
+}
+
+bool curl_get(std::string url, std::string* pbuffer, curl_slist* headers, bool tls, bool proxy)
+{
+ curl_code code;
+ curl_handle handle;
+
+ handle = curl_easy_init();
+ if (NULL == handle) {
+ return false;
+ }
+ code = curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, writer);
+ if (code != CURLE_OK) {
+ curl_easy_cleanup(handle);
+ return false;
+ }
+ code = curl_easy_setopt(handle, CURLOPT_WRITEDATA, pbuffer);
+ if (code != CURLE_OK) {
+ curl_easy_cleanup(handle);
+ return false;
+ }
+ if (tls) {
+ code = curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, false);
+ if (code != CURLE_OK) {
+ curl_easy_cleanup(handle);
+ return false;
+ }
+ code = curl_easy_setopt(handle, CURLOPT_SSL_VERIFYHOST, true);
+ if (code != CURLE_OK) {
+ curl_easy_cleanup(handle);
+ return false;
+ }
+ }
+ code = curl_easy_setopt(handle, CURLOPT_URL, url.c_str());
+ if (code != CURLE_OK) {
+ curl_easy_cleanup(handle);
+ return false;
+ }
+ code = curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers);
+ if (code != CURLE_OK) {
+ curl_easy_cleanup(handle);
+ return false;
+ }
+
+ if (proxy) {
+ curl_easy_setopt(handle, CURLOPT_PROXY, "127.0.0.1");
+ curl_easy_setopt(handle, CURLOPT_PROXYPORT, 7890);
+ curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5_HOSTNAME);
+ }
+
+ EnterCriticalSection(&curl_critical);
+ code = curl_easy_perform(handle);
+ LeaveCriticalSection(&curl_critical);
+
+ if (code != CURLE_OK) {
+ curl_easy_cleanup(handle);
+ return false;
+ }
+
+ curl_easy_cleanup(handle);
+ return true;
+}
+
+bool curl_post(std::string url, std::string* pbuffer, std::string data, curl_slist* headers, bool tls, bool proxy)
+{
+ curl_code code;
+ curl_handle handle;
+
+ handle = curl_easy_init();
+ if (NULL == handle) {
+ return false;
+ }
+ code = curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, writer);
+ if (code != CURLE_OK) {
+ curl_easy_cleanup(handle);
+ return false;
+ }
+ code = curl_easy_setopt(handle, CURLOPT_WRITEDATA, pbuffer);
+ if (code != CURLE_OK) {
+ curl_easy_cleanup(handle);
+ return false;
+ }
+ if (tls) {
+ code = curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, false);
+ if (code != CURLE_OK) {
+ curl_easy_cleanup(handle);
+ return false;
+ }
+ code = curl_easy_setopt(handle, CURLOPT_SSL_VERIFYHOST, true);
+ if (code != CURLE_OK) {
+ curl_easy_cleanup(handle);
+ return false;
+ }
+ }
+ code = curl_easy_setopt(handle, CURLOPT_POST, true);
+ if (code != CURLE_OK) {
+ curl_easy_cleanup(handle);
+ return false;
+ }
+ code = curl_easy_setopt(handle, CURLOPT_POSTFIELDS, data.c_str());
+ if (code != CURLE_OK) {
+ curl_easy_cleanup(handle);
+ return false;
+ }
+ code = curl_easy_setopt(handle, CURLOPT_URL, url.c_str());
+ if (code != CURLE_OK) {
+ curl_easy_cleanup(handle);
+ return false;
+ }
+ code = curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers);
+ if (code != CURLE_OK) {
+ curl_easy_cleanup(handle);
+ return false;
+ }
+
+ if (proxy) {
+ curl_easy_setopt(handle, CURLOPT_PROXY, "127.0.0.1");
+ curl_easy_setopt(handle, CURLOPT_PROXYPORT, 7890);
+ curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5_HOSTNAME);
+ }
+
+ EnterCriticalSection(&curl_critical);
+ code = curl_easy_perform(handle);
+ LeaveCriticalSection(&curl_critical);
+
+ if (code != CURLE_OK) {
+ curl_easy_cleanup(handle);
+ return false;
+ }
+
+ curl_easy_cleanup(handle);
+ return true;
+}
+
+void curl_init()
+{
+ InitializeCriticalSection(&curl_critical);
+ curl_global_init(CURL_GLOBAL_DEFAULT);
+}
+
+void curl_cleanup()
+{
+ curl_global_cleanup();
+ DeleteCriticalSection(&curl_critical);
+}
\ No newline at end of file
diff --git a/csgo2/libcurl/libcurl.h b/csgo2/libcurl/libcurl.h
new file mode 100644
index 0000000..3317c77
--- /dev/null
+++ b/csgo2/libcurl/libcurl.h
@@ -0,0 +1,42 @@
+#pragma once
+
+#include
+
+#define CURL_STATICLIB
+#include "inc/curl/curl.h"
+#pragma comment(lib,"crypt32.lib")
+#pragma comment(lib,"ws2_32.lib")
+#pragma comment(lib,"wldap32.lib")
+
+#ifndef _WIN64
+#ifdef _DEBUG
+#pragma comment(lib,"_x32/_Debug/libeay32.lib")
+#pragma comment(lib,"_x32/_Debug/ssleay32.lib")
+#pragma comment(lib,"_x32/_Debug/libcurld.lib")
+#else
+#pragma comment(lib,"_x32/_Release/libeay32.lib")
+#pragma comment(lib,"_x32/_Release/ssleay32.lib")
+#pragma comment(lib,"_x32/_Release/libcurl.lib")
+#endif
+#else
+#ifdef _DEBUG
+#pragma comment(lib,"_x64/_Debug/libeay32.lib")
+#pragma comment(lib,"_x64/_Debug/ssleay32.lib")
+#pragma comment(lib,"_x64/_Debug/libcurld.lib")
+#else
+#pragma comment(lib,"_x64/_Release/libeay32.lib")
+#pragma comment(lib,"_x64/_Release/ssleay32.lib")
+#pragma comment(lib,"_x64/_Release/libcurl.lib")
+#endif
+#endif
+
+extern "C" unsigned char* MD5(const unsigned char* d, size_t n, unsigned char* md);
+extern "C" unsigned char* SHA1(const unsigned char* d, size_t n, unsigned char* md);
+
+typedef CURL* curl_handle;
+typedef CURLcode curl_code;
+
+bool curl_get(std::string url, std::string* pbuffer, curl_slist* headers, bool tls, bool proxy);
+bool curl_post(std::string url, std::string* pbuffer, std::string data, curl_slist* headers, bool tls, bool proxy);
+void curl_init();
+void curl_cleanup();
\ No newline at end of file
diff --git a/csgo2/luaCjson/dtoa.c b/csgo2/luaCjson/dtoa.c
new file mode 100644
index 0000000..3dffa0d
--- /dev/null
+++ b/csgo2/luaCjson/dtoa.c
@@ -0,0 +1,6205 @@
+/****************************************************************
+ *
+ * The author of this software is David M. Gay.
+ *
+ * Copyright (c) 1991, 2000, 2001 by Lucent Technologies.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose without fee is hereby granted, provided that this entire notice
+ * is included in all copies of any software which is or includes a copy
+ * or modification of this software and in all copies of the supporting
+ * documentation for such software.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY
+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
+ * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
+ *
+ ***************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+/* On a machine with IEEE extended-precision registers, it is
+ * necessary to specify double-precision (53-bit) rounding precision
+ * before invoking strtod or dtoa. If the machine uses (the equivalent
+ * of) Intel 80x87 arithmetic, the call
+ * _control87(PC_53, MCW_PC);
+ * does this with many compilers. Whether this or another call is
+ * appropriate depends on the compiler; for this to work, it may be
+ * necessary to #include "float.h" or another system-dependent header
+ * file.
+ */
+
+/* strtod for IEEE-, VAX-, and IBM-arithmetic machines.
+ * (Note that IEEE arithmetic is disabled by gcc's -ffast-math flag.)
+ *
+ * This strtod returns a nearest machine number to the input decimal
+ * string (or sets errno to ERANGE). With IEEE arithmetic, ties are
+ * broken by the IEEE round-even rule. Otherwise ties are broken by
+ * biased rounding (add half and chop).
+ *
+ * Inspired loosely by William D. Clinger's paper "How to Read Floating
+ * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101].
+ *
+ * Modifications:
+ *
+ * 1. We only require IEEE, IBM, or VAX double-precision
+ * arithmetic (not IEEE double-extended).
+ * 2. We get by with floating-point arithmetic in a case that
+ * Clinger missed -- when we're computing d * 10^n
+ * for a small integer d and the integer n is not too
+ * much larger than 22 (the maximum integer k for which
+ * we can represent 10^k exactly), we may be able to
+ * compute (d*10^k) * 10^(e-k) with just one roundoff.
+ * 3. Rather than a bit-at-a-time adjustment of the binary
+ * result in the hard case, we use floating-point
+ * arithmetic to determine the adjustment to within
+ * one bit; only in really hard cases do we need to
+ * compute a second residual.
+ * 4. Because of 3., we don't need a large table of powers of 10
+ * for ten-to-e (just some small tables, e.g. of 10^k
+ * for 0 <= k <= 22).
+ */
+
+/*
+ * #define IEEE_8087 for IEEE-arithmetic machines where the least
+ * significant byte has the lowest address.
+ * #define IEEE_MC68k for IEEE-arithmetic machines where the most
+ * significant byte has the lowest address.
+ * #define Long int on machines with 32-bit ints and 64-bit longs.
+ * #define IBM for IBM mainframe-style floating-point arithmetic.
+ * #define VAX for VAX-style floating-point arithmetic (D_floating).
+ * #define No_leftright to omit left-right logic in fast floating-point
+ * computation of dtoa. This will cause dtoa modes 4 and 5 to be
+ * treated the same as modes 2 and 3 for some inputs.
+ * #define Honor_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3
+ * and strtod and dtoa should round accordingly. Unless Trust_FLT_ROUNDS
+ * is also #defined, fegetround() will be queried for the rounding mode.
+ * Note that both FLT_ROUNDS and fegetround() are specified by the C99
+ * standard (and are specified to be consistent, with fesetround()
+ * affecting the value of FLT_ROUNDS), but that some (Linux) systems
+ * do not work correctly in this regard, so using fegetround() is more
+ * portable than using FLT_ROUNDS directly.
+ * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3
+ * and Honor_FLT_ROUNDS is not #defined.
+ * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines
+ * that use extended-precision instructions to compute rounded
+ * products and quotients) with IBM.
+ * #define ROUND_BIASED for IEEE-format with biased rounding and arithmetic
+ * that rounds toward +Infinity.
+ * #define ROUND_BIASED_without_Round_Up for IEEE-format with biased
+ * rounding when the underlying floating-point arithmetic uses
+ * unbiased rounding. This prevent using ordinary floating-point
+ * arithmetic when the result could be computed with one rounding error.
+ * #define Inaccurate_Divide for IEEE-format with correctly rounded
+ * products but inaccurate quotients, e.g., for Intel i860.
+ * #define NO_LONG_LONG on machines that do not have a "long long"
+ * integer type (of >= 64 bits). On such machines, you can
+ * #define Just_16 to store 16 bits per 32-bit Long when doing
+ * high-precision integer arithmetic. Whether this speeds things
+ * up or slows things down depends on the machine and the number
+ * being converted. If long long is available and the name is
+ * something other than "long long", #define Llong to be the name,
+ * and if "unsigned Llong" does not work as an unsigned version of
+ * Llong, #define #ULLong to be the corresponding unsigned type.
+ * #define Bad_float_h if your system lacks a float.h or if it does not
+ * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP,
+ * FLT_RADIX, FLT_ROUNDS, and DBL_MAX.
+ * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n)
+ * if memory is available and otherwise does something you deem
+ * appropriate. If MALLOC is undefined, malloc will be invoked
+ * directly -- and assumed always to succeed. Similarly, if you
+ * want something other than the system's free() to be called to
+ * recycle memory acquired from MALLOC, #define FREE to be the
+ * name of the alternate routine. (FREE or free is only called in
+ * pathological cases, e.g., in a dtoa call after a dtoa return in
+ * mode 3 with thousands of digits requested.)
+ * #define Omit_Private_Memory to omit logic (added Jan. 1998) for making
+ * memory allocations from a private pool of memory when possible.
+ * When used, the private pool is PRIVATE_MEM bytes long: 2304 bytes,
+ * unless #defined to be a different length. This default length
+ * suffices to get rid of MALLOC calls except for unusual cases,
+ * such as decimal-to-binary conversion of a very long string of
+ * digits. The longest string dtoa can return is about 751 bytes
+ * long. For conversions by strtod of strings of 800 digits and
+ * all dtoa conversions in single-threaded executions with 8-byte
+ * pointers, PRIVATE_MEM >= 7400 appears to suffice; with 4-byte
+ * pointers, PRIVATE_MEM >= 7112 appears adequate.
+ * #define NO_INFNAN_CHECK if you do not wish to have INFNAN_CHECK
+ * #defined automatically on IEEE systems. On such systems,
+ * when INFNAN_CHECK is #defined, strtod checks
+ * for Infinity and NaN (case insensitively). On some systems
+ * (e.g., some HP systems), it may be necessary to #define NAN_WORD0
+ * appropriately -- to the most significant word of a quiet NaN.
+ * (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.)
+ * When INFNAN_CHECK is #defined and No_Hex_NaN is not #defined,
+ * strtod also accepts (case insensitively) strings of the form
+ * NaN(x), where x is a string of hexadecimal digits and spaces;
+ * if there is only one string of hexadecimal digits, it is taken
+ * for the 52 fraction bits of the resulting NaN; if there are two
+ * or more strings of hex digits, the first is for the high 20 bits,
+ * the second and subsequent for the low 32 bits, with intervening
+ * white space ignored; but if this results in none of the 52
+ * fraction bits being on (an IEEE Infinity symbol), then NAN_WORD0
+ * and NAN_WORD1 are used instead.
+ * #define MULTIPLE_THREADS if the system offers preemptively scheduled
+ * multiple threads. In this case, you must provide (or suitably
+ * #define) two locks, acquired by ACQUIRE_DTOA_LOCK(n) and freed
+ * by FREE_DTOA_LOCK(n) for n = 0 or 1. (The second lock, accessed
+ * in pow5mult, ensures lazy evaluation of only one copy of high
+ * powers of 5; omitting this lock would introduce a small
+ * probability of wasting memory, but would otherwise be harmless.)
+ * You must also invoke freedtoa(s) to free the value s returned by
+ * dtoa. You may do so whether or not MULTIPLE_THREADS is #defined.
+
+ * When MULTIPLE_THREADS is #defined, this source file provides
+ * void set_max_dtoa_threads(unsigned int n);
+ * and expects
+ * unsigned int dtoa_get_threadno(void);
+ * to be available (possibly provided by
+ * #define dtoa_get_threadno omp_get_thread_num
+ * if OpenMP is in use or by
+ * #define dtoa_get_threadno pthread_self
+ * if Pthreads is in use), to return the current thread number.
+ * If set_max_dtoa_threads(n) was called and the current thread
+ * number is k with k < n, then calls on ACQUIRE_DTOA_LOCK(...) and
+ * FREE_DTOA_LOCK(...) are avoided; instead each thread with thread
+ * number < n has a separate copy of relevant data structures.
+ * After set_max_dtoa_threads(n), a call set_max_dtoa_threads(m)
+ * with m <= n has has no effect, but a call with m > n is honored.
+ * Such a call invokes REALLOC (assumed to be "realloc" if REALLOC
+ * is not #defined) to extend the size of the relevant array.
+
+ * #define NO_IEEE_Scale to disable new (Feb. 1997) logic in strtod that
+ * avoids underflows on inputs whose result does not underflow.
+ * If you #define NO_IEEE_Scale on a machine that uses IEEE-format
+ * floating-point numbers and flushes underflows to zero rather
+ * than implementing gradual underflow, then you must also #define
+ * Sudden_Underflow.
+ * #define USE_LOCALE to use the current locale's decimal_point value.
+ * #define SET_INEXACT if IEEE arithmetic is being used and extra
+ * computation should be done to set the inexact flag when the
+ * result is inexact and avoid setting inexact when the result
+ * is exact. In this case, dtoa.c must be compiled in
+ * an environment, perhaps provided by #include "dtoa.c" in a
+ * suitable wrapper, that defines two functions,
+ * int get_inexact(void);
+ * void clear_inexact(void);
+ * such that get_inexact() returns a nonzero value if the
+ * inexact bit is already set, and clear_inexact() sets the
+ * inexact bit to 0. When SET_INEXACT is #defined, strtod
+ * also does extra computations to set the underflow and overflow
+ * flags when appropriate (i.e., when the result is tiny and
+ * inexact or when it is a numeric value rounded to +-infinity).
+ * #define NO_ERRNO if strtod should not assign errno = ERANGE when
+ * the result overflows to +-Infinity or underflows to 0.
+ * When errno should be assigned, under seemingly rare conditions
+ * it may be necessary to define Set_errno(x) suitably, e.g., in
+ * a local errno.h, such as
+ * #include
+ * #define Set_errno(x) _set_errno(x)
+ * #define NO_HEX_FP to omit recognition of hexadecimal floating-point
+ * values by strtod.
+ * #define NO_STRTOD_BIGCOMP (on IEEE-arithmetic systems only for now)
+ * to disable logic for "fast" testing of very long input strings
+ * to strtod. This testing proceeds by initially truncating the
+ * input string, then if necessary comparing the whole string with
+ * a decimal expansion to decide close cases. This logic is only
+ * used for input more than STRTOD_DIGLIM digits long (default 40).
+ */
+
+#include "dtoa_config.h"
+
+#ifndef Long
+#define Long int
+#endif
+#ifndef ULong
+typedef unsigned Long ULong;
+#endif
+
+#ifdef DEBUG
+#include
+#include "stdio.h"
+#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
+#define Debug(x) x
+int dtoa_stats[7]; /* strtod_{64,96,bigcomp},dtoa_{exact,64,96,bigcomp} */
+#else
+#define assert(x) /*nothing*/
+#define Debug(x) /*nothing*/
+#endif
+
+#include "stdlib.h"
+#include "string.h"
+
+#ifdef USE_LOCALE
+#include "locale.h"
+#endif
+
+#ifdef Honor_FLT_ROUNDS
+#ifndef Trust_FLT_ROUNDS
+#include
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef MALLOC
+extern void *MALLOC(size_t);
+#else
+#define MALLOC malloc
+#endif
+
+#ifdef REALLOC
+extern void *REALLOC(void*,size_t);
+#else
+#define REALLOC realloc
+#endif
+
+#ifndef FREE
+#define FREE free
+#endif
+
+#ifdef __cplusplus
+ }
+#endif
+
+#ifndef Omit_Private_Memory
+#ifndef PRIVATE_MEM
+#define PRIVATE_MEM 2304
+#endif
+#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
+static double private_mem[PRIVATE_mem], *pmem_next = private_mem;
+#endif
+
+#undef IEEE_Arith
+#undef Avoid_Underflow
+#ifdef IEEE_MC68k
+#define IEEE_Arith
+#endif
+#ifdef IEEE_8087
+#define IEEE_Arith
+#endif
+
+#ifdef IEEE_Arith
+#ifndef NO_INFNAN_CHECK
+#undef INFNAN_CHECK
+#define INFNAN_CHECK
+#endif
+#else
+#undef INFNAN_CHECK
+#define NO_STRTOD_BIGCOMP
+#endif
+
+#include "errno.h"
+
+#ifdef NO_ERRNO /*{*/
+#undef Set_errno
+#define Set_errno(x)
+#else
+#ifndef Set_errno
+#define Set_errno(x) errno = x
+#endif
+#endif /*}*/
+
+#ifdef Bad_float_h
+
+#ifdef IEEE_Arith
+#define DBL_DIG 15
+#define DBL_MAX_10_EXP 308
+#define DBL_MAX_EXP 1024
+#define FLT_RADIX 2
+#endif /*IEEE_Arith*/
+
+#ifdef IBM
+#define DBL_DIG 16
+#define DBL_MAX_10_EXP 75
+#define DBL_MAX_EXP 63
+#define FLT_RADIX 16
+#define DBL_MAX 7.2370055773322621e+75
+#endif
+
+#ifdef VAX
+#define DBL_DIG 16
+#define DBL_MAX_10_EXP 38
+#define DBL_MAX_EXP 127
+#define FLT_RADIX 2
+#define DBL_MAX 1.7014118346046923e+38
+#endif
+
+#ifndef LONG_MAX
+#define LONG_MAX 2147483647
+#endif
+
+#else /* ifndef Bad_float_h */
+#include "float.h"
+#endif /* Bad_float_h */
+
+#ifndef __MATH_H__
+#include "math.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(VAX) + defined(IBM) != 1
+Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined.
+#endif
+
+#undef USE_BF96
+
+#ifdef NO_LONG_LONG /*{{*/
+#undef ULLong
+#ifdef Just_16
+#undef Pack_32
+/* When Pack_32 is not defined, we store 16 bits per 32-bit Long.
+ * This makes some inner loops simpler and sometimes saves work
+ * during multiplications, but it often seems to make things slightly
+ * slower. Hence the default is now to store 32 bits per Long.
+ */
+#endif
+#else /*}{ long long available */
+#ifndef Llong
+#define Llong long long
+#endif
+#ifndef ULLong
+#define ULLong unsigned Llong
+#endif
+#ifndef NO_BF96 /*{*/
+#define USE_BF96
+
+#ifdef SET_INEXACT
+#define dtoa_divmax 27
+#else
+int dtoa_divmax = 2; /* Permit experimenting: on some systems, 64-bit integer */
+ /* division is slow enough that we may sometimes want to */
+ /* avoid using it. We assume (but do not check) that */
+ /* dtoa_divmax <= 27.*/
+#endif
+
+typedef struct BF96 { /* Normalized 96-bit software floating point numbers */
+ unsigned int b0,b1,b2; /* b0 = most significant, binary point just to its left */
+ int e; /* number represented = b * 2^e, with .5 <= b < 1 */
+ } BF96;
+
+ static BF96 pten[667] = {
+ { 0xeef453d6, 0x923bd65a, 0x113faa29, -1136 },
+ { 0x9558b466, 0x1b6565f8, 0x4ac7ca59, -1132 },
+ { 0xbaaee17f, 0xa23ebf76, 0x5d79bcf0, -1129 },
+ { 0xe95a99df, 0x8ace6f53, 0xf4d82c2c, -1126 },
+ { 0x91d8a02b, 0xb6c10594, 0x79071b9b, -1122 },
+ { 0xb64ec836, 0xa47146f9, 0x9748e282, -1119 },
+ { 0xe3e27a44, 0x4d8d98b7, 0xfd1b1b23, -1116 },
+ { 0x8e6d8c6a, 0xb0787f72, 0xfe30f0f5, -1112 },
+ { 0xb208ef85, 0x5c969f4f, 0xbdbd2d33, -1109 },
+ { 0xde8b2b66, 0xb3bc4723, 0xad2c7880, -1106 },
+ { 0x8b16fb20, 0x3055ac76, 0x4c3bcb50, -1102 },
+ { 0xaddcb9e8, 0x3c6b1793, 0xdf4abe24, -1099 },
+ { 0xd953e862, 0x4b85dd78, 0xd71d6dad, -1096 },
+ { 0x87d4713d, 0x6f33aa6b, 0x8672648c, -1092 },
+ { 0xa9c98d8c, 0xcb009506, 0x680efdaf, -1089 },
+ { 0xd43bf0ef, 0xfdc0ba48, 0x0212bd1b, -1086 },
+ { 0x84a57695, 0xfe98746d, 0x014bb630, -1082 },
+ { 0xa5ced43b, 0x7e3e9188, 0x419ea3bd, -1079 },
+ { 0xcf42894a, 0x5dce35ea, 0x52064cac, -1076 },
+ { 0x818995ce, 0x7aa0e1b2, 0x7343efeb, -1072 },
+ { 0xa1ebfb42, 0x19491a1f, 0x1014ebe6, -1069 },
+ { 0xca66fa12, 0x9f9b60a6, 0xd41a26e0, -1066 },
+ { 0xfd00b897, 0x478238d0, 0x8920b098, -1063 },
+ { 0x9e20735e, 0x8cb16382, 0x55b46e5f, -1059 },
+ { 0xc5a89036, 0x2fddbc62, 0xeb2189f7, -1056 },
+ { 0xf712b443, 0xbbd52b7b, 0xa5e9ec75, -1053 },
+ { 0x9a6bb0aa, 0x55653b2d, 0x47b233c9, -1049 },
+ { 0xc1069cd4, 0xeabe89f8, 0x999ec0bb, -1046 },
+ { 0xf148440a, 0x256e2c76, 0xc00670ea, -1043 },
+ { 0x96cd2a86, 0x5764dbca, 0x38040692, -1039 },
+ { 0xbc807527, 0xed3e12bc, 0xc6050837, -1036 },
+ { 0xeba09271, 0xe88d976b, 0xf7864a44, -1033 },
+ { 0x93445b87, 0x31587ea3, 0x7ab3ee6a, -1029 },
+ { 0xb8157268, 0xfdae9e4c, 0x5960ea05, -1026 },
+ { 0xe61acf03, 0x3d1a45df, 0x6fb92487, -1023 },
+ { 0x8fd0c162, 0x06306bab, 0xa5d3b6d4, -1019 },
+ { 0xb3c4f1ba, 0x87bc8696, 0x8f48a489, -1016 },
+ { 0xe0b62e29, 0x29aba83c, 0x331acdab, -1013 },
+ { 0x8c71dcd9, 0xba0b4925, 0x9ff0c08b, -1009 },
+ { 0xaf8e5410, 0x288e1b6f, 0x07ecf0ae, -1006 },
+ { 0xdb71e914, 0x32b1a24a, 0xc9e82cd9, -1003 },
+ { 0x892731ac, 0x9faf056e, 0xbe311c08, -999 },
+ { 0xab70fe17, 0xc79ac6ca, 0x6dbd630a, -996 },
+ { 0xd64d3d9d, 0xb981787d, 0x092cbbcc, -993 },
+ { 0x85f04682, 0x93f0eb4e, 0x25bbf560, -989 },
+ { 0xa76c5823, 0x38ed2621, 0xaf2af2b8, -986 },
+ { 0xd1476e2c, 0x07286faa, 0x1af5af66, -983 },
+ { 0x82cca4db, 0x847945ca, 0x50d98d9f, -979 },
+ { 0xa37fce12, 0x6597973c, 0xe50ff107, -976 },
+ { 0xcc5fc196, 0xfefd7d0c, 0x1e53ed49, -973 },
+ { 0xff77b1fc, 0xbebcdc4f, 0x25e8e89c, -970 },
+ { 0x9faacf3d, 0xf73609b1, 0x77b19161, -966 },
+ { 0xc795830d, 0x75038c1d, 0xd59df5b9, -963 },
+ { 0xf97ae3d0, 0xd2446f25, 0x4b057328, -960 },
+ { 0x9becce62, 0x836ac577, 0x4ee367f9, -956 },
+ { 0xc2e801fb, 0x244576d5, 0x229c41f7, -953 },
+ { 0xf3a20279, 0xed56d48a, 0x6b435275, -950 },
+ { 0x9845418c, 0x345644d6, 0x830a1389, -946 },
+ { 0xbe5691ef, 0x416bd60c, 0x23cc986b, -943 },
+ { 0xedec366b, 0x11c6cb8f, 0x2cbfbe86, -940 },
+ { 0x94b3a202, 0xeb1c3f39, 0x7bf7d714, -936 },
+ { 0xb9e08a83, 0xa5e34f07, 0xdaf5ccd9, -933 },
+ { 0xe858ad24, 0x8f5c22c9, 0xd1b3400f, -930 },
+ { 0x91376c36, 0xd99995be, 0x23100809, -926 },
+ { 0xb5854744, 0x8ffffb2d, 0xabd40a0c, -923 },
+ { 0xe2e69915, 0xb3fff9f9, 0x16c90c8f, -920 },
+ { 0x8dd01fad, 0x907ffc3b, 0xae3da7d9, -916 },
+ { 0xb1442798, 0xf49ffb4a, 0x99cd11cf, -913 },
+ { 0xdd95317f, 0x31c7fa1d, 0x40405643, -910 },
+ { 0x8a7d3eef, 0x7f1cfc52, 0x482835ea, -906 },
+ { 0xad1c8eab, 0x5ee43b66, 0xda324365, -903 },
+ { 0xd863b256, 0x369d4a40, 0x90bed43e, -900 },
+ { 0x873e4f75, 0xe2224e68, 0x5a7744a6, -896 },
+ { 0xa90de353, 0x5aaae202, 0x711515d0, -893 },
+ { 0xd3515c28, 0x31559a83, 0x0d5a5b44, -890 },
+ { 0x8412d999, 0x1ed58091, 0xe858790a, -886 },
+ { 0xa5178fff, 0x668ae0b6, 0x626e974d, -883 },
+ { 0xce5d73ff, 0x402d98e3, 0xfb0a3d21, -880 },
+ { 0x80fa687f, 0x881c7f8e, 0x7ce66634, -876 },
+ { 0xa139029f, 0x6a239f72, 0x1c1fffc1, -873 },
+ { 0xc9874347, 0x44ac874e, 0xa327ffb2, -870 },
+ { 0xfbe91419, 0x15d7a922, 0x4bf1ff9f, -867 },
+ { 0x9d71ac8f, 0xada6c9b5, 0x6f773fc3, -863 },
+ { 0xc4ce17b3, 0x99107c22, 0xcb550fb4, -860 },
+ { 0xf6019da0, 0x7f549b2b, 0x7e2a53a1, -857 },
+ { 0x99c10284, 0x4f94e0fb, 0x2eda7444, -853 },
+ { 0xc0314325, 0x637a1939, 0xfa911155, -850 },
+ { 0xf03d93ee, 0xbc589f88, 0x793555ab, -847 },
+ { 0x96267c75, 0x35b763b5, 0x4bc1558b, -843 },
+ { 0xbbb01b92, 0x83253ca2, 0x9eb1aaed, -840 },
+ { 0xea9c2277, 0x23ee8bcb, 0x465e15a9, -837 },
+ { 0x92a1958a, 0x7675175f, 0x0bfacd89, -833 },
+ { 0xb749faed, 0x14125d36, 0xcef980ec, -830 },
+ { 0xe51c79a8, 0x5916f484, 0x82b7e127, -827 },
+ { 0x8f31cc09, 0x37ae58d2, 0xd1b2ecb8, -823 },
+ { 0xb2fe3f0b, 0x8599ef07, 0x861fa7e6, -820 },
+ { 0xdfbdcece, 0x67006ac9, 0x67a791e0, -817 },
+ { 0x8bd6a141, 0x006042bd, 0xe0c8bb2c, -813 },
+ { 0xaecc4991, 0x4078536d, 0x58fae9f7, -810 },
+ { 0xda7f5bf5, 0x90966848, 0xaf39a475, -807 },
+ { 0x888f9979, 0x7a5e012d, 0x6d8406c9, -803 },
+ { 0xaab37fd7, 0xd8f58178, 0xc8e5087b, -800 },
+ { 0xd5605fcd, 0xcf32e1d6, 0xfb1e4a9a, -797 },
+ { 0x855c3be0, 0xa17fcd26, 0x5cf2eea0, -793 },
+ { 0xa6b34ad8, 0xc9dfc06f, 0xf42faa48, -790 },
+ { 0xd0601d8e, 0xfc57b08b, 0xf13b94da, -787 },
+ { 0x823c1279, 0x5db6ce57, 0x76c53d08, -783 },
+ { 0xa2cb1717, 0xb52481ed, 0x54768c4b, -780 },
+ { 0xcb7ddcdd, 0xa26da268, 0xa9942f5d, -777 },
+ { 0xfe5d5415, 0x0b090b02, 0xd3f93b35, -774 },
+ { 0x9efa548d, 0x26e5a6e1, 0xc47bc501, -770 },
+ { 0xc6b8e9b0, 0x709f109a, 0x359ab641, -767 },
+ { 0xf867241c, 0x8cc6d4c0, 0xc30163d2, -764 },
+ { 0x9b407691, 0xd7fc44f8, 0x79e0de63, -760 },
+ { 0xc2109436, 0x4dfb5636, 0x985915fc, -757 },
+ { 0xf294b943, 0xe17a2bc4, 0x3e6f5b7b, -754 },
+ { 0x979cf3ca, 0x6cec5b5a, 0xa705992c, -750 },
+ { 0xbd8430bd, 0x08277231, 0x50c6ff78, -747 },
+ { 0xece53cec, 0x4a314ebd, 0xa4f8bf56, -744 },
+ { 0x940f4613, 0xae5ed136, 0x871b7795, -740 },
+ { 0xb9131798, 0x99f68584, 0x28e2557b, -737 },
+ { 0xe757dd7e, 0xc07426e5, 0x331aeada, -734 },
+ { 0x9096ea6f, 0x3848984f, 0x3ff0d2c8, -730 },
+ { 0xb4bca50b, 0x065abe63, 0x0fed077a, -727 },
+ { 0xe1ebce4d, 0xc7f16dfb, 0xd3e84959, -724 },
+ { 0x8d3360f0, 0x9cf6e4bd, 0x64712dd7, -720 },
+ { 0xb080392c, 0xc4349dec, 0xbd8d794d, -717 },
+ { 0xdca04777, 0xf541c567, 0xecf0d7a0, -714 },
+ { 0x89e42caa, 0xf9491b60, 0xf41686c4, -710 },
+ { 0xac5d37d5, 0xb79b6239, 0x311c2875, -707 },
+ { 0xd77485cb, 0x25823ac7, 0x7d633293, -704 },
+ { 0x86a8d39e, 0xf77164bc, 0xae5dff9c, -700 },
+ { 0xa8530886, 0xb54dbdeb, 0xd9f57f83, -697 },
+ { 0xd267caa8, 0x62a12d66, 0xd072df63, -694 },
+ { 0x8380dea9, 0x3da4bc60, 0x4247cb9e, -690 },
+ { 0xa4611653, 0x8d0deb78, 0x52d9be85, -687 },
+ { 0xcd795be8, 0x70516656, 0x67902e27, -684 },
+ { 0x806bd971, 0x4632dff6, 0x00ba1cd8, -680 },
+ { 0xa086cfcd, 0x97bf97f3, 0x80e8a40e, -677 },
+ { 0xc8a883c0, 0xfdaf7df0, 0x6122cd12, -674 },
+ { 0xfad2a4b1, 0x3d1b5d6c, 0x796b8057, -671 },
+ { 0x9cc3a6ee, 0xc6311a63, 0xcbe33036, -667 },
+ { 0xc3f490aa, 0x77bd60fc, 0xbedbfc44, -664 },
+ { 0xf4f1b4d5, 0x15acb93b, 0xee92fb55, -661 },
+ { 0x99171105, 0x2d8bf3c5, 0x751bdd15, -657 },
+ { 0xbf5cd546, 0x78eef0b6, 0xd262d45a, -654 },
+ { 0xef340a98, 0x172aace4, 0x86fb8971, -651 },
+ { 0x9580869f, 0x0e7aac0e, 0xd45d35e6, -647 },
+ { 0xbae0a846, 0xd2195712, 0x89748360, -644 },
+ { 0xe998d258, 0x869facd7, 0x2bd1a438, -641 },
+ { 0x91ff8377, 0x5423cc06, 0x7b6306a3, -637 },
+ { 0xb67f6455, 0x292cbf08, 0x1a3bc84c, -634 },
+ { 0xe41f3d6a, 0x7377eeca, 0x20caba5f, -631 },
+ { 0x8e938662, 0x882af53e, 0x547eb47b, -627 },
+ { 0xb23867fb, 0x2a35b28d, 0xe99e619a, -624 },
+ { 0xdec681f9, 0xf4c31f31, 0x6405fa00, -621 },
+ { 0x8b3c113c, 0x38f9f37e, 0xde83bc40, -617 },
+ { 0xae0b158b, 0x4738705e, 0x9624ab50, -614 },
+ { 0xd98ddaee, 0x19068c76, 0x3badd624, -611 },
+ { 0x87f8a8d4, 0xcfa417c9, 0xe54ca5d7, -607 },
+ { 0xa9f6d30a, 0x038d1dbc, 0x5e9fcf4c, -604 },
+ { 0xd47487cc, 0x8470652b, 0x7647c320, -601 },
+ { 0x84c8d4df, 0xd2c63f3b, 0x29ecd9f4, -597 },
+ { 0xa5fb0a17, 0xc777cf09, 0xf4681071, -594 },
+ { 0xcf79cc9d, 0xb955c2cc, 0x7182148d, -591 },
+ { 0x81ac1fe2, 0x93d599bf, 0xc6f14cd8, -587 },
+ { 0xa21727db, 0x38cb002f, 0xb8ada00e, -584 },
+ { 0xca9cf1d2, 0x06fdc03b, 0xa6d90811, -581 },
+ { 0xfd442e46, 0x88bd304a, 0x908f4a16, -578 },
+ { 0x9e4a9cec, 0x15763e2e, 0x9a598e4e, -574 },
+ { 0xc5dd4427, 0x1ad3cdba, 0x40eff1e1, -571 },
+ { 0xf7549530, 0xe188c128, 0xd12bee59, -568 },
+ { 0x9a94dd3e, 0x8cf578b9, 0x82bb74f8, -564 },
+ { 0xc13a148e, 0x3032d6e7, 0xe36a5236, -561 },
+ { 0xf18899b1, 0xbc3f8ca1, 0xdc44e6c3, -558 },
+ { 0x96f5600f, 0x15a7b7e5, 0x29ab103a, -554 },
+ { 0xbcb2b812, 0xdb11a5de, 0x7415d448, -551 },
+ { 0xebdf6617, 0x91d60f56, 0x111b495b, -548 },
+ { 0x936b9fce, 0xbb25c995, 0xcab10dd9, -544 },
+ { 0xb84687c2, 0x69ef3bfb, 0x3d5d514f, -541 },
+ { 0xe65829b3, 0x046b0afa, 0x0cb4a5a3, -538 },
+ { 0x8ff71a0f, 0xe2c2e6dc, 0x47f0e785, -534 },
+ { 0xb3f4e093, 0xdb73a093, 0x59ed2167, -531 },
+ { 0xe0f218b8, 0xd25088b8, 0x306869c1, -528 },
+ { 0x8c974f73, 0x83725573, 0x1e414218, -524 },
+ { 0xafbd2350, 0x644eeacf, 0xe5d1929e, -521 },
+ { 0xdbac6c24, 0x7d62a583, 0xdf45f746, -518 },
+ { 0x894bc396, 0xce5da772, 0x6b8bba8c, -514 },
+ { 0xab9eb47c, 0x81f5114f, 0x066ea92f, -511 },
+ { 0xd686619b, 0xa27255a2, 0xc80a537b, -508 },
+ { 0x8613fd01, 0x45877585, 0xbd06742c, -504 },
+ { 0xa798fc41, 0x96e952e7, 0x2c481138, -501 },
+ { 0xd17f3b51, 0xfca3a7a0, 0xf75a1586, -498 },
+ { 0x82ef8513, 0x3de648c4, 0x9a984d73, -494 },
+ { 0xa3ab6658, 0x0d5fdaf5, 0xc13e60d0, -491 },
+ { 0xcc963fee, 0x10b7d1b3, 0x318df905, -488 },
+ { 0xffbbcfe9, 0x94e5c61f, 0xfdf17746, -485 },
+ { 0x9fd561f1, 0xfd0f9bd3, 0xfeb6ea8b, -481 },
+ { 0xc7caba6e, 0x7c5382c8, 0xfe64a52e, -478 },
+ { 0xf9bd690a, 0x1b68637b, 0x3dfdce7a, -475 },
+ { 0x9c1661a6, 0x51213e2d, 0x06bea10c, -471 },
+ { 0xc31bfa0f, 0xe5698db8, 0x486e494f, -468 },
+ { 0xf3e2f893, 0xdec3f126, 0x5a89dba3, -465 },
+ { 0x986ddb5c, 0x6b3a76b7, 0xf8962946, -461 },
+ { 0xbe895233, 0x86091465, 0xf6bbb397, -458 },
+ { 0xee2ba6c0, 0x678b597f, 0x746aa07d, -455 },
+ { 0x94db4838, 0x40b717ef, 0xa8c2a44e, -451 },
+ { 0xba121a46, 0x50e4ddeb, 0x92f34d62, -448 },
+ { 0xe896a0d7, 0xe51e1566, 0x77b020ba, -445 },
+ { 0x915e2486, 0xef32cd60, 0x0ace1474, -441 },
+ { 0xb5b5ada8, 0xaaff80b8, 0x0d819992, -438 },
+ { 0xe3231912, 0xd5bf60e6, 0x10e1fff6, -435 },
+ { 0x8df5efab, 0xc5979c8f, 0xca8d3ffa, -431 },
+ { 0xb1736b96, 0xb6fd83b3, 0xbd308ff8, -428 },
+ { 0xddd0467c, 0x64bce4a0, 0xac7cb3f6, -425 },
+ { 0x8aa22c0d, 0xbef60ee4, 0x6bcdf07a, -421 },
+ { 0xad4ab711, 0x2eb3929d, 0x86c16c98, -418 },
+ { 0xd89d64d5, 0x7a607744, 0xe871c7bf, -415 },
+ { 0x87625f05, 0x6c7c4a8b, 0x11471cd7, -411 },
+ { 0xa93af6c6, 0xc79b5d2d, 0xd598e40d, -408 },
+ { 0xd389b478, 0x79823479, 0x4aff1d10, -405 },
+ { 0x843610cb, 0x4bf160cb, 0xcedf722a, -401 },
+ { 0xa54394fe, 0x1eedb8fe, 0xc2974eb4, -398 },
+ { 0xce947a3d, 0xa6a9273e, 0x733d2262, -395 },
+ { 0x811ccc66, 0x8829b887, 0x0806357d, -391 },
+ { 0xa163ff80, 0x2a3426a8, 0xca07c2dc, -388 },
+ { 0xc9bcff60, 0x34c13052, 0xfc89b393, -385 },
+ { 0xfc2c3f38, 0x41f17c67, 0xbbac2078, -382 },
+ { 0x9d9ba783, 0x2936edc0, 0xd54b944b, -378 },
+ { 0xc5029163, 0xf384a931, 0x0a9e795e, -375 },
+ { 0xf64335bc, 0xf065d37d, 0x4d4617b5, -372 },
+ { 0x99ea0196, 0x163fa42e, 0x504bced1, -368 },
+ { 0xc06481fb, 0x9bcf8d39, 0xe45ec286, -365 },
+ { 0xf07da27a, 0x82c37088, 0x5d767327, -362 },
+ { 0x964e858c, 0x91ba2655, 0x3a6a07f8, -358 },
+ { 0xbbe226ef, 0xb628afea, 0x890489f7, -355 },
+ { 0xeadab0ab, 0xa3b2dbe5, 0x2b45ac74, -352 },
+ { 0x92c8ae6b, 0x464fc96f, 0x3b0b8bc9, -348 },
+ { 0xb77ada06, 0x17e3bbcb, 0x09ce6ebb, -345 },
+ { 0xe5599087, 0x9ddcaabd, 0xcc420a6a, -342 },
+ { 0x8f57fa54, 0xc2a9eab6, 0x9fa94682, -338 },
+ { 0xb32df8e9, 0xf3546564, 0x47939822, -335 },
+ { 0xdff97724, 0x70297ebd, 0x59787e2b, -332 },
+ { 0x8bfbea76, 0xc619ef36, 0x57eb4edb, -328 },
+ { 0xaefae514, 0x77a06b03, 0xede62292, -325 },
+ { 0xdab99e59, 0x958885c4, 0xe95fab36, -322 },
+ { 0x88b402f7, 0xfd75539b, 0x11dbcb02, -318 },
+ { 0xaae103b5, 0xfcd2a881, 0xd652bdc2, -315 },
+ { 0xd59944a3, 0x7c0752a2, 0x4be76d33, -312 },
+ { 0x857fcae6, 0x2d8493a5, 0x6f70a440, -308 },
+ { 0xa6dfbd9f, 0xb8e5b88e, 0xcb4ccd50, -305 },
+ { 0xd097ad07, 0xa71f26b2, 0x7e2000a4, -302 },
+ { 0x825ecc24, 0xc873782f, 0x8ed40066, -298 },
+ { 0xa2f67f2d, 0xfa90563b, 0x72890080, -295 },
+ { 0xcbb41ef9, 0x79346bca, 0x4f2b40a0, -292 },
+ { 0xfea126b7, 0xd78186bc, 0xe2f610c8, -289 },
+ { 0x9f24b832, 0xe6b0f436, 0x0dd9ca7d, -285 },
+ { 0xc6ede63f, 0xa05d3143, 0x91503d1c, -282 },
+ { 0xf8a95fcf, 0x88747d94, 0x75a44c63, -279 },
+ { 0x9b69dbe1, 0xb548ce7c, 0xc986afbe, -275 },
+ { 0xc24452da, 0x229b021b, 0xfbe85bad, -272 },
+ { 0xf2d56790, 0xab41c2a2, 0xfae27299, -269 },
+ { 0x97c560ba, 0x6b0919a5, 0xdccd879f, -265 },
+ { 0xbdb6b8e9, 0x05cb600f, 0x5400e987, -262 },
+ { 0xed246723, 0x473e3813, 0x290123e9, -259 },
+ { 0x9436c076, 0x0c86e30b, 0xf9a0b672, -255 },
+ { 0xb9447093, 0x8fa89bce, 0xf808e40e, -252 },
+ { 0xe7958cb8, 0x7392c2c2, 0xb60b1d12, -249 },
+ { 0x90bd77f3, 0x483bb9b9, 0xb1c6f22b, -245 },
+ { 0xb4ecd5f0, 0x1a4aa828, 0x1e38aeb6, -242 },
+ { 0xe2280b6c, 0x20dd5232, 0x25c6da63, -239 },
+ { 0x8d590723, 0x948a535f, 0x579c487e, -235 },
+ { 0xb0af48ec, 0x79ace837, 0x2d835a9d, -232 },
+ { 0xdcdb1b27, 0x98182244, 0xf8e43145, -229 },
+ { 0x8a08f0f8, 0xbf0f156b, 0x1b8e9ecb, -225 },
+ { 0xac8b2d36, 0xeed2dac5, 0xe272467e, -222 },
+ { 0xd7adf884, 0xaa879177, 0x5b0ed81d, -219 },
+ { 0x86ccbb52, 0xea94baea, 0x98e94712, -215 },
+ { 0xa87fea27, 0xa539e9a5, 0x3f2398d7, -212 },
+ { 0xd29fe4b1, 0x8e88640e, 0x8eec7f0d, -209 },
+ { 0x83a3eeee, 0xf9153e89, 0x1953cf68, -205 },
+ { 0xa48ceaaa, 0xb75a8e2b, 0x5fa8c342, -202 },
+ { 0xcdb02555, 0x653131b6, 0x3792f412, -199 },
+ { 0x808e1755, 0x5f3ebf11, 0xe2bbd88b, -195 },
+ { 0xa0b19d2a, 0xb70e6ed6, 0x5b6aceae, -192 },
+ { 0xc8de0475, 0x64d20a8b, 0xf245825a, -189 },
+ { 0xfb158592, 0xbe068d2e, 0xeed6e2f0, -186 },
+ { 0x9ced737b, 0xb6c4183d, 0x55464dd6, -182 },
+ { 0xc428d05a, 0xa4751e4c, 0xaa97e14c, -179 },
+ { 0xf5330471, 0x4d9265df, 0xd53dd99f, -176 },
+ { 0x993fe2c6, 0xd07b7fab, 0xe546a803, -172 },
+ { 0xbf8fdb78, 0x849a5f96, 0xde985204, -169 },
+ { 0xef73d256, 0xa5c0f77c, 0x963e6685, -166 },
+ { 0x95a86376, 0x27989aad, 0xdde70013, -162 },
+ { 0xbb127c53, 0xb17ec159, 0x5560c018, -159 },
+ { 0xe9d71b68, 0x9dde71af, 0xaab8f01e, -156 },
+ { 0x92267121, 0x62ab070d, 0xcab39613, -152 },
+ { 0xb6b00d69, 0xbb55c8d1, 0x3d607b97, -149 },
+ { 0xe45c10c4, 0x2a2b3b05, 0x8cb89a7d, -146 },
+ { 0x8eb98a7a, 0x9a5b04e3, 0x77f3608e, -142 },
+ { 0xb267ed19, 0x40f1c61c, 0x55f038b2, -139 },
+ { 0xdf01e85f, 0x912e37a3, 0x6b6c46de, -136 },
+ { 0x8b61313b, 0xbabce2c6, 0x2323ac4b, -132 },
+ { 0xae397d8a, 0xa96c1b77, 0xabec975e, -129 },
+ { 0xd9c7dced, 0x53c72255, 0x96e7bd35, -126 },
+ { 0x881cea14, 0x545c7575, 0x7e50d641, -122 },
+ { 0xaa242499, 0x697392d2, 0xdde50bd1, -119 },
+ { 0xd4ad2dbf, 0xc3d07787, 0x955e4ec6, -116 },
+ { 0x84ec3c97, 0xda624ab4, 0xbd5af13b, -112 },
+ { 0xa6274bbd, 0xd0fadd61, 0xecb1ad8a, -109 },
+ { 0xcfb11ead, 0x453994ba, 0x67de18ed, -106 },
+ { 0x81ceb32c, 0x4b43fcf4, 0x80eacf94, -102 },
+ { 0xa2425ff7, 0x5e14fc31, 0xa1258379, -99 },
+ { 0xcad2f7f5, 0x359a3b3e, 0x096ee458, -96 },
+ { 0xfd87b5f2, 0x8300ca0d, 0x8bca9d6e, -93 },
+ { 0x9e74d1b7, 0x91e07e48, 0x775ea264, -89 },
+ { 0xc6120625, 0x76589dda, 0x95364afe, -86 },
+ { 0xf79687ae, 0xd3eec551, 0x3a83ddbd, -83 },
+ { 0x9abe14cd, 0x44753b52, 0xc4926a96, -79 },
+ { 0xc16d9a00, 0x95928a27, 0x75b7053c, -76 },
+ { 0xf1c90080, 0xbaf72cb1, 0x5324c68b, -73 },
+ { 0x971da050, 0x74da7bee, 0xd3f6fc16, -69 },
+ { 0xbce50864, 0x92111aea, 0x88f4bb1c, -66 },
+ { 0xec1e4a7d, 0xb69561a5, 0x2b31e9e3, -63 },
+ { 0x9392ee8e, 0x921d5d07, 0x3aff322e, -59 },
+ { 0xb877aa32, 0x36a4b449, 0x09befeb9, -56 },
+ { 0xe69594be, 0xc44de15b, 0x4c2ebe68, -53 },
+ { 0x901d7cf7, 0x3ab0acd9, 0x0f9d3701, -49 },
+ { 0xb424dc35, 0x095cd80f, 0x538484c1, -46 },
+ { 0xe12e1342, 0x4bb40e13, 0x2865a5f2, -43 },
+ { 0x8cbccc09, 0x6f5088cb, 0xf93f87b7, -39 },
+ { 0xafebff0b, 0xcb24aafe, 0xf78f69a5, -36 },
+ { 0xdbe6fece, 0xbdedd5be, 0xb573440e, -33 },
+ { 0x89705f41, 0x36b4a597, 0x31680a88, -29 },
+ { 0xabcc7711, 0x8461cefc, 0xfdc20d2b, -26 },
+ { 0xd6bf94d5, 0xe57a42bc, 0x3d329076, -23 },
+ { 0x8637bd05, 0xaf6c69b5, 0xa63f9a49, -19 },
+ { 0xa7c5ac47, 0x1b478423, 0x0fcf80dc, -16 },
+ { 0xd1b71758, 0xe219652b, 0xd3c36113, -13 },
+ { 0x83126e97, 0x8d4fdf3b, 0x645a1cac, -9 },
+ { 0xa3d70a3d, 0x70a3d70a, 0x3d70a3d7, -6 },
+ { 0xcccccccc, 0xcccccccc, 0xcccccccc, -3 },
+ { 0x80000000, 0x00000000, 0x00000000, 1 },
+ { 0xa0000000, 0x00000000, 0x00000000, 4 },
+ { 0xc8000000, 0x00000000, 0x00000000, 7 },
+ { 0xfa000000, 0x00000000, 0x00000000, 10 },
+ { 0x9c400000, 0x00000000, 0x00000000, 14 },
+ { 0xc3500000, 0x00000000, 0x00000000, 17 },
+ { 0xf4240000, 0x00000000, 0x00000000, 20 },
+ { 0x98968000, 0x00000000, 0x00000000, 24 },
+ { 0xbebc2000, 0x00000000, 0x00000000, 27 },
+ { 0xee6b2800, 0x00000000, 0x00000000, 30 },
+ { 0x9502f900, 0x00000000, 0x00000000, 34 },
+ { 0xba43b740, 0x00000000, 0x00000000, 37 },
+ { 0xe8d4a510, 0x00000000, 0x00000000, 40 },
+ { 0x9184e72a, 0x00000000, 0x00000000, 44 },
+ { 0xb5e620f4, 0x80000000, 0x00000000, 47 },
+ { 0xe35fa931, 0xa0000000, 0x00000000, 50 },
+ { 0x8e1bc9bf, 0x04000000, 0x00000000, 54 },
+ { 0xb1a2bc2e, 0xc5000000, 0x00000000, 57 },
+ { 0xde0b6b3a, 0x76400000, 0x00000000, 60 },
+ { 0x8ac72304, 0x89e80000, 0x00000000, 64 },
+ { 0xad78ebc5, 0xac620000, 0x00000000, 67 },
+ { 0xd8d726b7, 0x177a8000, 0x00000000, 70 },
+ { 0x87867832, 0x6eac9000, 0x00000000, 74 },
+ { 0xa968163f, 0x0a57b400, 0x00000000, 77 },
+ { 0xd3c21bce, 0xcceda100, 0x00000000, 80 },
+ { 0x84595161, 0x401484a0, 0x00000000, 84 },
+ { 0xa56fa5b9, 0x9019a5c8, 0x00000000, 87 },
+ { 0xcecb8f27, 0xf4200f3a, 0x00000000, 90 },
+ { 0x813f3978, 0xf8940984, 0x40000000, 94 },
+ { 0xa18f07d7, 0x36b90be5, 0x50000000, 97 },
+ { 0xc9f2c9cd, 0x04674ede, 0xa4000000, 100 },
+ { 0xfc6f7c40, 0x45812296, 0x4d000000, 103 },
+ { 0x9dc5ada8, 0x2b70b59d, 0xf0200000, 107 },
+ { 0xc5371912, 0x364ce305, 0x6c280000, 110 },
+ { 0xf684df56, 0xc3e01bc6, 0xc7320000, 113 },
+ { 0x9a130b96, 0x3a6c115c, 0x3c7f4000, 117 },
+ { 0xc097ce7b, 0xc90715b3, 0x4b9f1000, 120 },
+ { 0xf0bdc21a, 0xbb48db20, 0x1e86d400, 123 },
+ { 0x96769950, 0xb50d88f4, 0x13144480, 127 },
+ { 0xbc143fa4, 0xe250eb31, 0x17d955a0, 130 },
+ { 0xeb194f8e, 0x1ae525fd, 0x5dcfab08, 133 },
+ { 0x92efd1b8, 0xd0cf37be, 0x5aa1cae5, 137 },
+ { 0xb7abc627, 0x050305ad, 0xf14a3d9e, 140 },
+ { 0xe596b7b0, 0xc643c719, 0x6d9ccd05, 143 },
+ { 0x8f7e32ce, 0x7bea5c6f, 0xe4820023, 147 },
+ { 0xb35dbf82, 0x1ae4f38b, 0xdda2802c, 150 },
+ { 0xe0352f62, 0xa19e306e, 0xd50b2037, 153 },
+ { 0x8c213d9d, 0xa502de45, 0x4526f422, 157 },
+ { 0xaf298d05, 0x0e4395d6, 0x9670b12b, 160 },
+ { 0xdaf3f046, 0x51d47b4c, 0x3c0cdd76, 163 },
+ { 0x88d8762b, 0xf324cd0f, 0xa5880a69, 167 },
+ { 0xab0e93b6, 0xefee0053, 0x8eea0d04, 170 },
+ { 0xd5d238a4, 0xabe98068, 0x72a49045, 173 },
+ { 0x85a36366, 0xeb71f041, 0x47a6da2b, 177 },
+ { 0xa70c3c40, 0xa64e6c51, 0x999090b6, 180 },
+ { 0xd0cf4b50, 0xcfe20765, 0xfff4b4e3, 183 },
+ { 0x82818f12, 0x81ed449f, 0xbff8f10e, 187 },
+ { 0xa321f2d7, 0x226895c7, 0xaff72d52, 190 },
+ { 0xcbea6f8c, 0xeb02bb39, 0x9bf4f8a6, 193 },
+ { 0xfee50b70, 0x25c36a08, 0x02f236d0, 196 },
+ { 0x9f4f2726, 0x179a2245, 0x01d76242, 200 },
+ { 0xc722f0ef, 0x9d80aad6, 0x424d3ad2, 203 },
+ { 0xf8ebad2b, 0x84e0d58b, 0xd2e08987, 206 },
+ { 0x9b934c3b, 0x330c8577, 0x63cc55f4, 210 },
+ { 0xc2781f49, 0xffcfa6d5, 0x3cbf6b71, 213 },
+ { 0xf316271c, 0x7fc3908a, 0x8bef464e, 216 },
+ { 0x97edd871, 0xcfda3a56, 0x97758bf0, 220 },
+ { 0xbde94e8e, 0x43d0c8ec, 0x3d52eeed, 223 },
+ { 0xed63a231, 0xd4c4fb27, 0x4ca7aaa8, 226 },
+ { 0x945e455f, 0x24fb1cf8, 0x8fe8caa9, 230 },
+ { 0xb975d6b6, 0xee39e436, 0xb3e2fd53, 233 },
+ { 0xe7d34c64, 0xa9c85d44, 0x60dbbca8, 236 },
+ { 0x90e40fbe, 0xea1d3a4a, 0xbc8955e9, 240 },
+ { 0xb51d13ae, 0xa4a488dd, 0x6babab63, 243 },
+ { 0xe264589a, 0x4dcdab14, 0xc696963c, 246 },
+ { 0x8d7eb760, 0x70a08aec, 0xfc1e1de5, 250 },
+ { 0xb0de6538, 0x8cc8ada8, 0x3b25a55f, 253 },
+ { 0xdd15fe86, 0xaffad912, 0x49ef0eb7, 256 },
+ { 0x8a2dbf14, 0x2dfcc7ab, 0x6e356932, 260 },
+ { 0xacb92ed9, 0x397bf996, 0x49c2c37f, 263 },
+ { 0xd7e77a8f, 0x87daf7fb, 0xdc33745e, 266 },
+ { 0x86f0ac99, 0xb4e8dafd, 0x69a028bb, 270 },
+ { 0xa8acd7c0, 0x222311bc, 0xc40832ea, 273 },
+ { 0xd2d80db0, 0x2aabd62b, 0xf50a3fa4, 276 },
+ { 0x83c7088e, 0x1aab65db, 0x792667c6, 280 },
+ { 0xa4b8cab1, 0xa1563f52, 0x577001b8, 283 },
+ { 0xcde6fd5e, 0x09abcf26, 0xed4c0226, 286 },
+ { 0x80b05e5a, 0xc60b6178, 0x544f8158, 290 },
+ { 0xa0dc75f1, 0x778e39d6, 0x696361ae, 293 },
+ { 0xc913936d, 0xd571c84c, 0x03bc3a19, 296 },
+ { 0xfb587849, 0x4ace3a5f, 0x04ab48a0, 299 },
+ { 0x9d174b2d, 0xcec0e47b, 0x62eb0d64, 303 },
+ { 0xc45d1df9, 0x42711d9a, 0x3ba5d0bd, 306 },
+ { 0xf5746577, 0x930d6500, 0xca8f44ec, 309 },
+ { 0x9968bf6a, 0xbbe85f20, 0x7e998b13, 313 },
+ { 0xbfc2ef45, 0x6ae276e8, 0x9e3fedd8, 316 },
+ { 0xefb3ab16, 0xc59b14a2, 0xc5cfe94e, 319 },
+ { 0x95d04aee, 0x3b80ece5, 0xbba1f1d1, 323 },
+ { 0xbb445da9, 0xca61281f, 0x2a8a6e45, 326 },
+ { 0xea157514, 0x3cf97226, 0xf52d09d7, 329 },
+ { 0x924d692c, 0xa61be758, 0x593c2626, 333 },
+ { 0xb6e0c377, 0xcfa2e12e, 0x6f8b2fb0, 336 },
+ { 0xe498f455, 0xc38b997a, 0x0b6dfb9c, 339 },
+ { 0x8edf98b5, 0x9a373fec, 0x4724bd41, 343 },
+ { 0xb2977ee3, 0x00c50fe7, 0x58edec91, 346 },
+ { 0xdf3d5e9b, 0xc0f653e1, 0x2f2967b6, 349 },
+ { 0x8b865b21, 0x5899f46c, 0xbd79e0d2, 353 },
+ { 0xae67f1e9, 0xaec07187, 0xecd85906, 356 },
+ { 0xda01ee64, 0x1a708de9, 0xe80e6f48, 359 },
+ { 0x884134fe, 0x908658b2, 0x3109058d, 363 },
+ { 0xaa51823e, 0x34a7eede, 0xbd4b46f0, 366 },
+ { 0xd4e5e2cd, 0xc1d1ea96, 0x6c9e18ac, 369 },
+ { 0x850fadc0, 0x9923329e, 0x03e2cf6b, 373 },
+ { 0xa6539930, 0xbf6bff45, 0x84db8346, 376 },
+ { 0xcfe87f7c, 0xef46ff16, 0xe6126418, 379 },
+ { 0x81f14fae, 0x158c5f6e, 0x4fcb7e8f, 383 },
+ { 0xa26da399, 0x9aef7749, 0xe3be5e33, 386 },
+ { 0xcb090c80, 0x01ab551c, 0x5cadf5bf, 389 },
+ { 0xfdcb4fa0, 0x02162a63, 0x73d9732f, 392 },
+ { 0x9e9f11c4, 0x014dda7e, 0x2867e7fd, 396 },
+ { 0xc646d635, 0x01a1511d, 0xb281e1fd, 399 },
+ { 0xf7d88bc2, 0x4209a565, 0x1f225a7c, 402 },
+ { 0x9ae75759, 0x6946075f, 0x3375788d, 406 },
+ { 0xc1a12d2f, 0xc3978937, 0x0052d6b1, 409 },
+ { 0xf209787b, 0xb47d6b84, 0xc0678c5d, 412 },
+ { 0x9745eb4d, 0x50ce6332, 0xf840b7ba, 416 },
+ { 0xbd176620, 0xa501fbff, 0xb650e5a9, 419 },
+ { 0xec5d3fa8, 0xce427aff, 0xa3e51f13, 422 },
+ { 0x93ba47c9, 0x80e98cdf, 0xc66f336c, 426 },
+ { 0xb8a8d9bb, 0xe123f017, 0xb80b0047, 429 },
+ { 0xe6d3102a, 0xd96cec1d, 0xa60dc059, 432 },
+ { 0x9043ea1a, 0xc7e41392, 0x87c89837, 436 },
+ { 0xb454e4a1, 0x79dd1877, 0x29babe45, 439 },
+ { 0xe16a1dc9, 0xd8545e94, 0xf4296dd6, 442 },
+ { 0x8ce2529e, 0x2734bb1d, 0x1899e4a6, 446 },
+ { 0xb01ae745, 0xb101e9e4, 0x5ec05dcf, 449 },
+ { 0xdc21a117, 0x1d42645d, 0x76707543, 452 },
+ { 0x899504ae, 0x72497eba, 0x6a06494a, 456 },
+ { 0xabfa45da, 0x0edbde69, 0x0487db9d, 459 },
+ { 0xd6f8d750, 0x9292d603, 0x45a9d284, 462 },
+ { 0x865b8692, 0x5b9bc5c2, 0x0b8a2392, 466 },
+ { 0xa7f26836, 0xf282b732, 0x8e6cac77, 469 },
+ { 0xd1ef0244, 0xaf2364ff, 0x3207d795, 472 },
+ { 0x8335616a, 0xed761f1f, 0x7f44e6bd, 476 },
+ { 0xa402b9c5, 0xa8d3a6e7, 0x5f16206c, 479 },
+ { 0xcd036837, 0x130890a1, 0x36dba887, 482 },
+ { 0x80222122, 0x6be55a64, 0xc2494954, 486 },
+ { 0xa02aa96b, 0x06deb0fd, 0xf2db9baa, 489 },
+ { 0xc83553c5, 0xc8965d3d, 0x6f928294, 492 },
+ { 0xfa42a8b7, 0x3abbf48c, 0xcb772339, 495 },
+ { 0x9c69a972, 0x84b578d7, 0xff2a7604, 499 },
+ { 0xc38413cf, 0x25e2d70d, 0xfef51385, 502 },
+ { 0xf46518c2, 0xef5b8cd1, 0x7eb25866, 505 },
+ { 0x98bf2f79, 0xd5993802, 0xef2f773f, 509 },
+ { 0xbeeefb58, 0x4aff8603, 0xaafb550f, 512 },
+ { 0xeeaaba2e, 0x5dbf6784, 0x95ba2a53, 515 },
+ { 0x952ab45c, 0xfa97a0b2, 0xdd945a74, 519 },
+ { 0xba756174, 0x393d88df, 0x94f97111, 522 },
+ { 0xe912b9d1, 0x478ceb17, 0x7a37cd56, 525 },
+ { 0x91abb422, 0xccb812ee, 0xac62e055, 529 },
+ { 0xb616a12b, 0x7fe617aa, 0x577b986b, 532 },
+ { 0xe39c4976, 0x5fdf9d94, 0xed5a7e85, 535 },
+ { 0x8e41ade9, 0xfbebc27d, 0x14588f13, 539 },
+ { 0xb1d21964, 0x7ae6b31c, 0x596eb2d8, 542 },
+ { 0xde469fbd, 0x99a05fe3, 0x6fca5f8e, 545 },
+ { 0x8aec23d6, 0x80043bee, 0x25de7bb9, 549 },
+ { 0xada72ccc, 0x20054ae9, 0xaf561aa7, 552 },
+ { 0xd910f7ff, 0x28069da4, 0x1b2ba151, 555 },
+ { 0x87aa9aff, 0x79042286, 0x90fb44d2, 559 },
+ { 0xa99541bf, 0x57452b28, 0x353a1607, 562 },
+ { 0xd3fa922f, 0x2d1675f2, 0x42889b89, 565 },
+ { 0x847c9b5d, 0x7c2e09b7, 0x69956135, 569 },
+ { 0xa59bc234, 0xdb398c25, 0x43fab983, 572 },
+ { 0xcf02b2c2, 0x1207ef2e, 0x94f967e4, 575 },
+ { 0x8161afb9, 0x4b44f57d, 0x1d1be0ee, 579 },
+ { 0xa1ba1ba7, 0x9e1632dc, 0x6462d92a, 582 },
+ { 0xca28a291, 0x859bbf93, 0x7d7b8f75, 585 },
+ { 0xfcb2cb35, 0xe702af78, 0x5cda7352, 588 },
+ { 0x9defbf01, 0xb061adab, 0x3a088813, 592 },
+ { 0xc56baec2, 0x1c7a1916, 0x088aaa18, 595 },
+ { 0xf6c69a72, 0xa3989f5b, 0x8aad549e, 598 },
+ { 0x9a3c2087, 0xa63f6399, 0x36ac54e2, 602 },
+ { 0xc0cb28a9, 0x8fcf3c7f, 0x84576a1b, 605 },
+ { 0xf0fdf2d3, 0xf3c30b9f, 0x656d44a2, 608 },
+ { 0x969eb7c4, 0x7859e743, 0x9f644ae5, 612 },
+ { 0xbc4665b5, 0x96706114, 0x873d5d9f, 615 },
+ { 0xeb57ff22, 0xfc0c7959, 0xa90cb506, 618 },
+ { 0x9316ff75, 0xdd87cbd8, 0x09a7f124, 622 },
+ { 0xb7dcbf53, 0x54e9bece, 0x0c11ed6d, 625 },
+ { 0xe5d3ef28, 0x2a242e81, 0x8f1668c8, 628 },
+ { 0x8fa47579, 0x1a569d10, 0xf96e017d, 632 },
+ { 0xb38d92d7, 0x60ec4455, 0x37c981dc, 635 },
+ { 0xe070f78d, 0x3927556a, 0x85bbe253, 638 },
+ { 0x8c469ab8, 0x43b89562, 0x93956d74, 642 },
+ { 0xaf584166, 0x54a6babb, 0x387ac8d1, 645 },
+ { 0xdb2e51bf, 0xe9d0696a, 0x06997b05, 648 },
+ { 0x88fcf317, 0xf22241e2, 0x441fece3, 652 },
+ { 0xab3c2fdd, 0xeeaad25a, 0xd527e81c, 655 },
+ { 0xd60b3bd5, 0x6a5586f1, 0x8a71e223, 658 },
+ { 0x85c70565, 0x62757456, 0xf6872d56, 662 },
+ { 0xa738c6be, 0xbb12d16c, 0xb428f8ac, 665 },
+ { 0xd106f86e, 0x69d785c7, 0xe13336d7, 668 },
+ { 0x82a45b45, 0x0226b39c, 0xecc00246, 672 },
+ { 0xa34d7216, 0x42b06084, 0x27f002d7, 675 },
+ { 0xcc20ce9b, 0xd35c78a5, 0x31ec038d, 678 },
+ { 0xff290242, 0xc83396ce, 0x7e670471, 681 },
+ { 0x9f79a169, 0xbd203e41, 0x0f0062c6, 685 },
+ { 0xc75809c4, 0x2c684dd1, 0x52c07b78, 688 },
+ { 0xf92e0c35, 0x37826145, 0xa7709a56, 691 },
+ { 0x9bbcc7a1, 0x42b17ccb, 0x88a66076, 695 },
+ { 0xc2abf989, 0x935ddbfe, 0x6acff893, 698 },
+ { 0xf356f7eb, 0xf83552fe, 0x0583f6b8, 701 },
+ { 0x98165af3, 0x7b2153de, 0xc3727a33, 705 },
+ { 0xbe1bf1b0, 0x59e9a8d6, 0x744f18c0, 708 },
+ { 0xeda2ee1c, 0x7064130c, 0x1162def0, 711 },
+ { 0x9485d4d1, 0xc63e8be7, 0x8addcb56, 715 },
+ { 0xb9a74a06, 0x37ce2ee1, 0x6d953e2b, 718 },
+ { 0xe8111c87, 0xc5c1ba99, 0xc8fa8db6, 721 },
+ { 0x910ab1d4, 0xdb9914a0, 0x1d9c9892, 725 },
+ { 0xb54d5e4a, 0x127f59c8, 0x2503beb6, 728 },
+ { 0xe2a0b5dc, 0x971f303a, 0x2e44ae64, 731 },
+ { 0x8da471a9, 0xde737e24, 0x5ceaecfe, 735 },
+ { 0xb10d8e14, 0x56105dad, 0x7425a83e, 738 },
+ { 0xdd50f199, 0x6b947518, 0xd12f124e, 741 },
+ { 0x8a5296ff, 0xe33cc92f, 0x82bd6b70, 745 },
+ { 0xace73cbf, 0xdc0bfb7b, 0x636cc64d, 748 },
+ { 0xd8210bef, 0xd30efa5a, 0x3c47f7e0, 751 },
+ { 0x8714a775, 0xe3e95c78, 0x65acfaec, 755 },
+ { 0xa8d9d153, 0x5ce3b396, 0x7f1839a7, 758 },
+ { 0xd31045a8, 0x341ca07c, 0x1ede4811, 761 },
+ { 0x83ea2b89, 0x2091e44d, 0x934aed0a, 765 },
+ { 0xa4e4b66b, 0x68b65d60, 0xf81da84d, 768 },
+ { 0xce1de406, 0x42e3f4b9, 0x36251260, 771 },
+ { 0x80d2ae83, 0xe9ce78f3, 0xc1d72b7c, 775 },
+ { 0xa1075a24, 0xe4421730, 0xb24cf65b, 778 },
+ { 0xc94930ae, 0x1d529cfc, 0xdee033f2, 781 },
+ { 0xfb9b7cd9, 0xa4a7443c, 0x169840ef, 784 },
+ { 0x9d412e08, 0x06e88aa5, 0x8e1f2895, 788 },
+ { 0xc491798a, 0x08a2ad4e, 0xf1a6f2ba, 791 },
+ { 0xf5b5d7ec, 0x8acb58a2, 0xae10af69, 794 },
+ { 0x9991a6f3, 0xd6bf1765, 0xacca6da1, 798 },
+ { 0xbff610b0, 0xcc6edd3f, 0x17fd090a, 801 },
+ { 0xeff394dc, 0xff8a948e, 0xddfc4b4c, 804 },
+ { 0x95f83d0a, 0x1fb69cd9, 0x4abdaf10, 808 },
+ { 0xbb764c4c, 0xa7a4440f, 0x9d6d1ad4, 811 },
+ { 0xea53df5f, 0xd18d5513, 0x84c86189, 814 },
+ { 0x92746b9b, 0xe2f8552c, 0x32fd3cf5, 818 },
+ { 0xb7118682, 0xdbb66a77, 0x3fbc8c33, 821 },
+ { 0xe4d5e823, 0x92a40515, 0x0fabaf3f, 824 },
+ { 0x8f05b116, 0x3ba6832d, 0x29cb4d87, 828 },
+ { 0xb2c71d5b, 0xca9023f8, 0x743e20e9, 831 },
+ { 0xdf78e4b2, 0xbd342cf6, 0x914da924, 834 },
+ { 0x8bab8eef, 0xb6409c1a, 0x1ad089b6, 838 },
+ { 0xae9672ab, 0xa3d0c320, 0xa184ac24, 841 },
+ { 0xda3c0f56, 0x8cc4f3e8, 0xc9e5d72d, 844 },
+ { 0x88658996, 0x17fb1871, 0x7e2fa67c, 848 },
+ { 0xaa7eebfb, 0x9df9de8d, 0xddbb901b, 851 },
+ { 0xd51ea6fa, 0x85785631, 0x552a7422, 854 },
+ { 0x8533285c, 0x936b35de, 0xd53a8895, 858 },
+ { 0xa67ff273, 0xb8460356, 0x8a892aba, 861 },
+ { 0xd01fef10, 0xa657842c, 0x2d2b7569, 864 },
+ { 0x8213f56a, 0x67f6b29b, 0x9c3b2962, 868 },
+ { 0xa298f2c5, 0x01f45f42, 0x8349f3ba, 871 },
+ { 0xcb3f2f76, 0x42717713, 0x241c70a9, 874 },
+ { 0xfe0efb53, 0xd30dd4d7, 0xed238cd3, 877 },
+ { 0x9ec95d14, 0x63e8a506, 0xf4363804, 881 },
+ { 0xc67bb459, 0x7ce2ce48, 0xb143c605, 884 },
+ { 0xf81aa16f, 0xdc1b81da, 0xdd94b786, 887 },
+ { 0x9b10a4e5, 0xe9913128, 0xca7cf2b4, 891 },
+ { 0xc1d4ce1f, 0x63f57d72, 0xfd1c2f61, 894 },
+ { 0xf24a01a7, 0x3cf2dccf, 0xbc633b39, 897 },
+ { 0x976e4108, 0x8617ca01, 0xd5be0503, 901 },
+ { 0xbd49d14a, 0xa79dbc82, 0x4b2d8644, 904 },
+ { 0xec9c459d, 0x51852ba2, 0xddf8e7d6, 907 },
+ { 0x93e1ab82, 0x52f33b45, 0xcabb90e5, 911 },
+ { 0xb8da1662, 0xe7b00a17, 0x3d6a751f, 914 },
+ { 0xe7109bfb, 0xa19c0c9d, 0x0cc51267, 917 },
+ { 0x906a617d, 0x450187e2, 0x27fb2b80, 921 },
+ { 0xb484f9dc, 0x9641e9da, 0xb1f9f660, 924 },
+ { 0xe1a63853, 0xbbd26451, 0x5e7873f8, 927 },
+ { 0x8d07e334, 0x55637eb2, 0xdb0b487b, 931 },
+ { 0xb049dc01, 0x6abc5e5f, 0x91ce1a9a, 934 },
+ { 0xdc5c5301, 0xc56b75f7, 0x7641a140, 937 },
+ { 0x89b9b3e1, 0x1b6329ba, 0xa9e904c8, 941 },
+ { 0xac2820d9, 0x623bf429, 0x546345fa, 944 },
+ { 0xd732290f, 0xbacaf133, 0xa97c1779, 947 },
+ { 0x867f59a9, 0xd4bed6c0, 0x49ed8eab, 951 },
+ { 0xa81f3014, 0x49ee8c70, 0x5c68f256, 954 },
+ { 0xd226fc19, 0x5c6a2f8c, 0x73832eec, 957 },
+ { 0x83585d8f, 0xd9c25db7, 0xc831fd53, 961 },
+ { 0xa42e74f3, 0xd032f525, 0xba3e7ca8, 964 },
+ { 0xcd3a1230, 0xc43fb26f, 0x28ce1bd2, 967 },
+ { 0x80444b5e, 0x7aa7cf85, 0x7980d163, 971 },
+ { 0xa0555e36, 0x1951c366, 0xd7e105bc, 974 },
+ { 0xc86ab5c3, 0x9fa63440, 0x8dd9472b, 977 },
+ { 0xfa856334, 0x878fc150, 0xb14f98f6, 980 },
+ { 0x9c935e00, 0xd4b9d8d2, 0x6ed1bf9a, 984 },
+ { 0xc3b83581, 0x09e84f07, 0x0a862f80, 987 },
+ { 0xf4a642e1, 0x4c6262c8, 0xcd27bb61, 990 },
+ { 0x98e7e9cc, 0xcfbd7dbd, 0x8038d51c, 994 },
+ { 0xbf21e440, 0x03acdd2c, 0xe0470a63, 997 },
+ { 0xeeea5d50, 0x04981478, 0x1858ccfc, 1000 },
+ { 0x95527a52, 0x02df0ccb, 0x0f37801e, 1004 },
+ { 0xbaa718e6, 0x8396cffd, 0xd3056025, 1007 },
+ { 0xe950df20, 0x247c83fd, 0x47c6b82e, 1010 },
+ { 0x91d28b74, 0x16cdd27e, 0x4cdc331d, 1014 },
+ { 0xb6472e51, 0x1c81471d, 0xe0133fe4, 1017 },
+ { 0xe3d8f9e5, 0x63a198e5, 0x58180fdd, 1020 },
+ { 0x8e679c2f, 0x5e44ff8f, 0x570f09ea, 1024 },
+ { 0xb201833b, 0x35d63f73, 0x2cd2cc65, 1027 },
+ { 0xde81e40a, 0x034bcf4f, 0xf8077f7e, 1030 },
+ { 0x8b112e86, 0x420f6191, 0xfb04afaf, 1034 },
+ { 0xadd57a27, 0xd29339f6, 0x79c5db9a, 1037 },
+ { 0xd94ad8b1, 0xc7380874, 0x18375281, 1040 },
+ { 0x87cec76f, 0x1c830548, 0x8f229391, 1044 },
+ { 0xa9c2794a, 0xe3a3c69a, 0xb2eb3875, 1047 },
+ { 0xd433179d, 0x9c8cb841, 0x5fa60692, 1050 },
+ { 0x849feec2, 0x81d7f328, 0xdbc7c41b, 1054 },
+ { 0xa5c7ea73, 0x224deff3, 0x12b9b522, 1057 },
+ { 0xcf39e50f, 0xeae16bef, 0xd768226b, 1060 },
+ { 0x81842f29, 0xf2cce375, 0xe6a11583, 1064 },
+ { 0xa1e53af4, 0x6f801c53, 0x60495ae3, 1067 },
+ { 0xca5e89b1, 0x8b602368, 0x385bb19c, 1070 },
+ { 0xfcf62c1d, 0xee382c42, 0x46729e03, 1073 },
+ { 0x9e19db92, 0xb4e31ba9, 0x6c07a2c2, 1077 }
+ };
+ static short int Lhint[2098] = {
+ /*18,*/19, 19, 19, 19, 20, 20, 20, 21, 21,
+ 21, 22, 22, 22, 23, 23, 23, 23, 24, 24,
+ 24, 25, 25, 25, 26, 26, 26, 26, 27, 27,
+ 27, 28, 28, 28, 29, 29, 29, 29, 30, 30,
+ 30, 31, 31, 31, 32, 32, 32, 32, 33, 33,
+ 33, 34, 34, 34, 35, 35, 35, 35, 36, 36,
+ 36, 37, 37, 37, 38, 38, 38, 38, 39, 39,
+ 39, 40, 40, 40, 41, 41, 41, 41, 42, 42,
+ 42, 43, 43, 43, 44, 44, 44, 44, 45, 45,
+ 45, 46, 46, 46, 47, 47, 47, 47, 48, 48,
+ 48, 49, 49, 49, 50, 50, 50, 51, 51, 51,
+ 51, 52, 52, 52, 53, 53, 53, 54, 54, 54,
+ 54, 55, 55, 55, 56, 56, 56, 57, 57, 57,
+ 57, 58, 58, 58, 59, 59, 59, 60, 60, 60,
+ 60, 61, 61, 61, 62, 62, 62, 63, 63, 63,
+ 63, 64, 64, 64, 65, 65, 65, 66, 66, 66,
+ 66, 67, 67, 67, 68, 68, 68, 69, 69, 69,
+ 69, 70, 70, 70, 71, 71, 71, 72, 72, 72,
+ 72, 73, 73, 73, 74, 74, 74, 75, 75, 75,
+ 75, 76, 76, 76, 77, 77, 77, 78, 78, 78,
+ 78, 79, 79, 79, 80, 80, 80, 81, 81, 81,
+ 82, 82, 82, 82, 83, 83, 83, 84, 84, 84,
+ 85, 85, 85, 85, 86, 86, 86, 87, 87, 87,
+ 88, 88, 88, 88, 89, 89, 89, 90, 90, 90,
+ 91, 91, 91, 91, 92, 92, 92, 93, 93, 93,
+ 94, 94, 94, 94, 95, 95, 95, 96, 96, 96,
+ 97, 97, 97, 97, 98, 98, 98, 99, 99, 99,
+ 100, 100, 100, 100, 101, 101, 101, 102, 102, 102,
+ 103, 103, 103, 103, 104, 104, 104, 105, 105, 105,
+ 106, 106, 106, 106, 107, 107, 107, 108, 108, 108,
+ 109, 109, 109, 110, 110, 110, 110, 111, 111, 111,
+ 112, 112, 112, 113, 113, 113, 113, 114, 114, 114,
+ 115, 115, 115, 116, 116, 116, 116, 117, 117, 117,
+ 118, 118, 118, 119, 119, 119, 119, 120, 120, 120,
+ 121, 121, 121, 122, 122, 122, 122, 123, 123, 123,
+ 124, 124, 124, 125, 125, 125, 125, 126, 126, 126,
+ 127, 127, 127, 128, 128, 128, 128, 129, 129, 129,
+ 130, 130, 130, 131, 131, 131, 131, 132, 132, 132,
+ 133, 133, 133, 134, 134, 134, 134, 135, 135, 135,
+ 136, 136, 136, 137, 137, 137, 137, 138, 138, 138,
+ 139, 139, 139, 140, 140, 140, 141, 141, 141, 141,
+ 142, 142, 142, 143, 143, 143, 144, 144, 144, 144,
+ 145, 145, 145, 146, 146, 146, 147, 147, 147, 147,
+ 148, 148, 148, 149, 149, 149, 150, 150, 150, 150,
+ 151, 151, 151, 152, 152, 152, 153, 153, 153, 153,
+ 154, 154, 154, 155, 155, 155, 156, 156, 156, 156,
+ 157, 157, 157, 158, 158, 158, 159, 159, 159, 159,
+ 160, 160, 160, 161, 161, 161, 162, 162, 162, 162,
+ 163, 163, 163, 164, 164, 164, 165, 165, 165, 165,
+ 166, 166, 166, 167, 167, 167, 168, 168, 168, 169,
+ 169, 169, 169, 170, 170, 170, 171, 171, 171, 172,
+ 172, 172, 172, 173, 173, 173, 174, 174, 174, 175,
+ 175, 175, 175, 176, 176, 176, 177, 177, 177, 178,
+ 178, 178, 178, 179, 179, 179, 180, 180, 180, 181,
+ 181, 181, 181, 182, 182, 182, 183, 183, 183, 184,
+ 184, 184, 184, 185, 185, 185, 186, 186, 186, 187,
+ 187, 187, 187, 188, 188, 188, 189, 189, 189, 190,
+ 190, 190, 190, 191, 191, 191, 192, 192, 192, 193,
+ 193, 193, 193, 194, 194, 194, 195, 195, 195, 196,
+ 196, 196, 197, 197, 197, 197, 198, 198, 198, 199,
+ 199, 199, 200, 200, 200, 200, 201, 201, 201, 202,
+ 202, 202, 203, 203, 203, 203, 204, 204, 204, 205,
+ 205, 205, 206, 206, 206, 206, 207, 207, 207, 208,
+ 208, 208, 209, 209, 209, 209, 210, 210, 210, 211,
+ 211, 211, 212, 212, 212, 212, 213, 213, 213, 214,
+ 214, 214, 215, 215, 215, 215, 216, 216, 216, 217,
+ 217, 217, 218, 218, 218, 218, 219, 219, 219, 220,
+ 220, 220, 221, 221, 221, 221, 222, 222, 222, 223,
+ 223, 223, 224, 224, 224, 224, 225, 225, 225, 226,
+ 226, 226, 227, 227, 227, 228, 228, 228, 228, 229,
+ 229, 229, 230, 230, 230, 231, 231, 231, 231, 232,
+ 232, 232, 233, 233, 233, 234, 234, 234, 234, 235,
+ 235, 235, 236, 236, 236, 237, 237, 237, 237, 238,
+ 238, 238, 239, 239, 239, 240, 240, 240, 240, 241,
+ 241, 241, 242, 242, 242, 243, 243, 243, 243, 244,
+ 244, 244, 245, 245, 245, 246, 246, 246, 246, 247,
+ 247, 247, 248, 248, 248, 249, 249, 249, 249, 250,
+ 250, 250, 251, 251, 251, 252, 252, 252, 252, 253,
+ 253, 253, 254, 254, 254, 255, 255, 255, 256, 256,
+ 256, 256, 257, 257, 257, 258, 258, 258, 259, 259,
+ 259, 259, 260, 260, 260, 261, 261, 261, 262, 262,
+ 262, 262, 263, 263, 263, 264, 264, 264, 265, 265,
+ 265, 265, 266, 266, 266, 267, 267, 267, 268, 268,
+ 268, 268, 269, 269, 269, 270, 270, 270, 271, 271,
+ 271, 271, 272, 272, 272, 273, 273, 273, 274, 274,
+ 274, 274, 275, 275, 275, 276, 276, 276, 277, 277,
+ 277, 277, 278, 278, 278, 279, 279, 279, 280, 280,
+ 280, 280, 281, 281, 281, 282, 282, 282, 283, 283,
+ 283, 283, 284, 284, 284, 285, 285, 285, 286, 286,
+ 286, 287, 287, 287, 287, 288, 288, 288, 289, 289,
+ 289, 290, 290, 290, 290, 291, 291, 291, 292, 292,
+ 292, 293, 293, 293, 293, 294, 294, 294, 295, 295,
+ 295, 296, 296, 296, 296, 297, 297, 297, 298, 298,
+ 298, 299, 299, 299, 299, 300, 300, 300, 301, 301,
+ 301, 302, 302, 302, 302, 303, 303, 303, 304, 304,
+ 304, 305, 305, 305, 305, 306, 306, 306, 307, 307,
+ 307, 308, 308, 308, 308, 309, 309, 309, 310, 310,
+ 310, 311, 311, 311, 311, 312, 312, 312, 313, 313,
+ 313, 314, 314, 314, 315, 315, 315, 315, 316, 316,
+ 316, 317, 317, 317, 318, 318, 318, 318, 319, 319,
+ 319, 320, 320, 320, 321, 321, 321, 321, 322, 322,
+ 322, 323, 323, 323, 324, 324, 324, 324, 325, 325,
+ 325, 326, 326, 326, 327, 327, 327, 327, 328, 328,
+ 328, 329, 329, 329, 330, 330, 330, 330, 331, 331,
+ 331, 332, 332, 332, 333, 333, 333, 333, 334, 334,
+ 334, 335, 335, 335, 336, 336, 336, 336, 337, 337,
+ 337, 338, 338, 338, 339, 339, 339, 339, 340, 340,
+ 340, 341, 341, 341, 342, 342, 342, 342, 343, 343,
+ 343, 344, 344, 344, 345, 345, 345, 346, 346, 346,
+ 346, 347, 347, 347, 348, 348, 348, 349, 349, 349,
+ 349, 350, 350, 350, 351, 351, 351, 352, 352, 352,
+ 352, 353, 353, 353, 354, 354, 354, 355, 355, 355,
+ 355, 356, 356, 356, 357, 357, 357, 358, 358, 358,
+ 358, 359, 359, 359, 360, 360, 360, 361, 361, 361,
+ 361, 362, 362, 362, 363, 363, 363, 364, 364, 364,
+ 364, 365, 365, 365, 366, 366, 366, 367, 367, 367,
+ 367, 368, 368, 368, 369, 369, 369, 370, 370, 370,
+ 370, 371, 371, 371, 372, 372, 372, 373, 373, 373,
+ 374, 374, 374, 374, 375, 375, 375, 376, 376, 376,
+ 377, 377, 377, 377, 378, 378, 378, 379, 379, 379,
+ 380, 380, 380, 380, 381, 381, 381, 382, 382, 382,
+ 383, 383, 383, 383, 384, 384, 384, 385, 385, 385,
+ 386, 386, 386, 386, 387, 387, 387, 388, 388, 388,
+ 389, 389, 389, 389, 390, 390, 390, 391, 391, 391,
+ 392, 392, 392, 392, 393, 393, 393, 394, 394, 394,
+ 395, 395, 395, 395, 396, 396, 396, 397, 397, 397,
+ 398, 398, 398, 398, 399, 399, 399, 400, 400, 400,
+ 401, 401, 401, 402, 402, 402, 402, 403, 403, 403,
+ 404, 404, 404, 405, 405, 405, 405, 406, 406, 406,
+ 407, 407, 407, 408, 408, 408, 408, 409, 409, 409,
+ 410, 410, 410, 411, 411, 411, 411, 412, 412, 412,
+ 413, 413, 413, 414, 414, 414, 414, 415, 415, 415,
+ 416, 416, 416, 417, 417, 417, 417, 418, 418, 418,
+ 419, 419, 419, 420, 420, 420, 420, 421, 421, 421,
+ 422, 422, 422, 423, 423, 423, 423, 424, 424, 424,
+ 425, 425, 425, 426, 426, 426, 426, 427, 427, 427,
+ 428, 428, 428, 429, 429, 429, 429, 430, 430, 430,
+ 431, 431, 431, 432, 432, 432, 433, 433, 433, 433,
+ 434, 434, 434, 435, 435, 435, 436, 436, 436, 436,
+ 437, 437, 437, 438, 438, 438, 439, 439, 439, 439,
+ 440, 440, 440, 441, 441, 441, 442, 442, 442, 442,
+ 443, 443, 443, 444, 444, 444, 445, 445, 445, 445,
+ 446, 446, 446, 447, 447, 447, 448, 448, 448, 448,
+ 449, 449, 449, 450, 450, 450, 451, 451, 451, 451,
+ 452, 452, 452, 453, 453, 453, 454, 454, 454, 454,
+ 455, 455, 455, 456, 456, 456, 457, 457, 457, 457,
+ 458, 458, 458, 459, 459, 459, 460, 460, 460, 461,
+ 461, 461, 461, 462, 462, 462, 463, 463, 463, 464,
+ 464, 464, 464, 465, 465, 465, 466, 466, 466, 467,
+ 467, 467, 467, 468, 468, 468, 469, 469, 469, 470,
+ 470, 470, 470, 471, 471, 471, 472, 472, 472, 473,
+ 473, 473, 473, 474, 474, 474, 475, 475, 475, 476,
+ 476, 476, 476, 477, 477, 477, 478, 478, 478, 479,
+ 479, 479, 479, 480, 480, 480, 481, 481, 481, 482,
+ 482, 482, 482, 483, 483, 483, 484, 484, 484, 485,
+ 485, 485, 485, 486, 486, 486, 487, 487, 487, 488,
+ 488, 488, 488, 489, 489, 489, 490, 490, 490, 491,
+ 491, 491, 492, 492, 492, 492, 493, 493, 493, 494,
+ 494, 494, 495, 495, 495, 495, 496, 496, 496, 497,
+ 497, 497, 498, 498, 498, 498, 499, 499, 499, 500,
+ 500, 500, 501, 501, 501, 501, 502, 502, 502, 503,
+ 503, 503, 504, 504, 504, 504, 505, 505, 505, 506,
+ 506, 506, 507, 507, 507, 507, 508, 508, 508, 509,
+ 509, 509, 510, 510, 510, 510, 511, 511, 511, 512,
+ 512, 512, 513, 513, 513, 513, 514, 514, 514, 515,
+ 515, 515, 516, 516, 516, 516, 517, 517, 517, 518,
+ 518, 518, 519, 519, 519, 520, 520, 520, 520, 521,
+ 521, 521, 522, 522, 522, 523, 523, 523, 523, 524,
+ 524, 524, 525, 525, 525, 526, 526, 526, 526, 527,
+ 527, 527, 528, 528, 528, 529, 529, 529, 529, 530,
+ 530, 530, 531, 531, 531, 532, 532, 532, 532, 533,
+ 533, 533, 534, 534, 534, 535, 535, 535, 535, 536,
+ 536, 536, 537, 537, 537, 538, 538, 538, 538, 539,
+ 539, 539, 540, 540, 540, 541, 541, 541, 541, 542,
+ 542, 542, 543, 543, 543, 544, 544, 544, 544, 545,
+ 545, 545, 546, 546, 546, 547, 547, 547, 548, 548,
+ 548, 548, 549, 549, 549, 550, 550, 550, 551, 551,
+ 551, 551, 552, 552, 552, 553, 553, 553, 554, 554,
+ 554, 554, 555, 555, 555, 556, 556, 556, 557, 557,
+ 557, 557, 558, 558, 558, 559, 559, 559, 560, 560,
+ 560, 560, 561, 561, 561, 562, 562, 562, 563, 563,
+ 563, 563, 564, 564, 564, 565, 565, 565, 566, 566,
+ 566, 566, 567, 567, 567, 568, 568, 568, 569, 569,
+ 569, 569, 570, 570, 570, 571, 571, 571, 572, 572,
+ 572, 572, 573, 573, 573, 574, 574, 574, 575, 575,
+ 575, 575, 576, 576, 576, 577, 577, 577, 578, 578,
+ 578, 579, 579, 579, 579, 580, 580, 580, 581, 581,
+ 581, 582, 582, 582, 582, 583, 583, 583, 584, 584,
+ 584, 585, 585, 585, 585, 586, 586, 586, 587, 587,
+ 587, 588, 588, 588, 588, 589, 589, 589, 590, 590,
+ 590, 591, 591, 591, 591, 592, 592, 592, 593, 593,
+ 593, 594, 594, 594, 594, 595, 595, 595, 596, 596,
+ 596, 597, 597, 597, 597, 598, 598, 598, 599, 599,
+ 599, 600, 600, 600, 600, 601, 601, 601, 602, 602,
+ 602, 603, 603, 603, 603, 604, 604, 604, 605, 605,
+ 605, 606, 606, 606, 607, 607, 607, 607, 608, 608,
+ 608, 609, 609, 609, 610, 610, 610, 610, 611, 611,
+ 611, 612, 612, 612, 613, 613, 613, 613, 614, 614,
+ 614, 615, 615, 615, 616, 616, 616, 616, 617, 617,
+ 617, 618, 618, 618, 619, 619, 619, 619, 620, 620,
+ 620, 621, 621, 621, 622, 622, 622, 622, 623, 623,
+ 623, 624, 624, 624, 625, 625, 625, 625, 626, 626,
+ 626, 627, 627, 627, 628, 628, 628, 628, 629, 629,
+ 629, 630, 630, 630, 631, 631, 631, 631, 632, 632,
+ 632, 633, 633, 633, 634, 634, 634, 634, 635, 635,
+ 635, 636, 636, 636, 637, 637, 637, 638, 638, 638,
+ 638, 639, 639, 639, 640, 640, 640, 641, 641, 641,
+ 641, 642, 642, 642, 643, 643, 643, 644, 644, 644,
+ 644, 645, 645, 645, 646, 646, 646, 647, 647, 647,
+ 647, 648, 648, 648, 649, 649, 649, 650, 650 };
+ static ULLong pfive[27] = {
+ 5ll,
+ 25ll,
+ 125ll,
+ 625ll,
+ 3125ll,
+ 15625ll,
+ 78125ll,
+ 390625ll,
+ 1953125ll,
+ 9765625ll,
+ 48828125ll,
+ 244140625ll,
+ 1220703125ll,
+ 6103515625ll,
+ 30517578125ll,
+ 152587890625ll,
+ 762939453125ll,
+ 3814697265625ll,
+ 19073486328125ll,
+ 95367431640625ll,
+ 476837158203125ll,
+ 2384185791015625ll,
+ 11920928955078125ll,
+ 59604644775390625ll,
+ 298023223876953125ll,
+ 1490116119384765625ll,
+ 7450580596923828125ll
+ };
+
+ static int pfivebits[25] = {3, 5, 7, 10, 12, 14, 17, 19, 21, 24, 26, 28, 31,
+ 33, 35, 38, 40, 42, 45, 47, 49, 52, 54, 56, 59};
+#endif /*}*/
+#endif /*}} NO_LONG_LONG */
+
+typedef union { double d; ULong L[2];
+#ifdef USE_BF96
+ ULLong LL;
+#endif
+ } U;
+
+#ifdef IEEE_8087
+#define word0(x) (x)->L[1]
+#define word1(x) (x)->L[0]
+#else
+#define word0(x) (x)->L[0]
+#define word1(x) (x)->L[1]
+#endif
+#define dval(x) (x)->d
+#define LLval(x) (x)->LL
+
+#ifndef STRTOD_DIGLIM
+#define STRTOD_DIGLIM 40
+#endif
+
+#ifdef DIGLIM_DEBUG
+extern int strtod_diglim;
+#else
+#define strtod_diglim STRTOD_DIGLIM
+#endif
+
+/* The following definition of Storeinc is appropriate for MIPS processors.
+ * An alternative that might be better on some machines is
+ * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff)
+ */
+#if defined(IEEE_8087) + defined(VAX)
+#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \
+((unsigned short *)a)[0] = (unsigned short)c, a++)
+#else
+#define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \
+((unsigned short *)a)[1] = (unsigned short)c, a++)
+#endif
+
+/* #define P DBL_MANT_DIG */
+/* Ten_pmax = floor(P*log(2)/log(5)) */
+/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */
+/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
+/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */
+
+#ifdef IEEE_Arith
+#define Exp_shift 20
+#define Exp_shift1 20
+#define Exp_msk1 0x100000
+#define Exp_msk11 0x100000
+#define Exp_mask 0x7ff00000
+#define P 53
+#define Nbits 53
+#define Bias 1023
+#define Emax 1023
+#define Emin (-1022)
+#define Exp_1 0x3ff00000
+#define Exp_11 0x3ff00000
+#define Ebits 11
+#define Frac_mask 0xfffff
+#define Frac_mask1 0xfffff
+#define Ten_pmax 22
+#define Bletch 0x10
+#define Bndry_mask 0xfffff
+#define Bndry_mask1 0xfffff
+#define LSB 1
+#define Sign_bit 0x80000000
+#define Log2P 1
+#define Tiny0 0
+#define Tiny1 1
+#define Quick_max 14
+#define Int_max 14
+#ifndef NO_IEEE_Scale
+#define Avoid_Underflow
+#ifdef Flush_Denorm /* debugging option */
+#undef Sudden_Underflow
+#endif
+#endif
+
+#ifndef Flt_Rounds
+#ifdef FLT_ROUNDS
+#define Flt_Rounds FLT_ROUNDS
+#else
+#define Flt_Rounds 1
+#endif
+#endif /*Flt_Rounds*/
+
+#ifdef Honor_FLT_ROUNDS
+#undef Check_FLT_ROUNDS
+#define Check_FLT_ROUNDS
+#else
+#define Rounding Flt_Rounds
+#endif
+
+#else /* ifndef IEEE_Arith */
+#undef Check_FLT_ROUNDS
+#undef Honor_FLT_ROUNDS
+#undef SET_INEXACT
+#undef Sudden_Underflow
+#define Sudden_Underflow
+#ifdef IBM
+#undef Flt_Rounds
+#define Flt_Rounds 0
+#define Exp_shift 24
+#define Exp_shift1 24
+#define Exp_msk1 0x1000000
+#define Exp_msk11 0x1000000
+#define Exp_mask 0x7f000000
+#define P 14
+#define Nbits 56
+#define Bias 65
+#define Emax 248
+#define Emin (-260)
+#define Exp_1 0x41000000
+#define Exp_11 0x41000000
+#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */
+#define Frac_mask 0xffffff
+#define Frac_mask1 0xffffff
+#define Bletch 4
+#define Ten_pmax 22
+#define Bndry_mask 0xefffff
+#define Bndry_mask1 0xffffff
+#define LSB 1
+#define Sign_bit 0x80000000
+#define Log2P 4
+#define Tiny0 0x100000
+#define Tiny1 0
+#define Quick_max 14
+#define Int_max 15
+#else /* VAX */
+#undef Flt_Rounds
+#define Flt_Rounds 1
+#define Exp_shift 23
+#define Exp_shift1 7
+#define Exp_msk1 0x80
+#define Exp_msk11 0x800000
+#define Exp_mask 0x7f80
+#define P 56
+#define Nbits 56
+#define Bias 129
+#define Emax 126
+#define Emin (-129)
+#define Exp_1 0x40800000
+#define Exp_11 0x4080
+#define Ebits 8
+#define Frac_mask 0x7fffff
+#define Frac_mask1 0xffff007f
+#define Ten_pmax 24
+#define Bletch 2
+#define Bndry_mask 0xffff007f
+#define Bndry_mask1 0xffff007f
+#define LSB 0x10000
+#define Sign_bit 0x8000
+#define Log2P 1
+#define Tiny0 0x80
+#define Tiny1 0
+#define Quick_max 15
+#define Int_max 15
+#endif /* IBM, VAX */
+#endif /* IEEE_Arith */
+
+#ifndef IEEE_Arith
+#define ROUND_BIASED
+#else
+#ifdef ROUND_BIASED_without_Round_Up
+#undef ROUND_BIASED
+#define ROUND_BIASED
+#endif
+#endif
+
+#ifdef RND_PRODQUOT
+#define rounded_product(a,b) a = rnd_prod(a, b)
+#define rounded_quotient(a,b) a = rnd_quot(a, b)
+extern double rnd_prod(double, double), rnd_quot(double, double);
+#else
+#define rounded_product(a,b) a *= b
+#define rounded_quotient(a,b) a /= b
+#endif
+
+#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
+#define Big1 0xffffffff
+
+#ifndef Pack_32
+#define Pack_32
+#endif
+
+typedef struct BCinfo BCinfo;
+ struct
+BCinfo { int dp0, dp1, dplen, dsign, e0, inexact, nd, nd0, rounding, scale, uflchk; };
+
+#define FFFFFFFF 0xffffffffUL
+
+#ifdef MULTIPLE_THREADS
+#define MTa , PTI
+#define MTb , &TI
+#define MTd , ThInfo **PTI
+static unsigned int maxthreads = 0;
+#else
+#define MTa /*nothing*/
+#define MTb /*nothing*/
+#define MTd /*nothing*/
+#endif
+
+#define Kmax 7
+
+#ifdef __cplusplus
+extern "C" double fpconv_strtod(const char *s00, char **se);
+extern "C" char *dtoa(double d, int mode, int ndigits,
+ int *decpt, int *sign, char **rve);
+#endif
+
+ struct
+Bigint {
+ struct Bigint *next;
+ int k, maxwds, sign, wds;
+ ULong x[1];
+ };
+
+ typedef struct Bigint Bigint;
+ typedef struct
+ThInfo {
+ Bigint *Freelist[Kmax+1];
+ Bigint *P5s;
+ } ThInfo;
+
+ static ThInfo TI0;
+
+#ifdef MULTIPLE_THREADS
+ static ThInfo *TI1;
+ static int TI0_used;
+
+ void
+set_max_dtoa_threads(unsigned int n)
+{
+ size_t L;
+
+ if (n > maxthreads) {
+ L = n*sizeof(ThInfo);
+ if (TI1) {
+ TI1 = (ThInfo*)REALLOC(TI1, L);
+ memset(TI1 + maxthreads, 0, (n-maxthreads)*sizeof(ThInfo));
+ }
+ else {
+ TI1 = (ThInfo*)MALLOC(L);
+ if (TI0_used) {
+ memcpy(TI1, &TI0, sizeof(ThInfo));
+ if (n > 1)
+ memset(TI1 + 1, 0, L - sizeof(ThInfo));
+ memset(&TI0, 0, sizeof(ThInfo));
+ }
+ else
+ memset(TI1, 0, L);
+ }
+ maxthreads = n;
+ }
+ }
+
+ static ThInfo*
+get_TI(void)
+{
+ unsigned int thno = dtoa_get_threadno();
+ if (thno < maxthreads)
+ return TI1 + thno;
+ if (thno == 0)
+ TI0_used = 1;
+ return &TI0;
+ }
+#define freelist TI->Freelist
+#define p5s TI->P5s
+#else
+#define freelist TI0.Freelist
+#define p5s TI0.P5s
+#endif
+
+ static Bigint *
+Balloc(int k MTd)
+{
+ int x;
+ Bigint *rv;
+#ifndef Omit_Private_Memory
+ unsigned int len;
+#endif
+#ifdef MULTIPLE_THREADS
+ ThInfo *TI;
+
+ if (!(TI = *PTI))
+ *PTI = TI = get_TI();
+ if (TI == &TI0)
+ ACQUIRE_DTOA_LOCK(0);
+#endif
+ /* The k > Kmax case does not need ACQUIRE_DTOA_LOCK(0), */
+ /* but this case seems very unlikely. */
+ if (k <= Kmax && (rv = freelist[k]))
+ freelist[k] = rv->next;
+ else {
+ x = 1 << k;
+#ifdef Omit_Private_Memory
+ rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong));
+#else
+ len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
+ /sizeof(double);
+ if (k <= Kmax && pmem_next - private_mem + len <= PRIVATE_mem
+#ifdef MULTIPLE_THREADS
+ && TI == TI1
+#endif
+ ) {
+ rv = (Bigint*)pmem_next;
+ pmem_next += len;
+ }
+ else
+ rv = (Bigint*)MALLOC(len*sizeof(double));
+#endif
+ rv->k = k;
+ rv->maxwds = x;
+ }
+#ifdef MULTIPLE_THREADS
+ if (TI == &TI0)
+ FREE_DTOA_LOCK(0);
+#endif
+ rv->sign = rv->wds = 0;
+ return rv;
+ }
+
+ static void
+Bfree(Bigint *v MTd)
+{
+#ifdef MULTIPLE_THREADS
+ ThInfo *TI;
+#endif
+ if (v) {
+ if (v->k > Kmax)
+ FREE((void*)v);
+ else {
+#ifdef MULTIPLE_THREADS
+ if (!(TI = *PTI))
+ *PTI = TI = get_TI();
+ if (TI == &TI0)
+ ACQUIRE_DTOA_LOCK(0);
+#endif
+ v->next = freelist[v->k];
+ freelist[v->k] = v;
+#ifdef MULTIPLE_THREADS
+ if (TI == &TI0)
+ FREE_DTOA_LOCK(0);
+#endif
+ }
+ }
+ }
+
+#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \
+y->wds*sizeof(Long) + 2*sizeof(int))
+
+ static Bigint *
+multadd(Bigint *b, int m, int a MTd) /* multiply by m and add a */
+{
+ int i, wds;
+#ifdef ULLong
+ ULong *x;
+ ULLong carry, y;
+#else
+ ULong carry, *x, y;
+#ifdef Pack_32
+ ULong xi, z;
+#endif
+#endif
+ Bigint *b1;
+
+ wds = b->wds;
+ x = b->x;
+ i = 0;
+ carry = a;
+ do {
+#ifdef ULLong
+ y = *x * (ULLong)m + carry;
+ carry = y >> 32;
+ *x++ = y & FFFFFFFF;
+#else
+#ifdef Pack_32
+ xi = *x;
+ y = (xi & 0xffff) * m + carry;
+ z = (xi >> 16) * m + (y >> 16);
+ carry = z >> 16;
+ *x++ = (z << 16) + (y & 0xffff);
+#else
+ y = *x * m + carry;
+ carry = y >> 16;
+ *x++ = y & 0xffff;
+#endif
+#endif
+ }
+ while(++i < wds);
+ if (carry) {
+ if (wds >= b->maxwds) {
+ b1 = Balloc(b->k+1 MTa);
+ Bcopy(b1, b);
+ Bfree(b MTa);
+ b = b1;
+ }
+ b->x[wds++] = carry;
+ b->wds = wds;
+ }
+ return b;
+ }
+
+ static Bigint *
+s2b(const char *s, int nd0, int nd, ULong y9, int dplen MTd)
+{
+ Bigint *b;
+ int i, k;
+ Long x, y;
+
+ x = (nd + 8) / 9;
+ for(k = 0, y = 1; x > y; y <<= 1, k++) ;
+#ifdef Pack_32
+ b = Balloc(k MTa);
+ b->x[0] = y9;
+ b->wds = 1;
+#else
+ b = Balloc(k+1 MTa);
+ b->x[0] = y9 & 0xffff;
+ b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;
+#endif
+
+ i = 9;
+ if (9 < nd0) {
+ s += 9;
+ do b = multadd(b, 10, *s++ - '0' MTa);
+ while(++i < nd0);
+ s += dplen;
+ }
+ else
+ s += dplen + 9;
+ for(; i < nd; i++)
+ b = multadd(b, 10, *s++ - '0' MTa);
+ return b;
+ }
+
+ static int
+hi0bits(ULong x)
+{
+ int k = 0;
+
+ if (!(x & 0xffff0000)) {
+ k = 16;
+ x <<= 16;
+ }
+ if (!(x & 0xff000000)) {
+ k += 8;
+ x <<= 8;
+ }
+ if (!(x & 0xf0000000)) {
+ k += 4;
+ x <<= 4;
+ }
+ if (!(x & 0xc0000000)) {
+ k += 2;
+ x <<= 2;
+ }
+ if (!(x & 0x80000000)) {
+ k++;
+ if (!(x & 0x40000000))
+ return 32;
+ }
+ return k;
+ }
+
+ static int
+lo0bits(ULong *y)
+{
+ int k;
+ ULong x = *y;
+
+ if (x & 7) {
+ if (x & 1)
+ return 0;
+ if (x & 2) {
+ *y = x >> 1;
+ return 1;
+ }
+ *y = x >> 2;
+ return 2;
+ }
+ k = 0;
+ if (!(x & 0xffff)) {
+ k = 16;
+ x >>= 16;
+ }
+ if (!(x & 0xff)) {
+ k += 8;
+ x >>= 8;
+ }
+ if (!(x & 0xf)) {
+ k += 4;
+ x >>= 4;
+ }
+ if (!(x & 0x3)) {
+ k += 2;
+ x >>= 2;
+ }
+ if (!(x & 1)) {
+ k++;
+ x >>= 1;
+ if (!x)
+ return 32;
+ }
+ *y = x;
+ return k;
+ }
+
+ static Bigint *
+i2b(int i MTd)
+{
+ Bigint *b;
+
+ b = Balloc(1 MTa);
+ b->x[0] = i;
+ b->wds = 1;
+ return b;
+ }
+
+ static Bigint *
+mult(Bigint *a, Bigint *b MTd)
+{
+ Bigint *c;
+ int k, wa, wb, wc;
+ ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
+ ULong y;
+#ifdef ULLong
+ ULLong carry, z;
+#else
+ ULong carry, z;
+#ifdef Pack_32
+ ULong z2;
+#endif
+#endif
+
+ if (a->wds < b->wds) {
+ c = a;
+ a = b;
+ b = c;
+ }
+ k = a->k;
+ wa = a->wds;
+ wb = b->wds;
+ wc = wa + wb;
+ if (wc > a->maxwds)
+ k++;
+ c = Balloc(k MTa);
+ for(x = c->x, xa = x + wc; x < xa; x++)
+ *x = 0;
+ xa = a->x;
+ xae = xa + wa;
+ xb = b->x;
+ xbe = xb + wb;
+ xc0 = c->x;
+#ifdef ULLong
+ for(; xb < xbe; xc0++) {
+ if ((y = *xb++)) {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ do {
+ z = *x++ * (ULLong)y + *xc + carry;
+ carry = z >> 32;
+ *xc++ = z & FFFFFFFF;
+ }
+ while(x < xae);
+ *xc = carry;
+ }
+ }
+#else
+#ifdef Pack_32
+ for(; xb < xbe; xb++, xc0++) {
+ if (y = *xb & 0xffff) {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ do {
+ z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
+ carry = z >> 16;
+ z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
+ carry = z2 >> 16;
+ Storeinc(xc, z2, z);
+ }
+ while(x < xae);
+ *xc = carry;
+ }
+ if (y = *xb >> 16) {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ z2 = *xc;
+ do {
+ z = (*x & 0xffff) * y + (*xc >> 16) + carry;
+ carry = z >> 16;
+ Storeinc(xc, z, z2);
+ z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
+ carry = z2 >> 16;
+ }
+ while(x < xae);
+ *xc = z2;
+ }
+ }
+#else
+ for(; xb < xbe; xc0++) {
+ if (y = *xb++) {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ do {
+ z = *x++ * y + *xc + carry;
+ carry = z >> 16;
+ *xc++ = z & 0xffff;
+ }
+ while(x < xae);
+ *xc = carry;
+ }
+ }
+#endif
+#endif
+ for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
+ c->wds = wc;
+ return c;
+ }
+
+ static Bigint *
+pow5mult(Bigint *b, int k MTd)
+{
+ Bigint *b1, *p5, *p51;
+#ifdef MULTIPLE_THREADS
+ ThInfo *TI;
+#endif
+ int i;
+ static int p05[3] = { 5, 25, 125 };
+
+ if ((i = k & 3))
+ b = multadd(b, p05[i-1], 0 MTa);
+
+ if (!(k >>= 2))
+ return b;
+#ifdef MULTIPLE_THREADS
+ if (!(TI = *PTI))
+ *PTI = TI = get_TI();
+#endif
+ if (!(p5 = p5s)) {
+ /* first time */
+#ifdef MULTIPLE_THREADS
+ if (!(TI = *PTI))
+ *PTI = TI = get_TI();
+ if (TI == &TI0)
+ ACQUIRE_DTOA_LOCK(1);
+ if (!(p5 = p5s)) {
+ p5 = p5s = i2b(625 MTa);
+ p5->next = 0;
+ }
+ if (TI == &TI0)
+ FREE_DTOA_LOCK(1);
+#else
+ p5 = p5s = i2b(625 MTa);
+ p5->next = 0;
+#endif
+ }
+ for(;;) {
+ if (k & 1) {
+ b1 = mult(b, p5 MTa);
+ Bfree(b MTa);
+ b = b1;
+ }
+ if (!(k >>= 1))
+ break;
+ if (!(p51 = p5->next)) {
+#ifdef MULTIPLE_THREADS
+ if (!TI && !(TI = *PTI))
+ *PTI = TI = get_TI();
+ if (TI == &TI0)
+ ACQUIRE_DTOA_LOCK(1);
+ if (!(p51 = p5->next)) {
+ p51 = p5->next = mult(p5,p5 MTa);
+ p51->next = 0;
+ }
+ if (TI == &TI0)
+ FREE_DTOA_LOCK(1);
+#else
+ p51 = p5->next = mult(p5,p5);
+ p51->next = 0;
+#endif
+ }
+ p5 = p51;
+ }
+ return b;
+ }
+
+ static Bigint *
+lshift(Bigint *b, int k MTd)
+{
+ int i, k1, n, n1;
+ Bigint *b1;
+ ULong *x, *x1, *xe, z;
+
+#ifdef Pack_32
+ n = k >> 5;
+#else
+ n = k >> 4;
+#endif
+ k1 = b->k;
+ n1 = n + b->wds + 1;
+ for(i = b->maxwds; n1 > i; i <<= 1)
+ k1++;
+ b1 = Balloc(k1 MTa);
+ x1 = b1->x;
+ for(i = 0; i < n; i++)
+ *x1++ = 0;
+ x = b->x;
+ xe = x + b->wds;
+#ifdef Pack_32
+ if (k &= 0x1f) {
+ k1 = 32 - k;
+ z = 0;
+ do {
+ *x1++ = *x << k | z;
+ z = *x++ >> k1;
+ }
+ while(x < xe);
+ if ((*x1 = z))
+ ++n1;
+ }
+#else
+ if (k &= 0xf) {
+ k1 = 16 - k;
+ z = 0;
+ do {
+ *x1++ = *x << k & 0xffff | z;
+ z = *x++ >> k1;
+ }
+ while(x < xe);
+ if (*x1 = z)
+ ++n1;
+ }
+#endif
+ else do
+ *x1++ = *x++;
+ while(x < xe);
+ b1->wds = n1 - 1;
+ Bfree(b MTa);
+ return b1;
+ }
+
+ static int
+cmp(Bigint *a, Bigint *b)
+{
+ ULong *xa, *xa0, *xb, *xb0;
+ int i, j;
+
+ i = a->wds;
+ j = b->wds;
+#ifdef DEBUG
+ if (i > 1 && !a->x[i-1])
+ Bug("cmp called with a->x[a->wds-1] == 0");
+ if (j > 1 && !b->x[j-1])
+ Bug("cmp called with b->x[b->wds-1] == 0");
+#endif
+ if (i -= j)
+ return i;
+ xa0 = a->x;
+ xa = xa0 + j;
+ xb0 = b->x;
+ xb = xb0 + j;
+ for(;;) {
+ if (*--xa != *--xb)
+ return *xa < *xb ? -1 : 1;
+ if (xa <= xa0)
+ break;
+ }
+ return 0;
+ }
+
+ static Bigint *
+diff(Bigint *a, Bigint *b MTd)
+{
+ Bigint *c;
+ int i, wa, wb;
+ ULong *xa, *xae, *xb, *xbe, *xc;
+#ifdef ULLong
+ ULLong borrow, y;
+#else
+ ULong borrow, y;
+#ifdef Pack_32
+ ULong z;
+#endif
+#endif
+
+ i = cmp(a,b);
+ if (!i) {
+ c = Balloc(0 MTa);
+ c->wds = 1;
+ c->x[0] = 0;
+ return c;
+ }
+ if (i < 0) {
+ c = a;
+ a = b;
+ b = c;
+ i = 1;
+ }
+ else
+ i = 0;
+ c = Balloc(a->k MTa);
+ c->sign = i;
+ wa = a->wds;
+ xa = a->x;
+ xae = xa + wa;
+ wb = b->wds;
+ xb = b->x;
+ xbe = xb + wb;
+ xc = c->x;
+ borrow = 0;
+#ifdef ULLong
+ do {
+ y = (ULLong)*xa++ - *xb++ - borrow;
+ borrow = y >> 32 & (ULong)1;
+ *xc++ = y & FFFFFFFF;
+ }
+ while(xb < xbe);
+ while(xa < xae) {
+ y = *xa++ - borrow;
+ borrow = y >> 32 & (ULong)1;
+ *xc++ = y & FFFFFFFF;
+ }
+#else
+#ifdef Pack_32
+ do {
+ y = (*xa & 0xffff) - (*xb & 0xffff) - borrow;
+ borrow = (y & 0x10000) >> 16;
+ z = (*xa++ >> 16) - (*xb++ >> 16) - borrow;
+ borrow = (z & 0x10000) >> 16;
+ Storeinc(xc, z, y);
+ }
+ while(xb < xbe);
+ while(xa < xae) {
+ y = (*xa & 0xffff) - borrow;
+ borrow = (y & 0x10000) >> 16;
+ z = (*xa++ >> 16) - borrow;
+ borrow = (z & 0x10000) >> 16;
+ Storeinc(xc, z, y);
+ }
+#else
+ do {
+ y = *xa++ - *xb++ - borrow;
+ borrow = (y & 0x10000) >> 16;
+ *xc++ = y & 0xffff;
+ }
+ while(xb < xbe);
+ while(xa < xae) {
+ y = *xa++ - borrow;
+ borrow = (y & 0x10000) >> 16;
+ *xc++ = y & 0xffff;
+ }
+#endif
+#endif
+ while(!*--xc)
+ wa--;
+ c->wds = wa;
+ return c;
+ }
+
+ static double
+ulp(U *x)
+{
+ Long L;
+ U u;
+
+ L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
+#ifndef Avoid_Underflow
+#ifndef Sudden_Underflow
+ if (L > 0) {
+#endif
+#endif
+#ifdef IBM
+ L |= Exp_msk1 >> 4;
+#endif
+ word0(&u) = L;
+ word1(&u) = 0;
+#ifndef Avoid_Underflow
+#ifndef Sudden_Underflow
+ }
+ else {
+ L = -L >> Exp_shift;
+ if (L < Exp_shift) {
+ word0(&u) = 0x80000 >> L;
+ word1(&u) = 0;
+ }
+ else {
+ word0(&u) = 0;
+ L -= Exp_shift;
+ word1(&u) = L >= 31 ? 1 : 1 << 31 - L;
+ }
+ }
+#endif
+#endif
+ return dval(&u);
+ }
+
+ static double
+b2d(Bigint *a, int *e)
+{
+ ULong *xa, *xa0, w, y, z;
+ int k;
+ U d;
+#ifdef VAX
+ ULong d0, d1;
+#else
+#define d0 word0(&d)
+#define d1 word1(&d)
+#endif
+
+ xa0 = a->x;
+ xa = xa0 + a->wds;
+ y = *--xa;
+#ifdef DEBUG
+ if (!y) Bug("zero y in b2d");
+#endif
+ k = hi0bits(y);
+ *e = 32 - k;
+#ifdef Pack_32
+ if (k < Ebits) {
+ d0 = Exp_1 | y >> (Ebits - k);
+ w = xa > xa0 ? *--xa : 0;
+ d1 = y << ((32-Ebits) + k) | w >> (Ebits - k);
+ goto ret_d;
+ }
+ z = xa > xa0 ? *--xa : 0;
+ if (k -= Ebits) {
+ d0 = Exp_1 | y << k | z >> (32 - k);
+ y = xa > xa0 ? *--xa : 0;
+ d1 = z << k | y >> (32 - k);
+ }
+ else {
+ d0 = Exp_1 | y;
+ d1 = z;
+ }
+#else
+ if (k < Ebits + 16) {
+ z = xa > xa0 ? *--xa : 0;
+ d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k;
+ w = xa > xa0 ? *--xa : 0;
+ y = xa > xa0 ? *--xa : 0;
+ d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k;
+ goto ret_d;
+ }
+ z = xa > xa0 ? *--xa : 0;
+ w = xa > xa0 ? *--xa : 0;
+ k -= Ebits + 16;
+ d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k;
+ y = xa > xa0 ? *--xa : 0;
+ d1 = w << k + 16 | y << k;
+#endif
+ ret_d:
+#ifdef VAX
+ word0(&d) = d0 >> 16 | d0 << 16;
+ word1(&d) = d1 >> 16 | d1 << 16;
+#else
+#undef d0
+#undef d1
+#endif
+ return dval(&d);
+ }
+
+ static Bigint *
+d2b(U *d, int *e, int *bits MTd)
+{
+ Bigint *b;
+ int de, k;
+ ULong *x, y, z;
+#ifndef Sudden_Underflow
+ int i;
+#endif
+#ifdef VAX
+ ULong d0, d1;
+ d0 = word0(d) >> 16 | word0(d) << 16;
+ d1 = word1(d) >> 16 | word1(d) << 16;
+#else
+#define d0 word0(d)
+#define d1 word1(d)
+#endif
+
+#ifdef Pack_32
+ b = Balloc(1 MTa);
+#else
+ b = Balloc(2 MTa);
+#endif
+ x = b->x;
+
+ z = d0 & Frac_mask;
+ d0 &= 0x7fffffff; /* clear sign bit, which we ignore */
+#ifdef Sudden_Underflow
+ de = (int)(d0 >> Exp_shift);
+#ifndef IBM
+ z |= Exp_msk11;
+#endif
+#else
+ if ((de = (int)(d0 >> Exp_shift)))
+ z |= Exp_msk1;
+#endif
+#ifdef Pack_32
+ if ((y = d1)) {
+ if ((k = lo0bits(&y))) {
+ x[0] = y | z << (32 - k);
+ z >>= k;
+ }
+ else
+ x[0] = y;
+#ifndef Sudden_Underflow
+ i =
+#endif
+ b->wds = (x[1] = z) ? 2 : 1;
+ }
+ else {
+ k = lo0bits(&z);
+ x[0] = z;
+#ifndef Sudden_Underflow
+ i =
+#endif
+ b->wds = 1;
+ k += 32;
+ }
+#else
+ if (y = d1) {
+ if (k = lo0bits(&y))
+ if (k >= 16) {
+ x[0] = y | z << 32 - k & 0xffff;
+ x[1] = z >> k - 16 & 0xffff;
+ x[2] = z >> k;
+ i = 2;
+ }
+ else {
+ x[0] = y & 0xffff;
+ x[1] = y >> 16 | z << 16 - k & 0xffff;
+ x[2] = z >> k & 0xffff;
+ x[3] = z >> k+16;
+ i = 3;
+ }
+ else {
+ x[0] = y & 0xffff;
+ x[1] = y >> 16;
+ x[2] = z & 0xffff;
+ x[3] = z >> 16;
+ i = 3;
+ }
+ }
+ else {
+#ifdef DEBUG
+ if (!z)
+ Bug("Zero passed to d2b");
+#endif
+ k = lo0bits(&z);
+ if (k >= 16) {
+ x[0] = z;
+ i = 0;
+ }
+ else {
+ x[0] = z & 0xffff;
+ x[1] = z >> 16;
+ i = 1;
+ }
+ k += 32;
+ }
+ while(!x[i])
+ --i;
+ b->wds = i + 1;
+#endif
+#ifndef Sudden_Underflow
+ if (de) {
+#endif
+#ifdef IBM
+ *e = (de - Bias - (P-1) << 2) + k;
+ *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask);
+#else
+ *e = de - Bias - (P-1) + k;
+ *bits = P - k;
+#endif
+#ifndef Sudden_Underflow
+ }
+ else {
+ *e = de - Bias - (P-1) + 1 + k;
+#ifdef Pack_32
+ *bits = 32*i - hi0bits(x[i-1]);
+#else
+ *bits = (i+2)*16 - hi0bits(x[i]);
+#endif
+ }
+#endif
+ return b;
+ }
+#undef d0
+#undef d1
+
+ static double
+ratio(Bigint *a, Bigint *b)
+{
+ U da, db;
+ int k, ka, kb;
+
+ dval(&da) = b2d(a, &ka);
+ dval(&db) = b2d(b, &kb);
+#ifdef Pack_32
+ k = ka - kb + 32*(a->wds - b->wds);
+#else
+ k = ka - kb + 16*(a->wds - b->wds);
+#endif
+#ifdef IBM
+ if (k > 0) {
+ word0(&da) += (k >> 2)*Exp_msk1;
+ if (k &= 3)
+ dval(&da) *= 1 << k;
+ }
+ else {
+ k = -k;
+ word0(&db) += (k >> 2)*Exp_msk1;
+ if (k &= 3)
+ dval(&db) *= 1 << k;
+ }
+#else
+ if (k > 0)
+ word0(&da) += k*Exp_msk1;
+ else {
+ k = -k;
+ word0(&db) += k*Exp_msk1;
+ }
+#endif
+ return dval(&da) / dval(&db);
+ }
+
+ static const double
+tens[] = {
+ 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
+ 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
+ 1e20, 1e21, 1e22
+#ifdef VAX
+ , 1e23, 1e24
+#endif
+ };
+
+ static const double
+#ifdef IEEE_Arith
+bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
+static const double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128,
+#ifdef Avoid_Underflow
+ 9007199254740992.*9007199254740992.e-256
+ /* = 2^106 * 1e-256 */
+#else
+ 1e-256
+#endif
+ };
+/* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */
+/* flag unnecessarily. It leads to a song and dance at the end of strtod. */
+#define Scale_Bit 0x10
+#define n_bigtens 5
+#else
+#ifdef IBM
+bigtens[] = { 1e16, 1e32, 1e64 };
+static const double tinytens[] = { 1e-16, 1e-32, 1e-64 };
+#define n_bigtens 3
+#else
+bigtens[] = { 1e16, 1e32 };
+static const double tinytens[] = { 1e-16, 1e-32 };
+#define n_bigtens 2
+#endif
+#endif
+
+#undef Need_Hexdig
+#ifdef INFNAN_CHECK
+#ifndef No_Hex_NaN
+#define Need_Hexdig
+#endif
+#endif
+
+#ifndef Need_Hexdig
+#ifndef NO_HEX_FP
+#define Need_Hexdig
+#endif
+#endif
+
+#ifdef Need_Hexdig /*{*/
+#if 0
+static unsigned char hexdig[256];
+
+ static void
+htinit(unsigned char *h, unsigned char *s, int inc)
+{
+ int i, j;
+ for(i = 0; (j = s[i]) !=0; i++)
+ h[j] = i + inc;
+ }
+
+ static void
+hexdig_init(void) /* Use of hexdig_init omitted 20121220 to avoid a */
+ /* race condition when multiple threads are used. */
+{
+#define USC (unsigned char *)
+ htinit(hexdig, USC "0123456789", 0x10);
+ htinit(hexdig, USC "abcdef", 0x10 + 10);
+ htinit(hexdig, USC "ABCDEF", 0x10 + 10);
+ }
+#else
+static unsigned char hexdig[256] = {
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 16,17,18,19,20,21,22,23,24,25,0,0,0,0,0,0,
+ 0,26,27,28,29,30,31,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,26,27,28,29,30,31,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+ };
+#endif
+#endif /* } Need_Hexdig */
+
+#ifdef INFNAN_CHECK
+
+#ifndef NAN_WORD0
+#define NAN_WORD0 0x7ff80000
+#endif
+
+#ifndef NAN_WORD1
+#define NAN_WORD1 0
+#endif
+
+ static int
+match(const char **sp, const char *t)
+{
+ int c, d;
+ const char *s = *sp;
+
+ while((d = *t++)) {
+ if ((c = *++s) >= 'A' && c <= 'Z')
+ c += 'a' - 'A';
+ if (c != d)
+ return 0;
+ }
+ *sp = s + 1;
+ return 1;
+ }
+
+#ifndef No_Hex_NaN
+ static void
+hexnan(U *rvp, const char **sp)
+{
+ ULong c, x[2];
+ const char *s;
+ int c1, havedig, udx0, xshift;
+
+ /**** if (!hexdig['0']) hexdig_init(); ****/
+ x[0] = x[1] = 0;
+ havedig = xshift = 0;
+ udx0 = 1;
+ s = *sp;
+ /* allow optional initial 0x or 0X */
+ while((c = *(const unsigned char*)(s+1)) && c <= ' ')
+ ++s;
+ if (s[1] == '0' && (s[2] == 'x' || s[2] == 'X'))
+ s += 2;
+ while((c = *(const unsigned char*)++s)) {
+ if ((c1 = hexdig[c]))
+ c = c1 & 0xf;
+ else if (c <= ' ') {
+ if (udx0 && havedig) {
+ udx0 = 0;
+ xshift = 1;
+ }
+ continue;
+ }
+#ifdef GDTOA_NON_PEDANTIC_NANCHECK
+ else if (/*(*/ c == ')' && havedig) {
+ *sp = s + 1;
+ break;
+ }
+ else
+ return; /* invalid form: don't change *sp */
+#else
+ else {
+ do {
+ if (/*(*/ c == ')') {
+ *sp = s + 1;
+ break;
+ }
+ } while((c = *++s));
+ break;
+ }
+#endif
+ havedig = 1;
+ if (xshift) {
+ xshift = 0;
+ x[0] = x[1];
+ x[1] = 0;
+ }
+ if (udx0)
+ x[0] = (x[0] << 4) | (x[1] >> 28);
+ x[1] = (x[1] << 4) | c;
+ }
+ if ((x[0] &= 0xfffff) || x[1]) {
+ word0(rvp) = Exp_mask | x[0];
+ word1(rvp) = x[1];
+ }
+ }
+#endif /*No_Hex_NaN*/
+#endif /* INFNAN_CHECK */
+
+#ifdef Pack_32
+#define ULbits 32
+#define kshift 5
+#define kmask 31
+#else
+#define ULbits 16
+#define kshift 4
+#define kmask 15
+#endif
+
+#if !defined(NO_HEX_FP) || defined(Honor_FLT_ROUNDS) /*{*/
+ static Bigint *
+increment(Bigint *b MTd)
+{
+ ULong *x, *xe;
+ Bigint *b1;
+
+ x = b->x;
+ xe = x + b->wds;
+ do {
+ if (*x < (ULong)0xffffffffL) {
+ ++*x;
+ return b;
+ }
+ *x++ = 0;
+ } while(x < xe);
+ {
+ if (b->wds >= b->maxwds) {
+ b1 = Balloc(b->k+1 MTa);
+ Bcopy(b1,b);
+ Bfree(b MTa);
+ b = b1;
+ }
+ b->x[b->wds++] = 1;
+ }
+ return b;
+ }
+
+#endif /*}*/
+
+#ifndef NO_HEX_FP /*{*/
+
+ static void
+rshift(Bigint *b, int k)
+{
+ ULong *x, *x1, *xe, y;
+ int n;
+
+ x = x1 = b->x;
+ n = k >> kshift;
+ if (n < b->wds) {
+ xe = x + b->wds;
+ x += n;
+ if (k &= kmask) {
+ n = 32 - k;
+ y = *x++ >> k;
+ while(x < xe) {
+ *x1++ = (y | (*x << n)) & 0xffffffff;
+ y = *x++ >> k;
+ }
+ if ((*x1 = y) !=0)
+ x1++;
+ }
+ else
+ while(x < xe)
+ *x1++ = *x++;
+ }
+ if ((b->wds = x1 - b->x) == 0)
+ b->x[0] = 0;
+ }
+
+ static ULong
+any_on(Bigint *b, int k)
+{
+ int n, nwds;
+ ULong *x, *x0, x1, x2;
+
+ x = b->x;
+ nwds = b->wds;
+ n = k >> kshift;
+ if (n > nwds)
+ n = nwds;
+ else if (n < nwds && (k &= kmask)) {
+ x1 = x2 = x[n];
+ x1 >>= k;
+ x1 <<= k;
+ if (x1 != x2)
+ return 1;
+ }
+ x0 = x;
+ x += n;
+ while(x > x0)
+ if (*--x)
+ return 1;
+ return 0;
+ }
+
+enum { /* rounding values: same as FLT_ROUNDS */
+ Round_zero = 0,
+ Round_near = 1,
+ Round_up = 2,
+ Round_down = 3
+ };
+
+ void
+gethex( const char **sp, U *rvp, int rounding, int sign MTd)
+{
+ Bigint *b;
+ const unsigned char *decpt, *s0, *s, *s1;
+ Long e, e1;
+ ULong L, lostbits, *x;
+ int big, denorm, esign, havedig, k, n, nbits, up, zret;
+#ifdef IBM
+ int j;
+#endif
+ enum {
+#ifdef IEEE_Arith /*{{*/
+ emax = 0x7fe - Bias - P + 1,
+ emin = Emin - P + 1
+#else /*}{*/
+ emin = Emin - P,
+#ifdef VAX
+ emax = 0x7ff - Bias - P + 1
+#endif
+#ifdef IBM
+ emax = 0x7f - Bias - P
+#endif
+#endif /*}}*/
+ };
+#ifdef USE_LOCALE
+ int i;
+#ifdef NO_LOCALE_CACHE
+ const unsigned char *decimalpoint = (unsigned char*)
+ localeconv()->decimal_point;
+#else
+ const unsigned char *decimalpoint;
+ static unsigned char *decimalpoint_cache;
+ if (!(s0 = decimalpoint_cache)) {
+ s0 = (unsigned char*)localeconv()->decimal_point;
+ if ((decimalpoint_cache = (unsigned char*)
+ MALLOC(strlen((const char*)s0) + 1))) {
+ strcpy((char*)decimalpoint_cache, (const char*)s0);
+ s0 = decimalpoint_cache;
+ }
+ }
+ decimalpoint = s0;
+#endif
+#endif
+
+ /**** if (!hexdig['0']) hexdig_init(); ****/
+ havedig = 0;
+ s0 = *(const unsigned char **)sp + 2;
+ while(s0[havedig] == '0')
+ havedig++;
+ s0 += havedig;
+ s = s0;
+ decpt = 0;
+ zret = 0;
+ e = 0;
+ if (hexdig[*s])
+ havedig++;
+ else {
+ zret = 1;
+#ifdef USE_LOCALE
+ for(i = 0; decimalpoint[i]; ++i) {
+ if (s[i] != decimalpoint[i])
+ goto pcheck;
+ }
+ decpt = s += i;
+#else
+ if (*s != '.')
+ goto pcheck;
+ decpt = ++s;
+#endif
+ if (!hexdig[*s])
+ goto pcheck;
+ while(*s == '0')
+ s++;
+ if (hexdig[*s])
+ zret = 0;
+ havedig = 1;
+ s0 = s;
+ }
+ while(hexdig[*s])
+ s++;
+#ifdef USE_LOCALE
+ if (*s == *decimalpoint && !decpt) {
+ for(i = 1; decimalpoint[i]; ++i) {
+ if (s[i] != decimalpoint[i])
+ goto pcheck;
+ }
+ decpt = s += i;
+#else
+ if (*s == '.' && !decpt) {
+ decpt = ++s;
+#endif
+ while(hexdig[*s])
+ s++;
+ }/*}*/
+ if (decpt)
+ e = -(((Long)(s-decpt)) << 2);
+ pcheck:
+ s1 = s;
+ big = esign = 0;
+ switch(*s) {
+ case 'p':
+ case 'P':
+ switch(*++s) {
+ case '-':
+ esign = 1;
+ /* no break */
+ case '+':
+ s++;
+ }
+ if ((n = hexdig[*s]) == 0 || n > 0x19) {
+ s = s1;
+ break;
+ }
+ e1 = n - 0x10;
+ while((n = hexdig[*++s]) !=0 && n <= 0x19) {
+ if (e1 & 0xf8000000)
+ big = 1;
+ e1 = 10*e1 + n - 0x10;
+ }
+ if (esign)
+ e1 = -e1;
+ e += e1;
+ }
+ *sp = (char*)s;
+ if (!havedig)
+ *sp = (char*)s0 - 1;
+ if (zret)
+ goto retz1;
+ if (big) {
+ if (esign) {
+#ifdef IEEE_Arith
+ switch(rounding) {
+ case Round_up:
+ if (sign)
+ break;
+ goto ret_tiny;
+ case Round_down:
+ if (!sign)
+ break;
+ goto ret_tiny;
+ }
+#endif
+ goto retz;
+#ifdef IEEE_Arith
+ ret_tinyf:
+ Bfree(b MTa);
+ ret_tiny:
+ Set_errno(ERANGE);
+ word0(rvp) = 0;
+ word1(rvp) = 1;
+ return;
+#endif /* IEEE_Arith */
+ }
+ switch(rounding) {
+ case Round_near:
+ goto ovfl1;
+ case Round_up:
+ if (!sign)
+ goto ovfl1;
+ goto ret_big;
+ case Round_down:
+ if (sign)
+ goto ovfl1;
+ goto ret_big;
+ }
+ ret_big:
+ word0(rvp) = Big0;
+ word1(rvp) = Big1;
+ return;
+ }
+ n = s1 - s0 - 1;
+ for(k = 0; n > (1 << (kshift-2)) - 1; n >>= 1)
+ k++;
+ b = Balloc(k MTa);
+ x = b->x;
+ n = 0;
+ L = 0;
+#ifdef USE_LOCALE
+ for(i = 0; decimalpoint[i+1]; ++i);
+#endif
+ while(s1 > s0) {
+#ifdef USE_LOCALE
+ if (*--s1 == decimalpoint[i]) {
+ s1 -= i;
+ continue;
+ }
+#else
+ if (*--s1 == '.')
+ continue;
+#endif
+ if (n == ULbits) {
+ *x++ = L;
+ L = 0;
+ n = 0;
+ }
+ L |= (hexdig[*s1] & 0x0f) << n;
+ n += 4;
+ }
+ *x++ = L;
+ b->wds = n = x - b->x;
+ n = ULbits*n - hi0bits(L);
+ nbits = Nbits;
+ lostbits = 0;
+ x = b->x;
+ if (n > nbits) {
+ n -= nbits;
+ if (any_on(b,n)) {
+ lostbits = 1;
+ k = n - 1;
+ if (x[k>>kshift] & 1 << (k & kmask)) {
+ lostbits = 2;
+ if (k > 0 && any_on(b,k))
+ lostbits = 3;
+ }
+ }
+ rshift(b, n);
+ e += n;
+ }
+ else if (n < nbits) {
+ n = nbits - n;
+ b = lshift(b, n MTa);
+ e -= n;
+ x = b->x;
+ }
+ if (e > emax) {
+ ovfl:
+ Bfree(b MTa);
+ ovfl1:
+ Set_errno(ERANGE);
+#ifdef Honor_FLT_ROUNDS
+ switch (rounding) {
+ case Round_zero:
+ goto ret_big;
+ case Round_down:
+ if (!sign)
+ goto ret_big;
+ break;
+ case Round_up:
+ if (sign)
+ goto ret_big;
+ }
+#endif
+ word0(rvp) = Exp_mask;
+ word1(rvp) = 0;
+ return;
+ }
+ denorm = 0;
+ if (e < emin) {
+ denorm = 1;
+ n = emin - e;
+ if (n >= nbits) {
+#ifdef IEEE_Arith /*{*/
+ switch (rounding) {
+ case Round_near:
+ if (n == nbits && (n < 2 || lostbits || any_on(b,n-1)))
+ goto ret_tinyf;
+ break;
+ case Round_up:
+ if (!sign)
+ goto ret_tinyf;
+ break;
+ case Round_down:
+ if (sign)
+ goto ret_tinyf;
+ }
+#endif /* } IEEE_Arith */
+ Bfree(b MTa);
+ retz:
+ Set_errno(ERANGE);
+ retz1:
+ rvp->d = 0.;
+ return;
+ }
+ k = n - 1;
+ if (lostbits)
+ lostbits = 1;
+ else if (k > 0)
+ lostbits = any_on(b,k);
+ if (x[k>>kshift] & 1 << (k & kmask))
+ lostbits |= 2;
+ nbits -= n;
+ rshift(b,n);
+ e = emin;
+ }
+ if (lostbits) {
+ up = 0;
+ switch(rounding) {
+ case Round_zero:
+ break;
+ case Round_near:
+ if (lostbits & 2
+ && (lostbits & 1) | (x[0] & 1))
+ up = 1;
+ break;
+ case Round_up:
+ up = 1 - sign;
+ break;
+ case Round_down:
+ up = sign;
+ }
+ if (up) {
+ k = b->wds;
+ b = increment(b MTa);
+ x = b->x;
+ if (denorm) {
+#if 0
+ if (nbits == Nbits - 1
+ && x[nbits >> kshift] & 1 << (nbits & kmask))
+ denorm = 0; /* not currently used */
+#endif
+ }
+ else if (b->wds > k
+ || ((n = nbits & kmask) !=0
+ && hi0bits(x[k-1]) < 32-n)) {
+ rshift(b,1);
+ if (++e > Emax)
+ goto ovfl;
+ }
+ }
+ }
+#ifdef IEEE_Arith
+ if (denorm)
+ word0(rvp) = b->wds > 1 ? b->x[1] & ~0x100000 : 0;
+ else
+ word0(rvp) = (b->x[1] & ~0x100000) | ((e + 0x3ff + 52) << 20);
+ word1(rvp) = b->x[0];
+#endif
+#ifdef IBM
+ if ((j = e & 3)) {
+ k = b->x[0] & ((1 << j) - 1);
+ rshift(b,j);
+ if (k) {
+ switch(rounding) {
+ case Round_up:
+ if (!sign)
+ increment(b);
+ break;
+ case Round_down:
+ if (sign)
+ increment(b);
+ break;
+ case Round_near:
+ j = 1 << (j-1);
+ if (k & j && ((k & (j-1)) | lostbits))
+ increment(b);
+ }
+ }
+ }
+ e >>= 2;
+ word0(rvp) = b->x[1] | ((e + 65 + 13) << 24);
+ word1(rvp) = b->x[0];
+#endif
+#ifdef VAX
+ /* The next two lines ignore swap of low- and high-order 2 bytes. */
+ /* word0(rvp) = (b->x[1] & ~0x800000) | ((e + 129 + 55) << 23); */
+ /* word1(rvp) = b->x[0]; */
+ word0(rvp) = ((b->x[1] & ~0x800000) >> 16) | ((e + 129 + 55) << 7) | (b->x[1] << 16);
+ word1(rvp) = (b->x[0] >> 16) | (b->x[0] << 16);
+#endif
+ Bfree(b MTa);
+ }
+#endif /*!NO_HEX_FP}*/
+
+ static int
+dshift(Bigint *b, int p2)
+{
+ int rv = hi0bits(b->x[b->wds-1]) - 4;
+ if (p2 > 0)
+ rv -= p2;
+ return rv & kmask;
+ }
+
+ static int
+quorem(Bigint *b, Bigint *S)
+{
+ int n;
+ ULong *bx, *bxe, q, *sx, *sxe;
+#ifdef ULLong
+ ULLong borrow, carry, y, ys;
+#else
+ ULong borrow, carry, y, ys;
+#ifdef Pack_32
+ ULong si, z, zs;
+#endif
+#endif
+
+ n = S->wds;
+#ifdef DEBUG
+ /*debug*/ if (b->wds > n)
+ /*debug*/ Bug("oversize b in quorem");
+#endif
+ if (b->wds < n)
+ return 0;
+ sx = S->x;
+ sxe = sx + --n;
+ bx = b->x;
+ bxe = bx + n;
+ q = *bxe / (*sxe + 1); /* ensure q <= true quotient */
+#ifdef DEBUG
+#ifdef NO_STRTOD_BIGCOMP
+ /*debug*/ if (q > 9)
+#else
+ /* An oversized q is possible when quorem is called from bigcomp and */
+ /* the input is near, e.g., twice the smallest denormalized number. */
+ /*debug*/ if (q > 15)
+#endif
+ /*debug*/ Bug("oversized quotient in quorem");
+#endif
+ if (q) {
+ borrow = 0;
+ carry = 0;
+ do {
+#ifdef ULLong
+ ys = *sx++ * (ULLong)q + carry;
+ carry = ys >> 32;
+ y = *bx - (ys & FFFFFFFF) - borrow;
+ borrow = y >> 32 & (ULong)1;
+ *bx++ = y & FFFFFFFF;
+#else
+#ifdef Pack_32
+ si = *sx++;
+ ys = (si & 0xffff) * q + carry;
+ zs = (si >> 16) * q + (ys >> 16);
+ carry = zs >> 16;
+ y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
+ borrow = (y & 0x10000) >> 16;
+ z = (*bx >> 16) - (zs & 0xffff) - borrow;
+ borrow = (z & 0x10000) >> 16;
+ Storeinc(bx, z, y);
+#else
+ ys = *sx++ * q + carry;
+ carry = ys >> 16;
+ y = *bx - (ys & 0xffff) - borrow;
+ borrow = (y & 0x10000) >> 16;
+ *bx++ = y & 0xffff;
+#endif
+#endif
+ }
+ while(sx <= sxe);
+ if (!*bxe) {
+ bx = b->x;
+ while(--bxe > bx && !*bxe)
+ --n;
+ b->wds = n;
+ }
+ }
+ if (cmp(b, S) >= 0) {
+ q++;
+ borrow = 0;
+ carry = 0;
+ bx = b->x;
+ sx = S->x;
+ do {
+#ifdef ULLong
+ ys = *sx++ + carry;
+ carry = ys >> 32;
+ y = *bx - (ys & FFFFFFFF) - borrow;
+ borrow = y >> 32 & (ULong)1;
+ *bx++ = y & FFFFFFFF;
+#else
+#ifdef Pack_32
+ si = *sx++;
+ ys = (si & 0xffff) + carry;
+ zs = (si >> 16) + (ys >> 16);
+ carry = zs >> 16;
+ y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
+ borrow = (y & 0x10000) >> 16;
+ z = (*bx >> 16) - (zs & 0xffff) - borrow;
+ borrow = (z & 0x10000) >> 16;
+ Storeinc(bx, z, y);
+#else
+ ys = *sx++ + carry;
+ carry = ys >> 16;
+ y = *bx - (ys & 0xffff) - borrow;
+ borrow = (y & 0x10000) >> 16;
+ *bx++ = y & 0xffff;
+#endif
+#endif
+ }
+ while(sx <= sxe);
+ bx = b->x;
+ bxe = bx + n;
+ if (!*bxe) {
+ while(--bxe > bx && !*bxe)
+ --n;
+ b->wds = n;
+ }
+ }
+ return q;
+ }
+
+#if defined(Avoid_Underflow) || !defined(NO_STRTOD_BIGCOMP) /*{*/
+ static double
+sulp(U *x, BCinfo *bc)
+{
+ U u;
+ double rv;
+ int i;
+
+ rv = ulp(x);
+ if (!bc->scale || (i = 2*P + 1 - ((word0(x) & Exp_mask) >> Exp_shift)) <= 0)
+ return rv; /* Is there an example where i <= 0 ? */
+ word0(&u) = Exp_1 + (i << Exp_shift);
+ word1(&u) = 0;
+ return rv * u.d;
+ }
+#endif /*}*/
+
+#ifndef NO_STRTOD_BIGCOMP
+ static void
+bigcomp(U *rv, const char *s0, BCinfo *bc MTd)
+{
+ Bigint *b, *d;
+ int b2, bbits, d2, dd, dig, dsign, i, j, nd, nd0, p2, p5, speccase;
+
+ dsign = bc->dsign;
+ nd = bc->nd;
+ nd0 = bc->nd0;
+ p5 = nd + bc->e0 - 1;
+ speccase = 0;
+#ifndef Sudden_Underflow
+ if (rv->d == 0.) { /* special case: value near underflow-to-zero */
+ /* threshold was rounded to zero */
+ b = i2b(1 MTa);
+ p2 = Emin - P + 1;
+ bbits = 1;
+#ifdef Avoid_Underflow
+ word0(rv) = (P+2) << Exp_shift;
+#else
+ word1(rv) = 1;
+#endif
+ i = 0;
+#ifdef Honor_FLT_ROUNDS
+ if (bc->rounding == 1)
+#endif
+ {
+ speccase = 1;
+ --p2;
+ dsign = 0;
+ goto have_i;
+ }
+ }
+ else
+#endif
+ b = d2b(rv, &p2, &bbits MTa);
+#ifdef Avoid_Underflow
+ p2 -= bc->scale;
+#endif
+ /* floor(log2(rv)) == bbits - 1 + p2 */
+ /* Check for denormal case. */
+ i = P - bbits;
+ if (i > (j = P - Emin - 1 + p2)) {
+#ifdef Sudden_Underflow
+ Bfree(b MTa);
+ b = i2b(1 MTa);
+ p2 = Emin;
+ i = P - 1;
+#ifdef Avoid_Underflow
+ word0(rv) = (1 + bc->scale) << Exp_shift;
+#else
+ word0(rv) = Exp_msk1;
+#endif
+ word1(rv) = 0;
+#else
+ i = j;
+#endif
+ }
+#ifdef Honor_FLT_ROUNDS
+ if (bc->rounding != 1) {
+ if (i > 0)
+ b = lshift(b, i MTa);
+ if (dsign)
+ b = increment(b MTa);
+ }
+ else
+#endif
+ {
+ b = lshift(b, ++i MTa);
+ b->x[0] |= 1;
+ }
+#ifndef Sudden_Underflow
+ have_i:
+#endif
+ p2 -= p5 + i;
+ d = i2b(1 MTa);
+ /* Arrange for convenient computation of quotients:
+ * shift left if necessary so divisor has 4 leading 0 bits.
+ */
+ if (p5 > 0)
+ d = pow5mult(d, p5 MTa);
+ else if (p5 < 0)
+ b = pow5mult(b, -p5 MTa);
+ if (p2 > 0) {
+ b2 = p2;
+ d2 = 0;
+ }
+ else {
+ b2 = 0;
+ d2 = -p2;
+ }
+ i = dshift(d, d2);
+ if ((b2 += i) > 0)
+ b = lshift(b, b2 MTa);
+ if ((d2 += i) > 0)
+ d = lshift(d, d2 MTa);
+
+ /* Now b/d = exactly half-way between the two floating-point values */
+ /* on either side of the input string. Compute first digit of b/d. */
+
+ if (!(dig = quorem(b,d))) {
+ b = multadd(b, 10, 0 MTa); /* very unlikely */
+ dig = quorem(b,d);
+ }
+
+ /* Compare b/d with s0 */
+
+ for(i = 0; i < nd0; ) {
+ if ((dd = s0[i++] - '0' - dig))
+ goto ret;
+ if (!b->x[0] && b->wds == 1) {
+ if (i < nd)
+ dd = 1;
+ goto ret;
+ }
+ b = multadd(b, 10, 0 MTa);
+ dig = quorem(b,d);
+ }
+ for(j = bc->dp1; i++ < nd;) {
+ if ((dd = s0[j++] - '0' - dig))
+ goto ret;
+ if (!b->x[0] && b->wds == 1) {
+ if (i < nd)
+ dd = 1;
+ goto ret;
+ }
+ b = multadd(b, 10, 0 MTa);
+ dig = quorem(b,d);
+ }
+ if (dig > 0 || b->x[0] || b->wds > 1)
+ dd = -1;
+ ret:
+ Bfree(b MTa);
+ Bfree(d MTa);
+#ifdef Honor_FLT_ROUNDS
+ if (bc->rounding != 1) {
+ if (dd < 0) {
+ if (bc->rounding == 0) {
+ if (!dsign)
+ goto retlow1;
+ }
+ else if (dsign)
+ goto rethi1;
+ }
+ else if (dd > 0) {
+ if (bc->rounding == 0) {
+ if (dsign)
+ goto rethi1;
+ goto ret1;
+ }
+ if (!dsign)
+ goto rethi1;
+ dval(rv) += 2.*sulp(rv,bc);
+ }
+ else {
+ bc->inexact = 0;
+ if (dsign)
+ goto rethi1;
+ }
+ }
+ else
+#endif
+ if (speccase) {
+ if (dd <= 0)
+ rv->d = 0.;
+ }
+ else if (dd < 0) {
+ if (!dsign) /* does not happen for round-near */
+retlow1:
+ dval(rv) -= sulp(rv,bc);
+ }
+ else if (dd > 0) {
+ if (dsign) {
+ rethi1:
+ dval(rv) += sulp(rv,bc);
+ }
+ }
+ else {
+ /* Exact half-way case: apply round-even rule. */
+ if ((j = ((word0(rv) & Exp_mask) >> Exp_shift) - bc->scale) <= 0) {
+ i = 1 - j;
+ if (i <= 31) {
+ if (word1(rv) & (0x1 << i))
+ goto odd;
+ }
+ else if (word0(rv) & (0x1 << (i-32)))
+ goto odd;
+ }
+ else if (word1(rv) & 1) {
+ odd:
+ if (dsign)
+ goto rethi1;
+ goto retlow1;
+ }
+ }
+
+#ifdef Honor_FLT_ROUNDS
+ ret1:
+#endif
+ return;
+ }
+#endif /* NO_STRTOD_BIGCOMP */
+
+ double
+fpconv_strtod(const char *s00, char **se)
+{
+ int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, e, e1;
+ int esign, i, j, k, nd, nd0, nf, nz, nz0, nz1, sign;
+ const char *s, *s0, *s1;
+ double aadj, aadj1;
+ Long L;
+ U aadj2, adj, rv, rv0;
+ ULong y, z;
+ BCinfo bc;
+ Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
+#ifdef USE_BF96
+ ULLong bhi, blo, brv, t00, t01, t02, t10, t11, terv, tg, tlo, yz;
+ const BF96 *p10;
+ int bexact, erv;
+#endif
+#ifdef Avoid_Underflow
+ ULong Lsb, Lsb1;
+#endif
+#ifdef SET_INEXACT
+ int oldinexact;
+#endif
+#ifndef NO_STRTOD_BIGCOMP
+ int req_bigcomp = 0;
+#endif
+#ifdef MULTIPLE_THREADS
+ ThInfo *TI = 0;
+#endif
+#ifdef Honor_FLT_ROUNDS /*{*/
+#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */
+ bc.rounding = Flt_Rounds;
+#else /*}{*/
+ bc.rounding = 1;
+ switch(fegetround()) {
+ case FE_TOWARDZERO: bc.rounding = 0; break;
+ case FE_UPWARD: bc.rounding = 2; break;
+ case FE_DOWNWARD: bc.rounding = 3;
+ }
+#endif /*}}*/
+#endif /*}*/
+#ifdef USE_LOCALE
+ const char *s2;
+#endif
+
+ sign = nz0 = nz1 = nz = bc.dplen = bc.uflchk = 0;
+ dval(&rv) = 0.;
+ for(s = s00;;s++) switch(*s) {
+ case '-':
+ sign = 1;
+ /* no break */
+ case '+':
+ if (*++s)
+ goto break2;
+ /* no break */
+ case 0:
+ goto ret0;
+ case '\t':
+ case '\n':
+ case '\v':
+ case '\f':
+ case '\r':
+ case ' ':
+ continue;
+ default:
+ goto break2;
+ }
+ break2:
+ if (*s == '0') {
+#ifndef NO_HEX_FP /*{*/
+ switch(s[1]) {
+ case 'x':
+ case 'X':
+#ifdef Honor_FLT_ROUNDS
+ gethex(&s, &rv, bc.rounding, sign MTb);
+#else
+ gethex(&s, &rv, 1, sign MTb);
+#endif
+ goto ret;
+ }
+#endif /*}*/
+ nz0 = 1;
+ while(*++s == '0') ;
+ if (!*s)
+ goto ret;
+ }
+ s0 = s;
+ nd = nf = 0;
+#ifdef USE_BF96
+ yz = 0;
+ for(; (c = *s) >= '0' && c <= '9'; nd++, s++)
+ if (nd < 19)
+ yz = 10*yz + c - '0';
+#else
+ y = z = 0;
+ for(; (c = *s) >= '0' && c <= '9'; nd++, s++)
+ if (nd < 9)
+ y = 10*y + c - '0';
+ else if (nd < DBL_DIG + 2)
+ z = 10*z + c - '0';
+#endif
+ nd0 = nd;
+ bc.dp0 = bc.dp1 = s - s0;
+ for(s1 = s; s1 > s0 && *--s1 == '0'; )
+ ++nz1;
+#ifdef USE_LOCALE
+ s1 = localeconv()->decimal_point;
+ if (c == *s1) {
+ c = '.';
+ if (*++s1) {
+ s2 = s;
+ for(;;) {
+ if (*++s2 != *s1) {
+ c = 0;
+ break;
+ }
+ if (!*++s1) {
+ s = s2;
+ break;
+ }
+ }
+ }
+ }
+#endif
+ if (c == '.') {
+ c = *++s;
+ bc.dp1 = s - s0;
+ bc.dplen = bc.dp1 - bc.dp0;
+ if (!nd) {
+ for(; c == '0'; c = *++s)
+ nz++;
+ if (c > '0' && c <= '9') {
+ bc.dp0 = s0 - s;
+ bc.dp1 = bc.dp0 + bc.dplen;
+ s0 = s;
+ nf += nz;
+ nz = 0;
+ goto have_dig;
+ }
+ goto dig_done;
+ }
+ for(; c >= '0' && c <= '9'; c = *++s) {
+ have_dig:
+ nz++;
+ if (c -= '0') {
+ nf += nz;
+ i = 1;
+#ifdef USE_BF96
+ for(; i < nz; ++i) {
+ if (++nd <= 19)
+ yz *= 10;
+ }
+ if (++nd <= 19)
+ yz = 10*yz + c;
+#else
+ for(; i < nz; ++i) {
+ if (nd++ < 9)
+ y *= 10;
+ else if (nd <= DBL_DIG + 2)
+ z *= 10;
+ }
+ if (nd++ < 9)
+ y = 10*y + c;
+ else if (nd <= DBL_DIG + 2)
+ z = 10*z + c;
+#endif
+ nz = nz1 = 0;
+ }
+ }
+ }
+ dig_done:
+ e = 0;
+ if (c == 'e' || c == 'E') {
+ if (!nd && !nz && !nz0) {
+ goto ret0;
+ }
+ s00 = s;
+ esign = 0;
+ switch(c = *++s) {
+ case '-':
+ esign = 1;
+ case '+':
+ c = *++s;
+ }
+ if (c >= '0' && c <= '9') {
+ while(c == '0')
+ c = *++s;
+ if (c > '0' && c <= '9') {
+ L = c - '0';
+ s1 = s;
+ while((c = *++s) >= '0' && c <= '9')
+ L = 10*L + c - '0';
+ if (s - s1 > 8 || L > 19999)
+ /* Avoid confusion from exponents
+ * so large that e might overflow.
+ */
+ e = 19999; /* safe for 16 bit ints */
+ else
+ e = (int)L;
+ if (esign)
+ e = -e;
+ }
+ else
+ e = 0;
+ }
+ else
+ s = s00;
+ }
+ if (!nd) {
+ if (!nz && !nz0) {
+#ifdef INFNAN_CHECK /*{*/
+ /* Check for Nan and Infinity */
+ if (!bc.dplen)
+ switch(c) {
+ case 'i':
+ case 'I':
+ if (match(&s,"nf")) {
+ --s;
+ if (!match(&s,"inity"))
+ ++s;
+ word0(&rv) = 0x7ff00000;
+ word1(&rv) = 0;
+ goto ret;
+ }
+ break;
+ case 'n':
+ case 'N':
+ if (match(&s, "an")) {
+ word0(&rv) = NAN_WORD0;
+ word1(&rv) = NAN_WORD1;
+#ifndef No_Hex_NaN
+ if (*s == '(') /*)*/
+ hexnan(&rv, &s);
+#endif
+ goto ret;
+ }
+ }
+#endif /*} INFNAN_CHECK */
+ ret0:
+ s = s00;
+ sign = 0;
+ }
+ goto ret;
+ }
+ bc.e0 = e1 = e -= nf;
+
+ /* Now we have nd0 digits, starting at s0, followed by a
+ * decimal point, followed by nd-nd0 digits. The number we're
+ * after is the integer represented by those digits times
+ * 10**e */
+
+ if (!nd0)
+ nd0 = nd;
+#ifndef USE_BF96
+ k = nd < DBL_DIG + 2 ? nd : DBL_DIG + 2;
+ dval(&rv) = y;
+ if (k > 9) {
+#ifdef SET_INEXACT
+ if (k > DBL_DIG)
+ oldinexact = get_inexact();
+#endif
+ dval(&rv) = tens[k - 9] * dval(&rv) + z;
+ }
+#endif
+ bd0 = 0;
+ if (nd <= DBL_DIG
+#ifndef RND_PRODQUOT
+#ifndef Honor_FLT_ROUNDS
+ && Flt_Rounds == 1
+#endif
+#endif
+ ) {
+#ifdef USE_BF96
+ dval(&rv) = yz;
+#endif
+ if (!e)
+ goto ret;
+#ifndef ROUND_BIASED_without_Round_Up
+ if (e > 0) {
+ if (e <= Ten_pmax) {
+#ifdef SET_INEXACT
+ bc.inexact = 0;
+ oldinexact = 1;
+#endif
+#ifdef VAX
+ goto vax_ovfl_check;
+#else
+#ifdef Honor_FLT_ROUNDS
+ /* round correctly FLT_ROUNDS = 2 or 3 */
+ if (sign) {
+ rv.d = -rv.d;
+ sign = 0;
+ }
+#endif
+ /* rv = */ rounded_product(dval(&rv), tens[e]);
+ goto ret;
+#endif
+ }
+ i = DBL_DIG - nd;
+ if (e <= Ten_pmax + i) {
+ /* A fancier test would sometimes let us do
+ * this for larger i values.
+ */
+#ifdef SET_INEXACT
+ bc.inexact = 0;
+ oldinexact = 1;
+#endif
+#ifdef Honor_FLT_ROUNDS
+ /* round correctly FLT_ROUNDS = 2 or 3 */
+ if (sign) {
+ rv.d = -rv.d;
+ sign = 0;
+ }
+#endif
+ e -= i;
+ dval(&rv) *= tens[i];
+#ifdef VAX
+ /* VAX exponent range is so narrow we must
+ * worry about overflow here...
+ */
+ vax_ovfl_check:
+ word0(&rv) -= P*Exp_msk1;
+ /* rv = */ rounded_product(dval(&rv), tens[e]);
+ if ((word0(&rv) & Exp_mask)
+ > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
+ goto ovfl;
+ word0(&rv) += P*Exp_msk1;
+#else
+ /* rv = */ rounded_product(dval(&rv), tens[e]);
+#endif
+ goto ret;
+ }
+ }
+#ifndef Inaccurate_Divide
+ else if (e >= -Ten_pmax) {
+#ifdef SET_INEXACT
+ bc.inexact = 0;
+ oldinexact = 1;
+#endif
+#ifdef Honor_FLT_ROUNDS
+ /* round correctly FLT_ROUNDS = 2 or 3 */
+ if (sign) {
+ rv.d = -rv.d;
+ sign = 0;
+ }
+#endif
+ /* rv = */ rounded_quotient(dval(&rv), tens[-e]);
+ goto ret;
+ }
+#endif
+#endif /* ROUND_BIASED_without_Round_Up */
+ }
+#ifdef USE_BF96
+ k = nd < 19 ? nd : 19;
+#endif
+ e1 += nd - k; /* scale factor = 10^e1 */
+
+#ifdef IEEE_Arith
+#ifdef SET_INEXACT
+ bc.inexact = 1;
+#ifndef USE_BF96
+ if (k <= DBL_DIG)
+#endif
+ oldinexact = get_inexact();
+#endif
+#ifdef Honor_FLT_ROUNDS
+ if (bc.rounding >= 2) {
+ if (sign)
+ bc.rounding = bc.rounding == 2 ? 0 : 2;
+ else
+ if (bc.rounding != 2)
+ bc.rounding = 0;
+ }
+#endif
+#endif /*IEEE_Arith*/
+
+#ifdef USE_BF96 /*{*/
+ Debug(++dtoa_stats[0]);
+ i = e1 + 342;
+ if (i < 0)
+ goto undfl;
+ if (i > 650)
+ goto ovfl;
+ p10 = &pten[i];
+ brv = yz;
+ /* shift brv left, with i = number of bits shifted */
+ i = 0;
+ if (!(brv & 0xffffffff00000000ull)) {
+ i = 32;
+ brv <<= 32;
+ }
+ if (!(brv & 0xffff000000000000ull)) {
+ i += 16;
+ brv <<= 16;
+ }
+ if (!(brv & 0xff00000000000000ull)) {
+ i += 8;
+ brv <<= 8;
+ }
+ if (!(brv & 0xf000000000000000ull)) {
+ i += 4;
+ brv <<= 4;
+ }
+ if (!(brv & 0xc000000000000000ull)) {
+ i += 2;
+ brv <<= 2;
+ }
+ if (!(brv & 0x8000000000000000ull)) {
+ i += 1;
+ brv <<= 1;
+ }
+ erv = (64 + 0x3fe) + p10->e - i;
+ if (erv <= 0 && nd > 19)
+ goto many_digits; /* denormal: may need to look at all digits */
+ bhi = brv >> 32;
+ blo = brv & 0xffffffffull;
+ /* Unsigned 32-bit ints lie in [0,2^32-1] and */
+ /* unsigned 64-bit ints lie in [0, 2^64-1]. The product of two unsigned */
+ /* 32-bit ints is <= 2^64 - 2*2^32-1 + 1 = 2^64 - 1 - 2*(2^32 - 1), so */
+ /* we can add two unsigned 32-bit ints to the product of two such ints, */
+ /* and 64 bits suffice to contain the result. */
+ t01 = bhi * p10->b1;
+ t10 = blo * p10->b0 + (t01 & 0xffffffffull);
+ t00 = bhi * p10->b0 + (t01 >> 32) + (t10 >> 32);
+ if (t00 & 0x8000000000000000ull) {
+ if ((t00 & 0x3ff) && (~t00 & 0x3fe)) { /* unambiguous result? */
+ if (nd > 19 && ((t00 + (1< 19 && ((t00 + (1<b2;
+ t11 = blo * p10->b1 + (t02 & 0xffffffffull);
+ bexact = 1;
+ if (e1 < 0 || e1 > 41 || (t10 | t11) & 0xffffffffull || nd > 19)
+ bexact = 0;
+ tlo = (t10 & 0xffffffffull) + (t02 >> 32) + (t11 >> 32);
+ if (!bexact && (tlo + 0x10) >> 32 > tlo >> 32)
+ goto many_digits;
+ t00 += tlo >> 32;
+ if (t00 & 0x8000000000000000ull) {
+ if (erv <= 0) { /* denormal result */
+ if (nd >= 20 || !((tlo & 0xfffffff0) | (t00 & 0x3ff)))
+ goto many_digits;
+ denormal:
+ if (erv <= -52) {
+#ifdef Honor_FLT_ROUNDS
+ switch(bc.rounding) {
+ case 0: goto undfl;
+ case 2: goto tiniest;
+ }
+#endif
+ if (erv < -52 || !(t00 & 0x7fffffffffffffffull))
+ goto undfl;
+ goto tiniest;
+ }
+ tg = 1ull << (11 - erv);
+ t00 &= ~(tg - 1); /* clear low bits */
+#ifdef Honor_FLT_ROUNDS
+ switch(bc.rounding) {
+ case 0: goto noround_den;
+ case 2: goto roundup_den;
+ }
+#endif
+ if (t00 & tg) {
+#ifdef Honor_FLT_ROUNDS
+ roundup_den:
+#endif
+ t00 += tg << 1;
+ if (!(t00 & 0x8000000000000000ull)) {
+ if (++erv > 0)
+ goto smallest_normal;
+ t00 = 0x8000000000000000ull;
+ }
+ }
+#ifdef Honor_FLT_ROUNDS
+ noround_den:
+#endif
+ LLval(&rv) = t00 >> (12 - erv);
+ Set_errno(ERANGE);
+ goto ret;
+ }
+ if (bexact) {
+#ifdef SET_INEXACT
+ if (!(t00 & 0x7ff) && !(tlo & 0xffffffffull)) {
+ bc.inexact = 0;
+ goto noround;
+ }
+#endif
+#ifdef Honor_FLT_ROUNDS
+ switch(bc.rounding) {
+ case 2:
+ if (t00 & 0x7ff)
+ goto roundup;
+ case 0: goto noround;
+ }
+#endif
+ if (t00 & 0x400 && (tlo & 0xffffffff) | (t00 & 0xbff))
+ goto roundup;
+ goto noround;
+ }
+ if ((tlo & 0xfffffff0) | (t00 & 0x3ff)
+ && (nd <= 19 || ((t00 + (1ull << i)) & 0xfffffffffffffc00ull)
+ == (t00 & 0xfffffffffffffc00ull))) {
+ /* Unambiguous result. */
+ /* If nd > 19, then incrementing the 19th digit */
+ /* does not affect rv. */
+#ifdef Honor_FLT_ROUNDS
+ switch(bc.rounding) {
+ case 0: goto noround;
+ case 2: goto roundup;
+ }
+#endif
+ if (t00 & 0x400) { /* round up */
+ roundup:
+ t00 += 0x800;
+ if (!(t00 & 0x8000000000000000ull)) {
+ /* rounded up to a power of 2 */
+ if (erv >= 0x7fe)
+ goto ovfl;
+ terv = erv + 1;
+ LLval(&rv) = terv << 52;
+ goto ret;
+ }
+ }
+ noround:
+ if (erv >= 0x7ff)
+ goto ovfl;
+ terv = erv;
+ LLval(&rv) = (terv << 52) | ((t00 & 0x7ffffffffffff800ull) >> 11);
+ goto ret;
+ }
+ }
+ else {
+ if (erv <= 1) { /* denormal result */
+ if (nd >= 20 || !((tlo & 0xfffffff0) | (t00 & 0x1ff)))
+ goto many_digits;
+ denormal1:
+ if (erv <= -51) {
+#ifdef Honor_FLT_ROUNDS
+ switch(bc.rounding) {
+ case 0: goto undfl;
+ case 2: goto tiniest;
+ }
+#endif
+ if (erv < -51 || !(t00 & 0x3fffffffffffffffull))
+ goto undfl;
+ tiniest:
+ LLval(&rv) = 1;
+ Set_errno(ERANGE);
+ goto ret;
+ }
+ tg = 1ull << (11 - erv);
+#ifdef Honor_FLT_ROUNDS
+ switch(bc.rounding) {
+ case 0: goto noround1_den;
+ case 2: goto roundup1_den;
+ }
+#endif
+ if (t00 & tg) {
+#ifdef Honor_FLT_ROUNDS
+ roundup1_den:
+#endif
+ if (0x8000000000000000ull & (t00 += (tg<<1)) && erv == 1) {
+
+ smallest_normal:
+ LLval(&rv) = 0x0010000000000000ull;
+ goto ret;
+ }
+ }
+#ifdef Honor_FLT_ROUNDS
+ noround1_den:
+#endif
+ if (erv <= -52)
+ goto undfl;
+ LLval(&rv) = t00 >> (12 - erv);
+ Set_errno(ERANGE);
+ goto ret;
+ }
+ if (bexact) {
+#ifdef SET_INEXACT
+ if (!(t00 & 0x3ff) && !(tlo & 0xffffffffull)) {
+ bc.inexact = 0;
+ goto noround1;
+ }
+#endif
+#ifdef Honor_FLT_ROUNDS
+ switch(bc.rounding) {
+ case 2:
+ if (t00 & 0x3ff)
+ goto roundup1;
+ case 0: goto noround1;
+ }
+#endif
+ if (t00 & 0x200 && (t00 & 0x5ff || tlo))
+ goto roundup1;
+ goto noround1;
+ }
+ if ((tlo & 0xfffffff0) | (t00 & 0x1ff)
+ && (nd <= 19 || ((t00 + (1ull << i)) & 0x7ffffffffffffe00ull)
+ == (t00 & 0x7ffffffffffffe00ull))) {
+ /* Unambiguous result. */
+#ifdef Honor_FLT_ROUNDS
+ switch(bc.rounding) {
+ case 0: goto noround1;
+ case 2: goto roundup1;
+ }
+#endif
+ if (t00 & 0x200) { /* round up */
+ roundup1:
+ t00 += 0x400;
+ if (!(t00 & 0x4000000000000000ull)) {
+ /* rounded up to a power of 2 */
+ if (erv >= 0x7ff)
+ goto ovfl;
+ terv = erv;
+ LLval(&rv) = terv << 52;
+ goto ret;
+ }
+ }
+ noround1:
+ if (erv >= 0x800)
+ goto ovfl;
+ terv = erv - 1;
+ LLval(&rv) = (terv << 52) | ((t00 & 0x3ffffffffffffc00ull) >> 10);
+ goto ret;
+ }
+ }
+ many_digits:
+ Debug(++dtoa_stats[2]);
+ if (nd > 17) {
+ if (nd > 18) {
+ yz /= 100;
+ e1 += 2;
+ }
+ else {
+ yz /= 10;
+ e1 += 1;
+ }
+ y = yz / 100000000;
+ }
+ else if (nd > 9) {
+ i = nd - 9;
+ y = (yz >> i) / pfive[i-1];
+ }
+ else
+ y = yz;
+ dval(&rv) = yz;
+#endif /*}*/
+
+#ifdef IEEE_Arith
+#ifdef Avoid_Underflow
+ bc.scale = 0;
+#endif
+#endif /*IEEE_Arith*/
+
+ /* Get starting approximation = rv * 10**e1 */
+
+ if (e1 > 0) {
+ if ((i = e1 & 15))
+ dval(&rv) *= tens[i];
+ if (e1 &= ~15) {
+ if (e1 > DBL_MAX_10_EXP) {
+ ovfl:
+ /* Can't trust HUGE_VAL */
+#ifdef IEEE_Arith
+#ifdef Honor_FLT_ROUNDS
+ switch(bc.rounding) {
+ case 0: /* toward 0 */
+ case 3: /* toward -infinity */
+ word0(&rv) = Big0;
+ word1(&rv) = Big1;
+ break;
+ default:
+ word0(&rv) = Exp_mask;
+ word1(&rv) = 0;
+ }
+#else /*Honor_FLT_ROUNDS*/
+ word0(&rv) = Exp_mask;
+ word1(&rv) = 0;
+#endif /*Honor_FLT_ROUNDS*/
+#ifdef SET_INEXACT
+ /* set overflow bit */
+ dval(&rv0) = 1e300;
+ dval(&rv0) *= dval(&rv0);
+#endif
+#else /*IEEE_Arith*/
+ word0(&rv) = Big0;
+ word1(&rv) = Big1;
+#endif /*IEEE_Arith*/
+ range_err:
+ if (bd0) {
+ Bfree(bb MTb);
+ Bfree(bd MTb);
+ Bfree(bs MTb);
+ Bfree(bd0 MTb);
+ Bfree(delta MTb);
+ }
+ Set_errno(ERANGE);
+ goto ret;
+ }
+ e1 >>= 4;
+ for(j = 0; e1 > 1; j++, e1 >>= 1)
+ if (e1 & 1)
+ dval(&rv) *= bigtens[j];
+ /* The last multiplication could overflow. */
+ word0(&rv) -= P*Exp_msk1;
+ dval(&rv) *= bigtens[j];
+ if ((z = word0(&rv) & Exp_mask)
+ > Exp_msk1*(DBL_MAX_EXP+Bias-P))
+ goto ovfl;
+ if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
+ /* set to largest number */
+ /* (Can't trust DBL_MAX) */
+ word0(&rv) = Big0;
+ word1(&rv) = Big1;
+ }
+ else
+ word0(&rv) += P*Exp_msk1;
+ }
+ }
+ else if (e1 < 0) {
+ e1 = -e1;
+ if ((i = e1 & 15))
+ dval(&rv) /= tens[i];
+ if (e1 >>= 4) {
+ if (e1 >= 1 << n_bigtens)
+ goto undfl;
+#ifdef Avoid_Underflow
+ if (e1 & Scale_Bit)
+ bc.scale = 2*P;
+ for(j = 0; e1 > 0; j++, e1 >>= 1)
+ if (e1 & 1)
+ dval(&rv) *= tinytens[j];
+ if (bc.scale && (j = 2*P + 1 - ((word0(&rv) & Exp_mask)
+ >> Exp_shift)) > 0) {
+ /* scaled rv is denormal; clear j low bits */
+ if (j >= 32) {
+ if (j > 54)
+ goto undfl;
+ word1(&rv) = 0;
+ if (j >= 53)
+ word0(&rv) = (P+2)*Exp_msk1;
+ else
+ word0(&rv) &= 0xffffffff << (j-32);
+ }
+ else
+ word1(&rv) &= 0xffffffff << j;
+ }
+#else
+ for(j = 0; e1 > 1; j++, e1 >>= 1)
+ if (e1 & 1)
+ dval(&rv) *= tinytens[j];
+ /* The last multiplication could underflow. */
+ dval(&rv0) = dval(&rv);
+ dval(&rv) *= tinytens[j];
+ if (!dval(&rv)) {
+ dval(&rv) = 2.*dval(&rv0);
+ dval(&rv) *= tinytens[j];
+#endif
+ if (!dval(&rv)) {
+ undfl:
+ dval(&rv) = 0.;
+#ifdef Honor_FLT_ROUNDS
+ if (bc.rounding == 2)
+ word1(&rv) = 1;
+#endif
+ goto range_err;
+ }
+#ifndef Avoid_Underflow
+ word0(&rv) = Tiny0;
+ word1(&rv) = Tiny1;
+ /* The refinement below will clean
+ * this approximation up.
+ */
+ }
+#endif
+ }
+ }
+
+ /* Now the hard part -- adjusting rv to the correct value.*/
+
+ /* Put digits into bd: true value = bd * 10^e */
+
+ bc.nd = nd - nz1;
+#ifndef NO_STRTOD_BIGCOMP
+ bc.nd0 = nd0; /* Only needed if nd > strtod_diglim, but done here */
+ /* to silence an erroneous warning about bc.nd0 */
+ /* possibly not being initialized. */
+ if (nd > strtod_diglim) {
+ /* ASSERT(strtod_diglim >= 18); 18 == one more than the */
+ /* minimum number of decimal digits to distinguish double values */
+ /* in IEEE arithmetic. */
+ i = j = 18;
+ if (i > nd0)
+ j += bc.dplen;
+ for(;;) {
+ if (--j < bc.dp1 && j >= bc.dp0)
+ j = bc.dp0 - 1;
+ if (s0[j] != '0')
+ break;
+ --i;
+ }
+ e += nd - i;
+ nd = i;
+ if (nd0 > nd)
+ nd0 = nd;
+ if (nd < 9) { /* must recompute y */
+ y = 0;
+ for(i = 0; i < nd0; ++i)
+ y = 10*y + s0[i] - '0';
+ for(j = bc.dp1; i < nd; ++i)
+ y = 10*y + s0[j++] - '0';
+ }
+ }
+#endif
+ bd0 = s2b(s0, nd0, nd, y, bc.dplen MTb);
+
+ for(;;) {
+ bd = Balloc(bd0->k MTb);
+ Bcopy(bd, bd0);
+ bb = d2b(&rv, &bbe, &bbbits MTb); /* rv = bb * 2^bbe */
+ bs = i2b(1 MTb);
+
+ if (e >= 0) {
+ bb2 = bb5 = 0;
+ bd2 = bd5 = e;
+ }
+ else {
+ bb2 = bb5 = -e;
+ bd2 = bd5 = 0;
+ }
+ if (bbe >= 0)
+ bb2 += bbe;
+ else
+ bd2 -= bbe;
+ bs2 = bb2;
+#ifdef Honor_FLT_ROUNDS
+ if (bc.rounding != 1)
+ bs2++;
+#endif
+#ifdef Avoid_Underflow
+ Lsb = LSB;
+ Lsb1 = 0;
+ j = bbe - bc.scale;
+ i = j + bbbits - 1; /* logb(rv) */
+ j = P + 1 - bbbits;
+ if (i < Emin) { /* denormal */
+ i = Emin - i;
+ j -= i;
+ if (i < 32)
+ Lsb <<= i;
+ else if (i < 52)
+ Lsb1 = Lsb << (i-32);
+ else
+ Lsb1 = Exp_mask;
+ }
+#else /*Avoid_Underflow*/
+#ifdef Sudden_Underflow
+#ifdef IBM
+ j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
+#else
+ j = P + 1 - bbbits;
+#endif
+#else /*Sudden_Underflow*/
+ j = bbe;
+ i = j + bbbits - 1; /* logb(rv) */
+ if (i < Emin) /* denormal */
+ j += P - Emin;
+ else
+ j = P + 1 - bbbits;
+#endif /*Sudden_Underflow*/
+#endif /*Avoid_Underflow*/
+ bb2 += j;
+ bd2 += j;
+#ifdef Avoid_Underflow
+ bd2 += bc.scale;
+#endif
+ i = bb2 < bd2 ? bb2 : bd2;
+ if (i > bs2)
+ i = bs2;
+ if (i > 0) {
+ bb2 -= i;
+ bd2 -= i;
+ bs2 -= i;
+ }
+ if (bb5 > 0) {
+ bs = pow5mult(bs, bb5 MTb);
+ bb1 = mult(bs, bb MTb);
+ Bfree(bb MTb);
+ bb = bb1;
+ }
+ if (bb2 > 0)
+ bb = lshift(bb, bb2 MTb);
+ if (bd5 > 0)
+ bd = pow5mult(bd, bd5 MTb);
+ if (bd2 > 0)
+ bd = lshift(bd, bd2 MTb);
+ if (bs2 > 0)
+ bs = lshift(bs, bs2 MTb);
+ delta = diff(bb, bd MTb);
+ bc.dsign = delta->sign;
+ delta->sign = 0;
+ i = cmp(delta, bs);
+#ifndef NO_STRTOD_BIGCOMP /*{*/
+ if (bc.nd > nd && i <= 0) {
+ if (bc.dsign) {
+ /* Must use bigcomp(). */
+ req_bigcomp = 1;
+ break;
+ }
+#ifdef Honor_FLT_ROUNDS
+ if (bc.rounding != 1) {
+ if (i < 0) {
+ req_bigcomp = 1;
+ break;
+ }
+ }
+ else
+#endif
+ i = -1; /* Discarded digits make delta smaller. */
+ }
+#endif /*}*/
+#ifdef Honor_FLT_ROUNDS /*{*/
+ if (bc.rounding != 1) {
+ if (i < 0) {
+ /* Error is less than an ulp */
+ if (!delta->x[0] && delta->wds <= 1) {
+ /* exact */
+#ifdef SET_INEXACT
+ bc.inexact = 0;
+#endif
+ break;
+ }
+ if (bc.rounding) {
+ if (bc.dsign) {
+ adj.d = 1.;
+ goto apply_adj;
+ }
+ }
+ else if (!bc.dsign) {
+ adj.d = -1.;
+ if (!word1(&rv)
+ && !(word0(&rv) & Frac_mask)) {
+ y = word0(&rv) & Exp_mask;
+#ifdef Avoid_Underflow
+ if (!bc.scale || y > 2*P*Exp_msk1)
+#else
+ if (y)
+#endif
+ {
+ delta = lshift(delta,Log2P MTb);
+ if (cmp(delta, bs) <= 0)
+ adj.d = -0.5;
+ }
+ }
+ apply_adj:
+#ifdef Avoid_Underflow /*{*/
+ if (bc.scale && (y = word0(&rv) & Exp_mask)
+ <= 2*P*Exp_msk1)
+ word0(&adj) += (2*P+1)*Exp_msk1 - y;
+#else
+#ifdef Sudden_Underflow
+ if ((word0(&rv) & Exp_mask) <=
+ P*Exp_msk1) {
+ word0(&rv) += P*Exp_msk1;
+ dval(&rv) += adj.d*ulp(dval(&rv));
+ word0(&rv) -= P*Exp_msk1;
+ }
+ else
+#endif /*Sudden_Underflow*/
+#endif /*Avoid_Underflow}*/
+ dval(&rv) += adj.d*ulp(&rv);
+ }
+ break;
+ }
+ adj.d = ratio(delta, bs);
+ if (adj.d < 1.)
+ adj.d = 1.;
+ if (adj.d <= 0x7ffffffe) {
+ /* adj = rounding ? ceil(adj) : floor(adj); */
+ y = adj.d;
+ if (y != adj.d) {
+ if (!((bc.rounding>>1) ^ bc.dsign))
+ y++;
+ adj.d = y;
+ }
+ }
+#ifdef Avoid_Underflow /*{*/
+ if (bc.scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1)
+ word0(&adj) += (2*P+1)*Exp_msk1 - y;
+#else
+#ifdef Sudden_Underflow
+ if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) {
+ word0(&rv) += P*Exp_msk1;
+ adj.d *= ulp(dval(&rv));
+ if (bc.dsign)
+ dval(&rv) += adj.d;
+ else
+ dval(&rv) -= adj.d;
+ word0(&rv) -= P*Exp_msk1;
+ goto cont;
+ }
+#endif /*Sudden_Underflow*/
+#endif /*Avoid_Underflow}*/
+ adj.d *= ulp(&rv);
+ if (bc.dsign) {
+ if (word0(&rv) == Big0 && word1(&rv) == Big1)
+ goto ovfl;
+ dval(&rv) += adj.d;
+ }
+ else
+ dval(&rv) -= adj.d;
+ goto cont;
+ }
+#endif /*}Honor_FLT_ROUNDS*/
+
+ if (i < 0) {
+ /* Error is less than half an ulp -- check for
+ * special case of mantissa a power of two.
+ */
+ if (bc.dsign || word1(&rv) || word0(&rv) & Bndry_mask
+#ifdef IEEE_Arith /*{*/
+#ifdef Avoid_Underflow
+ || (word0(&rv) & Exp_mask) <= (2*P+1)*Exp_msk1
+#else
+ || (word0(&rv) & Exp_mask) <= Exp_msk1
+#endif
+#endif /*}*/
+ ) {
+#ifdef SET_INEXACT
+ if (!delta->x[0] && delta->wds <= 1)
+ bc.inexact = 0;
+#endif
+ break;
+ }
+ if (!delta->x[0] && delta->wds <= 1) {
+ /* exact result */
+#ifdef SET_INEXACT
+ bc.inexact = 0;
+#endif
+ break;
+ }
+ delta = lshift(delta,Log2P MTb);
+ if (cmp(delta, bs) > 0)
+ goto drop_down;
+ break;
+ }
+ if (i == 0) {
+ /* exactly half-way between */
+ if (bc.dsign) {
+ if ((word0(&rv) & Bndry_mask1) == Bndry_mask1
+ && word1(&rv) == (
+#ifdef Avoid_Underflow
+ (bc.scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1)
+ ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) :
+#endif
+ 0xffffffff)) {
+ /*boundary case -- increment exponent*/
+ if (word0(&rv) == Big0 && word1(&rv) == Big1)
+ goto ovfl;
+ word0(&rv) = (word0(&rv) & Exp_mask)
+ + Exp_msk1
+#ifdef IBM
+ | Exp_msk1 >> 4
+#endif
+ ;
+ word1(&rv) = 0;
+#ifdef Avoid_Underflow
+ bc.dsign = 0;
+#endif
+ break;
+ }
+ }
+ else if (!(word0(&rv) & Bndry_mask) && !word1(&rv)) {
+ drop_down:
+ /* boundary case -- decrement exponent */
+#ifdef Sudden_Underflow /*{{*/
+ L = word0(&rv) & Exp_mask;
+#ifdef IBM
+ if (L < Exp_msk1)
+#else
+#ifdef Avoid_Underflow
+ if (L <= (bc.scale ? (2*P+1)*Exp_msk1 : Exp_msk1))
+#else
+ if (L <= Exp_msk1)
+#endif /*Avoid_Underflow*/
+#endif /*IBM*/
+ {
+ if (bc.nd >nd) {
+ bc.uflchk = 1;
+ break;
+ }
+ goto undfl;
+ }
+ L -= Exp_msk1;
+#else /*Sudden_Underflow}{*/
+#ifdef Avoid_Underflow
+ if (bc.scale) {
+ L = word0(&rv) & Exp_mask;
+ if (L <= (2*P+1)*Exp_msk1) {
+ if (L > (P+2)*Exp_msk1)
+ /* round even ==> */
+ /* accept rv */
+ break;
+ /* rv = smallest denormal */
+ if (bc.nd >nd) {
+ bc.uflchk = 1;
+ break;
+ }
+ goto undfl;
+ }
+ }
+#endif /*Avoid_Underflow*/
+ L = (word0(&rv) & Exp_mask) - Exp_msk1;
+#endif /*Sudden_Underflow}}*/
+ word0(&rv) = L | Bndry_mask1;
+ word1(&rv) = 0xffffffff;
+#ifdef IBM
+ goto cont;
+#else
+#ifndef NO_STRTOD_BIGCOMP
+ if (bc.nd > nd)
+ goto cont;
+#endif
+ break;
+#endif
+ }
+#ifndef ROUND_BIASED
+#ifdef Avoid_Underflow
+ if (Lsb1) {
+ if (!(word0(&rv) & Lsb1))
+ break;
+ }
+ else if (!(word1(&rv) & Lsb))
+ break;
+#else
+ if (!(word1(&rv) & LSB))
+ break;
+#endif
+#endif
+ if (bc.dsign)
+#ifdef Avoid_Underflow
+ dval(&rv) += sulp(&rv, &bc);
+#else
+ dval(&rv) += ulp(&rv);
+#endif
+#ifndef ROUND_BIASED
+ else {
+#ifdef Avoid_Underflow
+ dval(&rv) -= sulp(&rv, &bc);
+#else
+ dval(&rv) -= ulp(&rv);
+#endif
+#ifndef Sudden_Underflow
+ if (!dval(&rv)) {
+ if (bc.nd >nd) {
+ bc.uflchk = 1;
+ break;
+ }
+ goto undfl;
+ }
+#endif
+ }
+#ifdef Avoid_Underflow
+ bc.dsign = 1 - bc.dsign;
+#endif
+#endif
+ break;
+ }
+ if ((aadj = ratio(delta, bs)) <= 2.) {
+ if (bc.dsign)
+ aadj = aadj1 = 1.;
+ else if (word1(&rv) || word0(&rv) & Bndry_mask) {
+#ifndef Sudden_Underflow
+ if (word1(&rv) == Tiny1 && !word0(&rv)) {
+ if (bc.nd >nd) {
+ bc.uflchk = 1;
+ break;
+ }
+ goto undfl;
+ }
+#endif
+ aadj = 1.;
+ aadj1 = -1.;
+ }
+ else {
+ /* special case -- power of FLT_RADIX to be */
+ /* rounded down... */
+
+ if (aadj < 2./FLT_RADIX)
+ aadj = 1./FLT_RADIX;
+ else
+ aadj *= 0.5;
+ aadj1 = -aadj;
+ }
+ }
+ else {
+ aadj *= 0.5;
+ aadj1 = bc.dsign ? aadj : -aadj;
+#ifdef Check_FLT_ROUNDS
+ switch(bc.rounding) {
+ case 2: /* towards +infinity */
+ aadj1 -= 0.5;
+ break;
+ case 0: /* towards 0 */
+ case 3: /* towards -infinity */
+ aadj1 += 0.5;
+ }
+#else
+ if (Flt_Rounds == 0)
+ aadj1 += 0.5;
+#endif /*Check_FLT_ROUNDS*/
+ }
+ y = word0(&rv) & Exp_mask;
+
+ /* Check for overflow */
+
+ if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
+ dval(&rv0) = dval(&rv);
+ word0(&rv) -= P*Exp_msk1;
+ adj.d = aadj1 * ulp(&rv);
+ dval(&rv) += adj.d;
+ if ((word0(&rv) & Exp_mask) >=
+ Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
+ if (word0(&rv0) == Big0 && word1(&rv0) == Big1)
+ goto ovfl;
+ word0(&rv) = Big0;
+ word1(&rv) = Big1;
+ goto cont;
+ }
+ else
+ word0(&rv) += P*Exp_msk1;
+ }
+ else {
+#ifdef Avoid_Underflow
+ if (bc.scale && y <= 2*P*Exp_msk1) {
+ if (aadj <= 0x7fffffff) {
+ if ((z = aadj) <= 0)
+ z = 1;
+ aadj = z;
+ aadj1 = bc.dsign ? aadj : -aadj;
+ }
+ dval(&aadj2) = aadj1;
+ word0(&aadj2) += (2*P+1)*Exp_msk1 - y;
+ aadj1 = dval(&aadj2);
+ adj.d = aadj1 * ulp(&rv);
+ dval(&rv) += adj.d;
+ if (rv.d == 0.)
+#ifdef NO_STRTOD_BIGCOMP
+ goto undfl;
+#else
+ {
+ req_bigcomp = 1;
+ break;
+ }
+#endif
+ }
+ else {
+ adj.d = aadj1 * ulp(&rv);
+ dval(&rv) += adj.d;
+ }
+#else
+#ifdef Sudden_Underflow
+ if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) {
+ dval(&rv0) = dval(&rv);
+ word0(&rv) += P*Exp_msk1;
+ adj.d = aadj1 * ulp(&rv);
+ dval(&rv) += adj.d;
+#ifdef IBM
+ if ((word0(&rv) & Exp_mask) < P*Exp_msk1)
+#else
+ if ((word0(&rv) & Exp_mask) <= P*Exp_msk1)
+#endif
+ {
+ if (word0(&rv0) == Tiny0
+ && word1(&rv0) == Tiny1) {
+ if (bc.nd >nd) {
+ bc.uflchk = 1;
+ break;
+ }
+ goto undfl;
+ }
+ word0(&rv) = Tiny0;
+ word1(&rv) = Tiny1;
+ goto cont;
+ }
+ else
+ word0(&rv) -= P*Exp_msk1;
+ }
+ else {
+ adj.d = aadj1 * ulp(&rv);
+ dval(&rv) += adj.d;
+ }
+#else /*Sudden_Underflow*/
+ /* Compute adj so that the IEEE rounding rules will
+ * correctly round rv + adj in some half-way cases.
+ * If rv * ulp(rv) is denormalized (i.e.,
+ * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
+ * trouble from bits lost to denormalization;
+ * example: 1.2e-307 .
+ */
+ if (y <= (P-1)*Exp_msk1 && aadj > 1.) {
+ aadj1 = (double)(int)(aadj + 0.5);
+ if (!bc.dsign)
+ aadj1 = -aadj1;
+ }
+ adj.d = aadj1 * ulp(&rv);
+ dval(&rv) += adj.d;
+#endif /*Sudden_Underflow*/
+#endif /*Avoid_Underflow*/
+ }
+ z = word0(&rv) & Exp_mask;
+#ifndef SET_INEXACT
+ if (bc.nd == nd) {
+#ifdef Avoid_Underflow
+ if (!bc.scale)
+#endif
+ if (y == z) {
+ /* Can we stop now? */
+ L = (Long)aadj;
+ aadj -= L;
+ /* The tolerances below are conservative. */
+ if (bc.dsign || word1(&rv) || word0(&rv) & Bndry_mask) {
+ if (aadj < .4999999 || aadj > .5000001)
+ break;
+ }
+ else if (aadj < .4999999/FLT_RADIX)
+ break;
+ }
+ }
+#endif
+ cont:
+ Bfree(bb MTb);
+ Bfree(bd MTb);
+ Bfree(bs MTb);
+ Bfree(delta MTb);
+ }
+ Bfree(bb MTb);
+ Bfree(bd MTb);
+ Bfree(bs MTb);
+ Bfree(bd0 MTb);
+ Bfree(delta MTb);
+#ifndef NO_STRTOD_BIGCOMP
+ if (req_bigcomp) {
+ bd0 = 0;
+ bc.e0 += nz1;
+ bigcomp(&rv, s0, &bc MTb);
+ y = word0(&rv) & Exp_mask;
+ if (y == Exp_mask)
+ goto ovfl;
+ if (y == 0 && rv.d == 0.)
+ goto undfl;
+ }
+#endif
+#ifdef Avoid_Underflow
+ if (bc.scale) {
+ word0(&rv0) = Exp_1 - 2*P*Exp_msk1;
+ word1(&rv0) = 0;
+ dval(&rv) *= dval(&rv0);
+#ifndef NO_ERRNO
+ /* try to avoid the bug of testing an 8087 register value */
+#ifdef IEEE_Arith
+ if (!(word0(&rv) & Exp_mask))
+#else
+ if (word0(&rv) == 0 && word1(&rv) == 0)
+#endif
+ Set_errno(ERANGE);
+#endif
+ }
+#endif /* Avoid_Underflow */
+ ret:
+#ifdef SET_INEXACT
+ if (bc.inexact) {
+ if (!(word0(&rv) & Exp_mask)) {
+ /* set underflow and inexact bits */
+ dval(&rv0) = 1e-300;
+ dval(&rv0) *= dval(&rv0);
+ }
+ else if (!oldinexact) {
+ word0(&rv0) = Exp_1 + (70 << Exp_shift);
+ word1(&rv0) = 0;
+ dval(&rv0) += 1.;
+ }
+ }
+ else if (!oldinexact)
+ clear_inexact();
+#endif
+ if (se)
+ *se = (char *)s;
+ return sign ? -dval(&rv) : dval(&rv);
+ }
+
+#ifndef MULTIPLE_THREADS
+ static char *dtoa_result;
+#endif
+
+ static char *
+rv_alloc(int i MTd)
+{
+ int j, k, *r;
+
+ j = sizeof(ULong);
+ for(k = 0;
+ sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= i;
+ j <<= 1)
+ k++;
+ r = (int*)Balloc(k MTa);
+ *r = k;
+ return
+#ifndef MULTIPLE_THREADS
+ dtoa_result =
+#endif
+ (char *)(r+1);
+ }
+
+ static char *
+nrv_alloc(const char *s, char *s0, size_t s0len, char **rve, int n MTd)
+{
+ char *rv, *t;
+
+ if (!s0)
+ s0 = rv_alloc(n MTa);
+ else if (s0len <= n) {
+ rv = 0;
+ t = rv + n;
+ goto rve_chk;
+ }
+ t = rv = s0;
+ while((*t = *s++))
+ ++t;
+ rve_chk:
+ if (rve)
+ *rve = t;
+ return rv;
+ }
+
+/* freedtoa(s) must be used to free values s returned by dtoa
+ * when MULTIPLE_THREADS is #defined. It should be used in all cases,
+ * but for consistency with earlier versions of dtoa, it is optional
+ * when MULTIPLE_THREADS is not defined.
+ */
+
+ void
+freedtoa(char *s)
+{
+#ifdef MULTIPLE_THREADS
+ ThInfo *TI = 0;
+#endif
+ Bigint *b = (Bigint *)((int *)s - 1);
+ b->maxwds = 1 << (b->k = *(int*)b);
+ Bfree(b MTb);
+#ifndef MULTIPLE_THREADS
+ if (s == dtoa_result)
+ dtoa_result = 0;
+#endif
+ }
+
+/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
+ *
+ * Inspired by "How to Print Floating-Point Numbers Accurately" by
+ * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126].
+ *
+ * Modifications:
+ * 1. Rather than iterating, we use a simple numeric overestimate
+ * to determine k = floor(log10(d)). We scale relevant
+ * quantities using O(log2(k)) rather than O(k) multiplications.
+ * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
+ * try to generate digits strictly left to right. Instead, we
+ * compute with fewer bits and propagate the carry if necessary
+ * when rounding the final digit up. This is often faster.
+ * 3. Under the assumption that input will be rounded nearest,
+ * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
+ * That is, we allow equality in stopping tests when the
+ * round-nearest rule will give the same floating-point value
+ * as would satisfaction of the stopping test with strict
+ * inequality.
+ * 4. We remove common factors of powers of 2 from relevant
+ * quantities.
+ * 5. When converting floating-point integers less than 1e16,
+ * we use floating-point arithmetic rather than resorting
+ * to multiple-precision integers.
+ * 6. When asked to produce fewer than 15 digits, we first try
+ * to get by with floating-point arithmetic; we resort to
+ * multiple-precision integer arithmetic only if we cannot
+ * guarantee that the floating-point calculation has given
+ * the correctly rounded result. For k requested digits and
+ * "uniformly" distributed input, the probability is
+ * something like 10^(k-15) that we must resort to the Long
+ * calculation.
+ */
+
+ char *
+dtoa_r(double dd, int mode, int ndigits, int *decpt, int *sign, char **rve, char *buf, size_t blen)
+{
+ /* Arguments ndigits, decpt, sign are similar to those
+ of ecvt and fcvt; trailing zeros are suppressed from
+ the returned string. If not null, *rve is set to point
+ to the end of the return value. If d is +-Infinity or NaN,
+ then *decpt is set to 9999.
+
+ mode:
+ 0 ==> shortest string that yields d when read in
+ and rounded to nearest.
+ 1 ==> like 0, but with Steele & White stopping rule;
+ e.g. with IEEE P754 arithmetic , mode 0 gives
+ 1e23 whereas mode 1 gives 9.999999999999999e22.
+ 2 ==> max(1,ndigits) significant digits. This gives a
+ return value similar to that of ecvt, except
+ that trailing zeros are suppressed.
+ 3 ==> through ndigits past the decimal point. This
+ gives a return value similar to that from fcvt,
+ except that trailing zeros are suppressed, and
+ ndigits can be negative.
+ 4,5 ==> similar to 2 and 3, respectively, but (in
+ round-nearest mode) with the tests of mode 0 to
+ possibly return a shorter string that rounds to d.
+ With IEEE arithmetic and compilation with
+ -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same
+ as modes 2 and 3 when FLT_ROUNDS != 1.
+ 6-9 ==> Debugging modes similar to mode - 4: don't try
+ fast floating-point estimate (if applicable).
+
+ Values of mode other than 0-9 are treated as mode 0.
+
+ When not NULL, buf is an output buffer of length blen, which must
+ be large enough to accommodate suppressed trailing zeros and a trailing
+ null byte. If blen is too small, rv = NULL is returned, in which case
+ if rve is not NULL, a subsequent call with blen >= (*rve - rv) + 1
+ should succeed in returning buf.
+
+ When buf is NULL, sufficient space is allocated for the return value,
+ which, when done using, the caller should pass to freedtoa().
+
+ USE_BF is automatically defined when neither NO_LONG_LONG nor NO_BF96
+ is defined.
+ */
+
+#ifdef MULTIPLE_THREADS
+ ThInfo *TI = 0;
+#endif
+ int bbits, b2, b5, be, dig, i, ilim, ilim1,
+ j, j1, k, leftright, m2, m5, s2, s5, spec_case;
+#if !defined(Sudden_Underflow) || defined(USE_BF96)
+ int denorm;
+#endif
+ Bigint *b, *b1, *delta, *mlo, *mhi, *S;
+ U u;
+ char *s;
+#ifdef SET_INEXACT
+ int inexact, oldinexact;
+#endif
+#ifdef USE_BF96 /*{{*/
+ BF96 *p10;
+ ULLong dbhi, dbits, dblo, den, hb, rb, rblo, res, res0, res3, reslo, sres,
+ sulp, tv0, tv1, tv2, tv3, ulp, ulplo, ulpmask, ures, ureslo, zb;
+ int eulp, k1, n2, ulpadj, ulpshift;
+#else /*}{*/
+#ifndef Sudden_Underflow
+ ULong x;
+#endif
+ Long L;
+ U d2, eps;
+ double ds;
+ int ieps, ilim0, k0, k_check, try_quick;
+#ifndef No_leftright
+#ifdef IEEE_Arith
+ U eps1;
+#endif
+#endif
+#endif /*}}*/
+#ifdef Honor_FLT_ROUNDS /*{*/
+ int Rounding;
+#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */
+ Rounding = Flt_Rounds;
+#else /*}{*/
+ Rounding = 1;
+ switch(fegetround()) {
+ case FE_TOWARDZERO: Rounding = 0; break;
+ case FE_UPWARD: Rounding = 2; break;
+ case FE_DOWNWARD: Rounding = 3;
+ }
+#endif /*}}*/
+#endif /*}*/
+
+ u.d = dd;
+ if (word0(&u) & Sign_bit) {
+ /* set sign for everything, including 0's and NaNs */
+ *sign = 1;
+ word0(&u) &= ~Sign_bit; /* clear sign bit */
+ }
+ else
+ *sign = 0;
+
+#if defined(IEEE_Arith) + defined(VAX)
+#ifdef IEEE_Arith
+ if ((word0(&u) & Exp_mask) == Exp_mask)
+#else
+ if (word0(&u) == 0x8000)
+#endif
+ {
+ /* Infinity or NaN */
+ *decpt = 9999;
+#ifdef IEEE_Arith
+ if (!word1(&u) && !(word0(&u) & 0xfffff))
+ return nrv_alloc("Infinity", buf, blen, rve, 8 MTb);
+#endif
+ return nrv_alloc("NaN", buf, blen, rve, 3 MTb);
+ }
+#endif
+#ifdef IBM
+ dval(&u) += 0; /* normalize */
+#endif
+ if (!dval(&u)) {
+ *decpt = 1;
+ return nrv_alloc("0", buf, blen, rve, 1 MTb);
+ }
+
+#ifdef SET_INEXACT
+#ifndef USE_BF96
+ try_quick =
+#endif
+ oldinexact = get_inexact();
+ inexact = 1;
+#endif
+#ifdef Honor_FLT_ROUNDS
+ if (Rounding >= 2) {
+ if (*sign)
+ Rounding = Rounding == 2 ? 0 : 2;
+ else
+ if (Rounding != 2)
+ Rounding = 0;
+ }
+#endif
+#ifdef USE_BF96 /*{{*/
+ dbits = (u.LL & 0xfffffffffffffull) << 11; /* fraction bits */
+ if ((be = u.LL >> 52)) /* biased exponent; nonzero ==> normal */ {
+ dbits |= 0x8000000000000000ull;
+ denorm = ulpadj = 0;
+ }
+ else {
+ denorm = 1;
+ ulpadj = be + 1;
+ dbits <<= 1;
+ if (!(dbits & 0xffffffff00000000ull)) {
+ dbits <<= 32;
+ be -= 32;
+ }
+ if (!(dbits & 0xffff000000000000ull)) {
+ dbits <<= 16;
+ be -= 16;
+ }
+ if (!(dbits & 0xff00000000000000ull)) {
+ dbits <<= 8;
+ be -= 8;
+ }
+ if (!(dbits & 0xf000000000000000ull)) {
+ dbits <<= 4;
+ be -= 4;
+ }
+ if (!(dbits & 0xc000000000000000ull)) {
+ dbits <<= 2;
+ be -= 2;
+ }
+ if (!(dbits & 0x8000000000000000ull)) {
+ dbits <<= 1;
+ be -= 1;
+ }
+ assert(be >= -51);
+ ulpadj -= be;
+ }
+ j = Lhint[be + 51];
+ p10 = &pten[j];
+ dbhi = dbits >> 32;
+ dblo = dbits & 0xffffffffull;
+ i = be - 0x3fe;
+ if (i < p10->e
+ || (i == p10->e && (dbhi < p10->b0 || (dbhi == p10->b0 && dblo < p10->b1))))
+ --j;
+ k = j - 342;
+
+ /* now 10^k <= dd < 10^(k+1) */
+
+#else /*}{*/
+
+ b = d2b(&u, &be, &bbits MTb);
+#ifdef Sudden_Underflow
+ i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
+#else
+ if ((i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1)))) {
+#endif
+ dval(&d2) = dval(&u);
+ word0(&d2) &= Frac_mask1;
+ word0(&d2) |= Exp_11;
+#ifdef IBM
+ if (j = 11 - hi0bits(word0(&d2) & Frac_mask))
+ dval(&d2) /= 1 << j;
+#endif
+
+ /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
+ * log10(x) = log(x) / log(10)
+ * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
+ * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
+ *
+ * This suggests computing an approximation k to log10(d) by
+ *
+ * k = (i - Bias)*0.301029995663981
+ * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
+ *
+ * We want k to be too large rather than too small.
+ * The error in the first-order Taylor series approximation
+ * is in our favor, so we just round up the constant enough
+ * to compensate for any error in the multiplication of
+ * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
+ * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
+ * adding 1e-13 to the constant term more than suffices.
+ * Hence we adjust the constant term to 0.1760912590558.
+ * (We could get a more accurate k by invoking log10,
+ * but this is probably not worthwhile.)
+ */
+
+ i -= Bias;
+#ifdef IBM
+ i <<= 2;
+ i += j;
+#endif
+#ifndef Sudden_Underflow
+ denorm = 0;
+ }
+ else {
+ /* d is denormalized */
+
+ i = bbits + be + (Bias + (P-1) - 1);
+ x = i > 32 ? word0(&u) << (64 - i) | word1(&u) >> (i - 32)
+ : word1(&u) << (32 - i);
+ dval(&d2) = x;
+ word0(&d2) -= 31*Exp_msk1; /* adjust exponent */
+ i -= (Bias + (P-1) - 1) + 1;
+ denorm = 1;
+ }
+#endif
+ ds = (dval(&d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
+ k = (int)ds;
+ if (ds < 0. && ds != k)
+ k--; /* want k = floor(ds) */
+ k_check = 1;
+ if (k >= 0 && k <= Ten_pmax) {
+ if (dval(&u) < tens[k])
+ k--;
+ k_check = 0;
+ }
+ j = bbits - i - 1;
+ if (j >= 0) {
+ b2 = 0;
+ s2 = j;
+ }
+ else {
+ b2 = -j;
+ s2 = 0;
+ }
+ if (k >= 0) {
+ b5 = 0;
+ s5 = k;
+ s2 += k;
+ }
+ else {
+ b2 -= k;
+ b5 = -k;
+ s5 = 0;
+ }
+#endif /*}}*/
+ if (mode < 0 || mode > 9)
+ mode = 0;
+
+#ifndef USE_BF96
+#ifndef SET_INEXACT
+#ifdef Check_FLT_ROUNDS
+ try_quick = Rounding == 1;
+#endif
+#endif /*SET_INEXACT*/
+#endif
+
+ if (mode > 5) {
+ mode -= 4;
+#ifndef USE_BF96
+ try_quick = 0;
+#endif
+ }
+ leftright = 1;
+ ilim = ilim1 = -1; /* Values for cases 0 and 1; done here to */
+ /* silence erroneous "gcc -Wall" warning. */
+ switch(mode) {
+ case 0:
+ case 1:
+ i = 18;
+ ndigits = 0;
+ break;
+ case 2:
+ leftright = 0;
+ /* no break */
+ case 4:
+ if (ndigits <= 0)
+ ndigits = 1;
+ ilim = ilim1 = i = ndigits;
+ break;
+ case 3:
+ leftright = 0;
+ /* no break */
+ case 5:
+ i = ndigits + k + 1;
+ ilim = i;
+ ilim1 = i - 1;
+ if (i <= 0)
+ i = 1;
+ }
+ if (!buf) {
+ buf = rv_alloc(i MTb);
+ blen = sizeof(Bigint) + ((1 << ((int*)buf)[-1]) - 1)*sizeof(ULong) - sizeof(int);
+ }
+ else if (blen <= i) {
+ buf = 0;
+ if (rve)
+ *rve = buf + i;
+ return buf;
+ }
+ s = buf;
+
+ /* Check for special case that d is a normalized power of 2. */
+
+ spec_case = 0;
+ if (mode < 2 || (leftright
+#ifdef Honor_FLT_ROUNDS
+ && Rounding == 1
+#endif
+ )) {
+ if (!word1(&u) && !(word0(&u) & Bndry_mask)
+#ifndef Sudden_Underflow
+ && word0(&u) & (Exp_mask & ~Exp_msk1)
+#endif
+ ) {
+ /* The special case */
+ spec_case = 1;
+ }
+ }
+
+#ifdef USE_BF96 /*{*/
+ b = 0;
+ if (ilim < 0 && (mode == 3 || mode == 5)) {
+ S = mhi = 0;
+ goto no_digits;
+ }
+ i = 1;
+ j = 52 + 0x3ff - be;
+ ulpshift = 0;
+ ulplo = 0;
+ /* Can we do an exact computation with 64-bit integer arithmetic? */
+ if (k < 0) {
+ if (k < -25)
+ goto toobig;
+ res = dbits >> 11;
+ n2 = pfivebits[k1 = -(k + 1)] + 53;
+ j1 = j;
+ if (n2 > 61) {
+ ulpshift = n2 - 61;
+ if (res & (ulpmask = (1ull << ulpshift) - 1))
+ goto toobig;
+ j -= ulpshift;
+ res >>= ulpshift;
+ }
+ /* Yes. */
+ res *= ulp = pfive[k1];
+ if (ulpshift) {
+ ulplo = ulp;
+ ulp >>= ulpshift;
+ }
+ j += k;
+ if (ilim == 0) {
+ S = mhi = 0;
+ if (res > (5ull << j))
+ goto one_digit;
+ goto no_digits;
+ }
+ goto no_div;
+ }
+ if (ilim == 0 && j + k >= 0) {
+ S = mhi = 0;
+ if ((dbits >> 11) > (pfive[k-1] << j))
+ goto one_digit;
+ goto no_digits;
+ }
+ if (k <= dtoa_divmax && j + k >= 0) {
+ /* Another "yes" case -- we will use exact integer arithmetic. */
+ use_exact:
+ Debug(++dtoa_stats[3]);
+ res = dbits >> 11; /* residual */
+ ulp = 1;
+ if (k <= 0)
+ goto no_div;
+ j1 = j + k + 1;
+ den = pfive[k-i] << (j1 - i);
+ for(;;) {
+ dig = res / den;
+ *s++ = '0' + dig;
+ if (!(res -= dig*den)) {
+#ifdef SET_INEXACT
+ inexact = 0;
+ oldinexact = 1;
+#endif
+ goto retc;
+ }
+ if (ilim < 0) {
+ ures = den - res;
+ if (2*res <= ulp
+ && (spec_case ? 4*res <= ulp : (2*res < ulp || dig & 1)))
+ goto ulp_reached;
+ if (2*ures < ulp)
+ goto Roundup;
+ }
+ else if (i == ilim) {
+ switch(Rounding) {
+ case 0: goto retc;
+ case 2: goto Roundup;
+ }
+ ures = 2*res;
+ if (ures > den
+ || (ures == den && dig & 1)
+ || (spec_case && res <= ulp && 2*res >= ulp))
+ goto Roundup;
+ goto retc;
+ }
+ if (j1 < ++i) {
+ res *= 10;
+ ulp *= 10;
+ }
+ else {
+ if (i > k)
+ break;
+ den = pfive[k-i] << (j1 - i);
+ }
+ }
+ no_div:
+ for(;;) {
+ dig = den = res >> j;
+ *s++ = '0' + dig;
+ if (!(res -= den << j)) {
+#ifdef SET_INEXACT
+ inexact = 0;
+ oldinexact = 1;
+#endif
+ goto retc;
+ }
+ if (ilim < 0) {
+ ures = (1ull << j) - res;
+ if (2*res <= ulp
+ && (spec_case ? 4*res <= ulp : (2*res < ulp || dig & 1))) {
+ ulp_reached:
+ if (ures < res
+ || (ures == res && dig & 1))
+ goto Roundup;
+ goto retc;
+ }
+ if (2*ures < ulp)
+ goto Roundup;
+ }
+ --j;
+ if (i == ilim) {
+#ifdef Honor_FLT_ROUNDS
+ switch(Rounding) {
+ case 0: goto retc;
+ case 2: goto Roundup;
+ }
+#endif
+ hb = 1ull << j;
+ if (res & hb && (dig & 1 || res & (hb-1)))
+ goto Roundup;
+ if (spec_case && res <= ulp && 2*res >= ulp) {
+ Roundup:
+ while(*--s == '9')
+ if (s == buf) {
+ ++k;
+ *s++ = '1';
+ goto ret1;
+ }
+ ++*s++;
+ goto ret1;
+ }
+ goto retc;
+ }
+ ++i;
+ res *= 5;
+ if (ulpshift) {
+ ulplo = 5*(ulplo & ulpmask);
+ ulp = 5*ulp + (ulplo >> ulpshift);
+ }
+ else
+ ulp *= 5;
+ }
+ }
+ toobig:
+ if (ilim > 28)
+ goto Fast_failed1;
+ /* Scale by 10^-k */
+ p10 = &pten[342-k];
+ tv0 = p10->b2 * dblo; /* rarely matters, but does, e.g., for 9.862818194192001e18 */
+ tv1 = p10->b1 * dblo + (tv0 >> 32);
+ tv2 = p10->b2 * dbhi + (tv1 & 0xffffffffull);
+ tv3 = p10->b0 * dblo + (tv1>>32) + (tv2>>32);
+ res3 = p10->b1 * dbhi + (tv3 & 0xffffffffull);
+ res = p10->b0 * dbhi + (tv3>>32) + (res3>>32);
+ be += p10->e - 0x3fe;
+ eulp = j1 = be - 54 + ulpadj;
+ if (!(res & 0x8000000000000000ull)) {
+ --be;
+ res3 <<= 1;
+ res = (res << 1) | ((res3 & 0x100000000ull) >> 32);
+ }
+ res0 = res; /* save for Fast_failed */
+#if !defined(SET_INEXACT) && !defined(NO_DTOA_64) /*{*/
+ if (ilim > 19)
+ goto Fast_failed;
+ Debug(++dtoa_stats[4]);
+ assert(be >= 0 && be <= 4); /* be = 0 is rare, but possible, e.g., for 1e20 */
+ res >>= 4 - be;
+ ulp = p10->b0; /* ulp */
+ ulp = (ulp << 29) | (p10->b1 >> 3);
+ /* scaled ulp = ulp * 2^(eulp - 60) */
+ /* We maintain 61 bits of the scaled ulp. */
+ if (ilim == 0) {
+ if (!(res & 0x7fffffffffffffeull)
+ || !((~res) & 0x7fffffffffffffeull))
+ goto Fast_failed1;
+ S = mhi = 0;
+ if (res >= 0x5000000000000000ull)
+ goto one_digit;
+ goto no_digits;
+ }
+ rb = 1; /* upper bound on rounding error */
+ for(;;++i) {
+ dig = res >> 60;
+ *s++ = '0' + dig;
+ res &= 0xfffffffffffffffull;
+ if (ilim < 0) {
+ ures = 0x1000000000000000ull - res;
+ if (eulp > 0) {
+ assert(eulp <= 4);
+ sulp = ulp << (eulp - 1);
+ if (res <= ures) {
+ if (res + rb > ures - rb)
+ goto Fast_failed;
+ if (res < sulp)
+ goto retc;
+ }
+ else {
+ if (res - rb <= ures + rb)
+ goto Fast_failed;
+ if (ures < sulp)
+ goto Roundup;
+ }
+ }
+ else {
+ zb = -((int64_t)(1ull << (eulp + 63)));
+ if (!(zb & res)) {
+ sres = res << (1 - eulp);
+ if (sres < ulp && (!spec_case || 2*sres < ulp)) {
+ if ((res+rb) << (1 - eulp) >= ulp)
+ goto Fast_failed;
+ if (ures < res) {
+ if (ures + rb >= res - rb)
+ goto Fast_failed;
+ goto Roundup;
+ }
+ if (ures - rb < res + rb)
+ goto Fast_failed;
+ goto retc;
+ }
+ }
+ if (!(zb & ures) && ures << -eulp < ulp) {
+ if (ures << (1 - eulp) < ulp)
+ goto Roundup;
+ goto Fast_failed;
+ }
+ }
+ }
+ else if (i == ilim) {
+ ures = 0x1000000000000000ull - res;
+ if (ures < res) {
+ if (ures <= rb || res - rb <= ures + rb) {
+ if (j + k >= 0 && k >= 0 && k <= 27)
+ goto use_exact1;
+ goto Fast_failed;
+ }
+#ifdef Honor_FLT_ROUNDS
+ if (Rounding == 0)
+ goto retc;
+#endif
+ goto Roundup;
+ }
+ if (res <= rb || ures - rb <= res + rb) {
+ if (j + k >= 0 && k >= 0 && k <= 27) {
+ use_exact1:
+ s = buf;
+ i = 1;
+ goto use_exact;
+ }
+ goto Fast_failed;
+ }
+#ifdef Honor_FLT_ROUNDS
+ if (Rounding == 2)
+ goto Roundup;
+#endif
+ goto retc;
+ }
+ rb *= 10;
+ if (rb >= 0x1000000000000000ull)
+ goto Fast_failed;
+ res *= 10;
+ ulp *= 5;
+ if (ulp & 0x8000000000000000ull) {
+ eulp += 4;
+ ulp >>= 3;
+ }
+ else {
+ eulp += 3;
+ ulp >>= 2;
+ }
+ }
+#endif /*}*/
+#ifndef NO_BF96
+ Fast_failed:
+#endif
+ Debug(++dtoa_stats[5]);
+ s = buf;
+ i = 4 - be;
+ res = res0 >> i;
+ reslo = 0xffffffffull & res3;
+ if (i)
+ reslo = (res0 << (64 - i)) >> 32 | (reslo >> i);
+ rb = 0;
+ rblo = 4; /* roundoff bound */
+ ulp = p10->b0; /* ulp */
+ ulp = (ulp << 29) | (p10->b1 >> 3);
+ eulp = j1;
+ for(i = 1;;++i) {
+ dig = res >> 60;
+ *s++ = '0' + dig;
+ res &= 0xfffffffffffffffull;
+#ifdef SET_INEXACT
+ if (!res && !reslo) {
+ if (!(res3 & 0xffffffffull)) {
+ inexact = 0;
+ oldinexact = 1;
+ }
+ goto retc;
+ }
+#endif
+ if (ilim < 0) {
+ ures = 0x1000000000000000ull - res;
+ ureslo = 0;
+ if (reslo) {
+ ureslo = 0x100000000ull - reslo;
+ --ures;
+ }
+ if (eulp > 0) {
+ assert(eulp <= 4);
+ sulp = (ulp << (eulp - 1)) - rb;
+ if (res <= ures) {
+ if (res < sulp) {
+ if (res+rb < ures-rb)
+ goto retc;
+ }
+ }
+ else if (ures < sulp) {
+ if (res-rb > ures+rb)
+ goto Roundup;
+ }
+ goto Fast_failed1;
+ }
+ else {
+ zb = -(int64_t)((1ull << (eulp + 60)));
+ if (!(zb & (res + rb))) {
+ sres = (res - rb) << (1 - eulp);
+ if (sres < ulp && (!spec_case || 2*sres < ulp)) {
+ sres = res << (1 - eulp);
+ if ((j = eulp + 31) > 0)
+ sres += (rblo + reslo) >> j;
+ else
+ sres += (rblo + reslo) << -j;
+ if (sres + (rb << (1 - eulp)) >= ulp)
+ goto Fast_failed1;
+ if (sres >= ulp)
+ goto more96;
+ if (ures < res
+ || (ures == res && ureslo < reslo)) {
+ if (ures + rb >= res - rb)
+ goto Fast_failed1;
+ goto Roundup;
+ }
+ if (ures - rb <= res + rb)
+ goto Fast_failed1;
+ goto retc;
+ }
+ }
+ if (!(zb & ures) && (ures-rb) << (1 - eulp) < ulp) {
+ if ((ures + rb) << (1 - eulp) < ulp)
+ goto Roundup;
+ goto Fast_failed1;
+ }
+ }
+ }
+ else if (i == ilim) {
+ ures = 0x1000000000000000ull - res;
+ sres = ureslo = 0;
+ if (reslo) {
+ ureslo = 0x100000000ull - reslo;
+ --ures;
+ sres = (reslo + rblo) >> 31;
+ }
+ sres += 2*rb;
+ if (ures <= res) {
+ if (ures <=sres || res - ures <= sres)
+ goto Fast_failed1;
+#ifdef Honor_FLT_ROUNDS
+ if (Rounding == 0)
+ goto retc;
+#endif
+ goto Roundup;
+ }
+ if (res <= sres || ures - res <= sres)
+ goto Fast_failed1;
+#ifdef Honor_FLT_ROUNDS
+ if (Rounding == 2)
+ goto Roundup;
+#endif
+ goto retc;
+ }
+ more96:
+ rblo *= 10;
+ rb = 10*rb + (rblo >> 32);
+ rblo &= 0xffffffffull;
+ if (rb >= 0x1000000000000000ull)
+ goto Fast_failed1;
+ reslo *= 10;
+ res = 10*res + (reslo >> 32);
+ reslo &= 0xffffffffull;
+ ulp *= 5;
+ if (ulp & 0x8000000000000000ull) {
+ eulp += 4;
+ ulp >>= 3;
+ }
+ else {
+ eulp += 3;
+ ulp >>= 2;
+ }
+ }
+ Fast_failed1:
+ Debug(++dtoa_stats[6]);
+ S = mhi = mlo = 0;
+#ifdef USE_BF96
+ b = d2b(&u, &be, &bbits MTb);
+#endif
+ s = buf;
+ i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
+ i -= Bias;
+ if (ulpadj)
+ i -= ulpadj - 1;
+ j = bbits - i - 1;
+ if (j >= 0) {
+ b2 = 0;
+ s2 = j;
+ }
+ else {
+ b2 = -j;
+ s2 = 0;
+ }
+ if (k >= 0) {
+ b5 = 0;
+ s5 = k;
+ s2 += k;
+ }
+ else {
+ b2 -= k;
+ b5 = -k;
+ s5 = 0;
+ }
+#endif /*}*/
+
+#ifdef Honor_FLT_ROUNDS
+ if (mode > 1 && Rounding != 1)
+ leftright = 0;
+#endif
+
+#ifndef USE_BF96 /*{*/
+ if (ilim >= 0 && ilim <= Quick_max && try_quick) {
+
+ /* Try to get by with floating-point arithmetic. */
+
+ i = 0;
+ dval(&d2) = dval(&u);
+ j1 = -(k0 = k);
+ ilim0 = ilim;
+ ieps = 2; /* conservative */
+ if (k > 0) {
+ ds = tens[k&0xf];
+ j = k >> 4;
+ if (j & Bletch) {
+ /* prevent overflows */
+ j &= Bletch - 1;
+ dval(&u) /= bigtens[n_bigtens-1];
+ ieps++;
+ }
+ for(; j; j >>= 1, i++)
+ if (j & 1) {
+ ieps++;
+ ds *= bigtens[i];
+ }
+ dval(&u) /= ds;
+ }
+ else if (j1 > 0) {
+ dval(&u) *= tens[j1 & 0xf];
+ for(j = j1 >> 4; j; j >>= 1, i++)
+ if (j & 1) {
+ ieps++;
+ dval(&u) *= bigtens[i];
+ }
+ }
+ if (k_check && dval(&u) < 1. && ilim > 0) {
+ if (ilim1 <= 0)
+ goto fast_failed;
+ ilim = ilim1;
+ k--;
+ dval(&u) *= 10.;
+ ieps++;
+ }
+ dval(&eps) = ieps*dval(&u) + 7.;
+ word0(&eps) -= (P-1)*Exp_msk1;
+ if (ilim == 0) {
+ S = mhi = 0;
+ dval(&u) -= 5.;
+ if (dval(&u) > dval(&eps))
+ goto one_digit;
+ if (dval(&u) < -dval(&eps))
+ goto no_digits;
+ goto fast_failed;
+ }
+#ifndef No_leftright
+ if (leftright) {
+ /* Use Steele & White method of only
+ * generating digits needed.
+ */
+ dval(&eps) = 0.5/tens[ilim-1] - dval(&eps);
+#ifdef IEEE_Arith
+ if (j1 >= 307) {
+ eps1.d = 1.01e256; /* 1.01 allows roundoff in the next few lines */
+ word0(&eps1) -= Exp_msk1 * (Bias+P-1);
+ dval(&eps1) *= tens[j1 & 0xf];
+ for(i = 0, j = (j1-256) >> 4; j; j >>= 1, i++)
+ if (j & 1)
+ dval(&eps1) *= bigtens[i];
+ if (eps.d < eps1.d)
+ eps.d = eps1.d;
+ if (10. - u.d < 10.*eps.d && eps.d < 1.) {
+ /* eps.d < 1. excludes trouble with the tiniest denormal */
+ *s++ = '1';
+ ++k;
+ goto ret1;
+ }
+ }
+#endif
+ for(i = 0;;) {
+ L = dval(&u);
+ dval(&u) -= L;
+ *s++ = '0' + (int)L;
+ if (1. - dval(&u) < dval(&eps))
+ goto bump_up;
+ if (dval(&u) < dval(&eps))
+ goto retc;
+ if (++i >= ilim)
+ break;
+ dval(&eps) *= 10.;
+ dval(&u) *= 10.;
+ }
+ }
+ else {
+#endif
+ /* Generate ilim digits, then fix them up. */
+ dval(&eps) *= tens[ilim-1];
+ for(i = 1;; i++, dval(&u) *= 10.) {
+ L = (Long)(dval(&u));
+ if (!(dval(&u) -= L))
+ ilim = i;
+ *s++ = '0' + (int)L;
+ if (i == ilim) {
+ if (dval(&u) > 0.5 + dval(&eps))
+ goto bump_up;
+ else if (dval(&u) < 0.5 - dval(&eps))
+ goto retc;
+ break;
+ }
+ }
+#ifndef No_leftright
+ }
+#endif
+ fast_failed:
+ s = buf;
+ dval(&u) = dval(&d2);
+ k = k0;
+ ilim = ilim0;
+ }
+
+ /* Do we have a "small" integer? */
+
+ if (be >= 0 && k <= Int_max) {
+ /* Yes. */
+ ds = tens[k];
+ if (ndigits < 0 && ilim <= 0) {
+ S = mhi = 0;
+ if (ilim < 0 || dval(&u) <= 5*ds)
+ goto no_digits;
+ goto one_digit;
+ }
+ for(i = 1;; i++, dval(&u) *= 10.) {
+ L = (Long)(dval(&u) / ds);
+ dval(&u) -= L*ds;
+#ifdef Check_FLT_ROUNDS
+ /* If FLT_ROUNDS == 2, L will usually be high by 1 */
+ if (dval(&u) < 0) {
+ L--;
+ dval(&u) += ds;
+ }
+#endif
+ *s++ = '0' + (int)L;
+ if (!dval(&u)) {
+#ifdef SET_INEXACT
+ inexact = 0;
+#endif
+ break;
+ }
+ if (i == ilim) {
+#ifdef Honor_FLT_ROUNDS
+ if (mode > 1)
+ switch(Rounding) {
+ case 0: goto retc;
+ case 2: goto bump_up;
+ }
+#endif
+ dval(&u) += dval(&u);
+#ifdef ROUND_BIASED
+ if (dval(&u) >= ds)
+#else
+ if (dval(&u) > ds || (dval(&u) == ds && L & 1))
+#endif
+ {
+ bump_up:
+ while(*--s == '9')
+ if (s == buf) {
+ k++;
+ *s = '0';
+ break;
+ }
+ ++*s++;
+ }
+ break;
+ }
+ }
+ goto retc;
+ }
+
+#endif /*}*/
+ m2 = b2;
+ m5 = b5;
+ mhi = mlo = 0;
+ if (leftright) {
+ i =
+#ifndef Sudden_Underflow
+ denorm ? be + (Bias + (P-1) - 1 + 1) :
+#endif
+#ifdef IBM
+ 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);
+#else
+ 1 + P - bbits;
+#endif
+ b2 += i;
+ s2 += i;
+ mhi = i2b(1 MTb);
+ }
+ if (m2 > 0 && s2 > 0) {
+ i = m2 < s2 ? m2 : s2;
+ b2 -= i;
+ m2 -= i;
+ s2 -= i;
+ }
+ if (b5 > 0) {
+ if (leftright) {
+ if (m5 > 0) {
+ mhi = pow5mult(mhi, m5 MTb);
+ b1 = mult(mhi, b MTb);
+ Bfree(b MTb);
+ b = b1;
+ }
+ if ((j = b5 - m5))
+ b = pow5mult(b, j MTb);
+ }
+ else
+ b = pow5mult(b, b5 MTb);
+ }
+ S = i2b(1 MTb);
+ if (s5 > 0)
+ S = pow5mult(S, s5 MTb);
+
+ if (spec_case) {
+ b2 += Log2P;
+ s2 += Log2P;
+ }
+
+ /* Arrange for convenient computation of quotients:
+ * shift left if necessary so divisor has 4 leading 0 bits.
+ *
+ * Perhaps we should just compute leading 28 bits of S once
+ * and for all and pass them and a shift to quorem, so it
+ * can do shifts and ors to compute the numerator for q.
+ */
+ i = dshift(S, s2);
+ b2 += i;
+ m2 += i;
+ s2 += i;
+ if (b2 > 0)
+ b = lshift(b, b2 MTb);
+ if (s2 > 0)
+ S = lshift(S, s2 MTb);
+#ifndef USE_BF96
+ if (k_check) {
+ if (cmp(b,S) < 0) {
+ k--;
+ b = multadd(b, 10, 0 MTb); /* we botched the k estimate */
+ if (leftright)
+ mhi = multadd(mhi, 10, 0 MTb);
+ ilim = ilim1;
+ }
+ }
+#endif
+ if (ilim <= 0 && (mode == 3 || mode == 5)) {
+ if (ilim < 0 || cmp(b,S = multadd(S,5,0 MTb)) <= 0) {
+ /* no digits, fcvt style */
+ no_digits:
+ k = -1 - ndigits;
+ goto ret;
+ }
+ one_digit:
+ *s++ = '1';
+ ++k;
+ goto ret;
+ }
+ if (leftright) {
+ if (m2 > 0)
+ mhi = lshift(mhi, m2 MTb);
+
+ /* Compute mlo -- check for special case
+ * that d is a normalized power of 2.
+ */
+
+ mlo = mhi;
+ if (spec_case) {
+ mhi = Balloc(mhi->k MTb);
+ Bcopy(mhi, mlo);
+ mhi = lshift(mhi, Log2P MTb);
+ }
+
+ for(i = 1;;i++) {
+ dig = quorem(b,S) + '0';
+ /* Do we yet have the shortest decimal string
+ * that will round to d?
+ */
+ j = cmp(b, mlo);
+ delta = diff(S, mhi MTb);
+ j1 = delta->sign ? 1 : cmp(b, delta);
+ Bfree(delta MTb);
+#ifndef ROUND_BIASED
+ if (j1 == 0 && mode != 1 && !(word1(&u) & 1)
+#ifdef Honor_FLT_ROUNDS
+ && (mode <= 1 || Rounding >= 1)
+#endif
+ ) {
+ if (dig == '9')
+ goto round_9_up;
+ if (j > 0)
+ dig++;
+#ifdef SET_INEXACT
+ else if (!b->x[0] && b->wds <= 1)
+ inexact = 0;
+#endif
+ *s++ = dig;
+ goto ret;
+ }
+#endif
+ if (j < 0 || (j == 0 && mode != 1
+#ifndef ROUND_BIASED
+ && !(word1(&u) & 1)
+#endif
+ )) {
+ if (!b->x[0] && b->wds <= 1) {
+#ifdef SET_INEXACT
+ inexact = 0;
+#endif
+ goto accept_dig;
+ }
+#ifdef Honor_FLT_ROUNDS
+ if (mode > 1)
+ switch(Rounding) {
+ case 0: goto accept_dig;
+ case 2: goto keep_dig;
+ }
+#endif /*Honor_FLT_ROUNDS*/
+ if (j1 > 0) {
+ b = lshift(b, 1 MTb);
+ j1 = cmp(b, S);
+#ifdef ROUND_BIASED
+ if (j1 >= 0 /*)*/
+#else
+ if ((j1 > 0 || (j1 == 0 && dig & 1))
+#endif
+ && dig++ == '9')
+ goto round_9_up;
+ }
+ accept_dig:
+ *s++ = dig;
+ goto ret;
+ }
+ if (j1 > 0) {
+#ifdef Honor_FLT_ROUNDS
+ if (!Rounding && mode > 1)
+ goto accept_dig;
+#endif
+ if (dig == '9') { /* possible if i == 1 */
+ round_9_up:
+ *s++ = '9';
+ goto roundoff;
+ }
+ *s++ = dig + 1;
+ goto ret;
+ }
+#ifdef Honor_FLT_ROUNDS
+ keep_dig:
+#endif
+ *s++ = dig;
+ if (i == ilim)
+ break;
+ b = multadd(b, 10, 0 MTb);
+ if (mlo == mhi)
+ mlo = mhi = multadd(mhi, 10, 0 MTb);
+ else {
+ mlo = multadd(mlo, 10, 0 MTb);
+ mhi = multadd(mhi, 10, 0 MTb);
+ }
+ }
+ }
+ else
+ for(i = 1;; i++) {
+ dig = quorem(b,S) + '0';
+ *s++ = dig;
+ if (!b->x[0] && b->wds <= 1) {
+#ifdef SET_INEXACT
+ inexact = 0;
+#endif
+ goto ret;
+ }
+ if (i >= ilim)
+ break;
+ b = multadd(b, 10, 0 MTb);
+ }
+
+ /* Round off last digit */
+
+#ifdef Honor_FLT_ROUNDS
+ if (mode > 1)
+ switch(Rounding) {
+ case 0: goto ret;
+ case 2: goto roundoff;
+ }
+#endif
+ b = lshift(b, 1 MTb);
+ j = cmp(b, S);
+#ifdef ROUND_BIASED
+ if (j >= 0)
+#else
+ if (j > 0 || (j == 0 && dig & 1))
+#endif
+ {
+ roundoff:
+ while(*--s == '9')
+ if (s == buf) {
+ k++;
+ *s++ = '1';
+ goto ret;
+ }
+ ++*s++;
+ }
+ ret:
+ Bfree(S MTb);
+ if (mhi) {
+ if (mlo && mlo != mhi)
+ Bfree(mlo MTb);
+ Bfree(mhi MTb);
+ }
+ retc:
+ while(s > buf && s[-1] == '0')
+ --s;
+ ret1:
+ if (b)
+ Bfree(b MTb);
+ *s = 0;
+ *decpt = k + 1;
+ if (rve)
+ *rve = s;
+#ifdef SET_INEXACT
+ if (inexact) {
+ if (!oldinexact) {
+ word0(&u) = Exp_1 + (70 << Exp_shift);
+ word1(&u) = 0;
+ dval(&u) += 1.;
+ }
+ }
+ else if (!oldinexact)
+ clear_inexact();
+#endif
+ return buf;
+ }
+
+ char *
+dtoa(double dd, int mode, int ndigits, int *decpt, int *sign, char **rve)
+{
+ /* Sufficient space is allocated to the return value
+ to hold the suppressed trailing zeros.
+ See dtoa_r() above for details on the other arguments.
+ */
+#ifndef MULTIPLE_THREADS
+ if (dtoa_result)
+ freedtoa(dtoa_result);
+#endif
+ return dtoa_r(dd, mode, ndigits, decpt, sign, rve, 0, 0);
+ }
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/csgo2/luaCjson/dtoa_config.h b/csgo2/luaCjson/dtoa_config.h
new file mode 100644
index 0000000..c168e28
--- /dev/null
+++ b/csgo2/luaCjson/dtoa_config.h
@@ -0,0 +1,78 @@
+#ifndef _DTOA_CONFIG_H
+#define _DTOA_CONFIG_H
+
+#include
+#include
+#include
+
+/* Ensure dtoa.c does not USE_LOCALE. Lua CJSON must not use locale
+ * aware conversion routines. */
+#undef USE_LOCALE
+
+/* dtoa.c should not touch errno, Lua CJSON does not use it, and it
+ * may not be threadsafe */
+#define NO_ERRNO
+
+#define Long int32_t
+#define ULong uint32_t
+#define Llong int64_t
+#define ULLong uint64_t
+
+#ifdef IEEE_BIG_ENDIAN
+#define IEEE_MC68k
+#else
+#define IEEE_8087
+#endif
+
+#define MALLOC xmalloc
+
+static void *xmalloc(size_t size)
+{
+ void *p;
+
+ p = malloc(size);
+ if (!p) {
+ fprintf(stderr, "Out of memory");
+ abort();
+ }
+
+ return p;
+}
+
+#ifdef MULTIPLE_THREADS
+
+/* Enable locking to support multi-threaded applications */
+
+#include
+
+static pthread_mutex_t private_dtoa_lock[2] = {
+ PTHREAD_MUTEX_INITIALIZER,
+ PTHREAD_MUTEX_INITIALIZER
+};
+
+#define dtoa_get_threadno pthread_self
+void
+set_max_dtoa_threads(unsigned int n);
+
+#define ACQUIRE_DTOA_LOCK(n) do { \
+ int r = pthread_mutex_lock(&private_dtoa_lock[n]); \
+ if (r) { \
+ fprintf(stderr, "pthread_mutex_lock failed with %d\n", r); \
+ abort(); \
+ } \
+} while (0)
+
+#define FREE_DTOA_LOCK(n) do { \
+ int r = pthread_mutex_unlock(&private_dtoa_lock[n]); \
+ if (r) { \
+ fprintf(stderr, "pthread_mutex_unlock failed with %d\n", r);\
+ abort(); \
+ } \
+} while (0)
+
+#endif /* MULTIPLE_THREADS */
+
+#endif /* _DTOA_CONFIG_H */
+
+/* vi:ai et sw=4 ts=4:
+ */
diff --git a/csgo2/luaCjson/fpconv.c b/csgo2/luaCjson/fpconv.c
new file mode 100644
index 0000000..0ef7f18
--- /dev/null
+++ b/csgo2/luaCjson/fpconv.c
@@ -0,0 +1,211 @@
+/* fpconv - Floating point conversion routines
+ *
+ * Copyright (c) 2011-2012 Mark Pulford
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* JSON uses a '.' decimal separator. strtod() / sprintf() under C libraries
+ * with locale support will break when the decimal separator is a comma.
+ *
+ * fpconv_* will around these issues with a translation buffer if required.
+ */
+
+#include
+#include
+#include
+#include
+
+#include "fpconv.h"
+
+/* Workaround for MSVC */
+#ifdef _MSC_VER
+#define inline __inline
+#define snprintf sprintf_s
+#endif
+
+/* Lua CJSON assumes the locale is the same for all threads within a
+ * process and doesn't change after initialisation.
+ *
+ * This avoids the need for per thread storage or expensive checks
+ * for call. */
+static char locale_decimal_point = '.';
+
+/* In theory multibyte decimal_points are possible, but
+ * Lua CJSON only supports UTF-8 and known locales only have
+ * single byte decimal points ([.,]).
+ *
+ * localconv() may not be thread safe (=>crash), and nl_langinfo() is
+ * not supported on some platforms. Use sprintf() instead - if the
+ * locale does change, at least Lua CJSON won't crash. */
+static void fpconv_update_locale(void)
+{
+ char buf[8];
+
+ snprintf(buf, sizeof(buf), "%g", 0.5);
+
+ /* Failing this test might imply the platform has a buggy dtoa
+ * implementation or wide characters */
+ if (buf[0] != '0' || buf[2] != '5' || buf[3] != 0) {
+ fprintf(stderr, "Error: wide characters found or printf() bug.");
+ abort();
+ }
+
+ locale_decimal_point = buf[1];
+}
+
+/* Check for a valid number character: [-+0-9a-yA-Y.]
+ * Eg: -0.6e+5, infinity, 0xF0.F0pF0
+ *
+ * Used to find the probable end of a number. It doesn't matter if
+ * invalid characters are counted - strtod() will find the valid
+ * number if it exists. The risk is that slightly more memory might
+ * be allocated before a parse error occurs. */
+static inline int valid_number_character(char ch)
+{
+ char lower_ch;
+
+ if ('0' <= ch && ch <= '9')
+ return 1;
+ if (ch == '-' || ch == '+' || ch == '.')
+ return 1;
+
+ /* Hex digits, exponent (e), base (p), "infinity",.. */
+ lower_ch = ch | 0x20;
+ if ('a' <= lower_ch && lower_ch <= 'y')
+ return 1;
+
+ return 0;
+}
+
+/* Calculate the size of the buffer required for a strtod locale
+ * conversion. */
+static int strtod_buffer_size(const char *s)
+{
+ const char *p = s;
+
+ while (valid_number_character(*p))
+ p++;
+
+ return p - s;
+}
+
+/* Similar to strtod(), but must be passed the current locale's decimal point
+ * character. Guaranteed to be called at the start of any valid number in a string */
+double fpconv_strtod(const char *nptr, char **endptr)
+{
+ char localbuf[FPCONV_G_FMT_BUFSIZE];
+ char *buf, *endbuf, *dp;
+ int buflen;
+ double value;
+
+ /* System strtod() is fine when decimal point is '.' */
+ if (locale_decimal_point == '.')
+ return strtod(nptr, endptr);
+
+ buflen = strtod_buffer_size(nptr);
+ if (!buflen) {
+ /* No valid characters found, standard strtod() return */
+ *endptr = (char *)nptr;
+ return 0;
+ }
+
+ /* Duplicate number into buffer */
+ if (buflen >= FPCONV_G_FMT_BUFSIZE) {
+ /* Handle unusually large numbers */
+ buf = malloc(buflen + 1);
+ if (!buf) {
+ fprintf(stderr, "Out of memory");
+ abort();
+ }
+ } else {
+ /* This is the common case.. */
+ buf = localbuf;
+ }
+ memcpy(buf, nptr, buflen);
+ buf[buflen] = 0;
+
+ /* Update decimal point character if found */
+ dp = strchr(buf, '.');
+ if (dp)
+ *dp = locale_decimal_point;
+
+ value = strtod(buf, &endbuf);
+ *endptr = (char *)&nptr[endbuf - buf];
+ if (buflen >= FPCONV_G_FMT_BUFSIZE)
+ free(buf);
+
+ return value;
+}
+
+/* "fmt" must point to a buffer of at least 6 characters */
+static void set_number_format(char *fmt, int precision)
+{
+ int d1, d2, i;
+
+ assert(1 <= precision && precision <= 16);
+
+ /* Create printf format (%.14g) from precision */
+ d1 = precision / 10;
+ d2 = precision % 10;
+ fmt[0] = '%';
+ fmt[1] = '.';
+ i = 2;
+ if (d1) {
+ fmt[i++] = '0' + d1;
+ }
+ fmt[i++] = '0' + d2;
+ fmt[i++] = 'g';
+ fmt[i] = 0;
+}
+
+/* Assumes there is always at least 32 characters available in the target buffer */
+int fpconv_g_fmt(char *str, double num, int precision)
+{
+ char buf[FPCONV_G_FMT_BUFSIZE];
+ char fmt[6];
+ int len;
+ char *b;
+
+ set_number_format(fmt, precision);
+
+ /* Pass through when decimal point character is dot. */
+ if (locale_decimal_point == '.')
+ return snprintf(str, FPCONV_G_FMT_BUFSIZE, fmt, num);
+
+ /* snprintf() to a buffer then translate for other decimal point characters */
+ len = snprintf(buf, FPCONV_G_FMT_BUFSIZE, fmt, num);
+
+ /* Copy into target location. Translate decimal point if required */
+ b = buf;
+ do {
+ *str++ = (*b == locale_decimal_point ? '.' : *b);
+ } while(*b++);
+
+ return len;
+}
+
+void fpconv_init(void)
+{
+ fpconv_update_locale();
+}
+
+/* vi:ai et sw=4 ts=4:
+ */
diff --git a/csgo2/luaCjson/fpconv.h b/csgo2/luaCjson/fpconv.h
new file mode 100644
index 0000000..5d9d95e
--- /dev/null
+++ b/csgo2/luaCjson/fpconv.h
@@ -0,0 +1,32 @@
+/* Lua CJSON floating point conversion routines */
+
+/* Buffer required to store the largest string representation of a double.
+ *
+ * Longest double printed with %.14g is 21 characters long:
+ * -1.7976931348623e+308 */
+# define FPCONV_G_FMT_BUFSIZE 32
+
+#ifdef USE_INTERNAL_FPCONV
+#ifdef MULTIPLE_THREADS
+#include "dtoa_config.h"
+#include
+static inline void fpconv_init()
+{
+ // Add one to try and avoid core id multiplier alignment
+ set_max_dtoa_threads((sysconf(_SC_NPROCESSORS_CONF) + 1) * 3);
+}
+#else
+static inline void fpconv_init()
+{
+ /* Do nothing - not required */
+}
+#endif
+#else
+extern void fpconv_init(void);
+#endif
+
+extern int fpconv_g_fmt(char*, double, int);
+extern double fpconv_strtod(const char*, char**);
+
+/* vi:ai et sw=4 ts=4:
+ */
diff --git a/csgo2/luaCjson/g_fmt.c b/csgo2/luaCjson/g_fmt.c
new file mode 100644
index 0000000..50d6a1d
--- /dev/null
+++ b/csgo2/luaCjson/g_fmt.c
@@ -0,0 +1,111 @@
+/****************************************************************
+ *
+ * The author of this software is David M. Gay.
+ *
+ * Copyright (c) 1991, 1996 by Lucent Technologies.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose without fee is hereby granted, provided that this entire notice
+ * is included in all copies of any software which is or includes a copy
+ * or modification of this software and in all copies of the supporting
+ * documentation for such software.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY
+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
+ * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
+ *
+ ***************************************************************/
+
+/* g_fmt(buf,x) stores the closest decimal approximation to x in buf;
+ * it suffices to declare buf
+ * char buf[32];
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ extern char *dtoa(double, int, int, int *, int *, char **);
+ extern int g_fmt(char *, double, int);
+ extern void freedtoa(char*);
+#ifdef __cplusplus
+ }
+#endif
+
+int
+fpconv_g_fmt(char *b, double x, int precision)
+{
+ register int i, k;
+ register char *s;
+ int decpt, j, sign;
+ char *b0, *s0, *se;
+
+ b0 = b;
+#ifdef IGNORE_ZERO_SIGN
+ if (!x) {
+ *b++ = '0';
+ *b = 0;
+ goto done;
+ }
+#endif
+ s = s0 = dtoa(x, 2, precision, &decpt, &sign, &se);
+ if (sign)
+ *b++ = '-';
+ if (decpt == 9999) /* Infinity or Nan */ {
+ while((*b++ = *s++));
+ /* "b" is used to calculate the return length. Decrement to exclude the
+ * Null terminator from the length */
+ b--;
+ goto done0;
+ }
+ if (decpt <= -4 || decpt > precision) {
+ *b++ = *s++;
+ if (*s) {
+ *b++ = '.';
+ while((*b = *s++))
+ b++;
+ }
+ *b++ = 'e';
+ /* sprintf(b, "%+.2d", decpt - 1); */
+ if (--decpt < 0) {
+ *b++ = '-';
+ decpt = -decpt;
+ }
+ else
+ *b++ = '+';
+ for(j = 2, k = 10; 10*k <= decpt; j++, k *= 10);
+ for(;;) {
+ i = decpt / k;
+ *b++ = i + '0';
+ if (--j <= 0)
+ break;
+ decpt -= i*k;
+ decpt *= 10;
+ }
+ *b = 0;
+ }
+ else if (decpt <= 0) {
+ *b++ = '0';
+ *b++ = '.';
+ for(; decpt < 0; decpt++)
+ *b++ = '0';
+ while((*b++ = *s++));
+ b--;
+ }
+ else {
+ while((*b = *s++)) {
+ b++;
+ if (--decpt == 0 && *s)
+ *b++ = '.';
+ }
+ for(; decpt > 0; decpt--)
+ *b++ = '0';
+ *b = 0;
+ }
+ done0:
+ freedtoa(s0);
+#ifdef IGNORE_ZERO_SIGN
+ done:
+#endif
+ return b - b0;
+ }
diff --git a/csgo2/luaCjson/lua_cjson.c b/csgo2/luaCjson/lua_cjson.c
new file mode 100644
index 0000000..71dc71f
--- /dev/null
+++ b/csgo2/luaCjson/lua_cjson.c
@@ -0,0 +1,1623 @@
+/* Lua CJSON - JSON support for Lua
+ *
+ * Copyright (c) 2010-2012 Mark Pulford
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* Caveats:
+ * - JSON "null" values are represented as lightuserdata since Lua
+ * tables cannot contain "nil". Compare with cjson.null.
+ * - Invalid UTF-8 characters are not detected and will be passed
+ * untouched. If required, UTF-8 error checking should be done
+ * outside this library.
+ * - Javascript comments are not part of the JSON spec, and are not
+ * currently supported.
+ *
+ * Note: Decoding is slower than encoding. Lua spends significant
+ * time (30%) managing tables when parsing JSON since it is
+ * difficult to know object/array sizes ahead of time.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include "../lua/lua.h"
+#include "../lua/lualib.h"
+
+#include "strbuf.h"
+#include "fpconv.h"
+
+#ifndef CJSON_MODNAME
+#define CJSON_MODNAME "cjson"
+#endif
+
+#ifndef CJSON_VERSION
+#define CJSON_VERSION "2.1.0.11"
+#endif
+
+#ifdef _MSC_VER
+#ifndef isnan
+#include
+#define isnan(x) _isnan(x)
+#endif
+#include "../lua/lauxlib.h"
+
+#endif
+
+/* Workaround for Solaris platforms missing isinf() */
+#if !defined(isinf) && (defined(USE_INTERNAL_ISINF) || defined(MISSING_ISINF))
+#define isinf(x) (!isnan(x) && isnan((x) - (x)))
+#endif
+
+#define DEFAULT_SPARSE_CONVERT 0
+#define DEFAULT_SPARSE_RATIO 2
+#define DEFAULT_SPARSE_SAFE 10
+#define DEFAULT_ENCODE_MAX_DEPTH 1000
+#define DEFAULT_DECODE_MAX_DEPTH 1000
+#define DEFAULT_ENCODE_INVALID_NUMBERS 0
+#define DEFAULT_DECODE_INVALID_NUMBERS 1
+#define DEFAULT_ENCODE_KEEP_BUFFER 1
+#define DEFAULT_ENCODE_NUMBER_PRECISION 14
+#define DEFAULT_ENCODE_EMPTY_TABLE_AS_OBJECT 1
+#define DEFAULT_DECODE_ARRAY_WITH_ARRAY_MT 0
+#define DEFAULT_ENCODE_ESCAPE_FORWARD_SLASH 1
+#define DEFAULT_ENCODE_SKIP_UNSUPPORTED_VALUE_TYPES 0
+
+#ifdef DISABLE_INVALID_NUMBERS
+#undef DEFAULT_DECODE_INVALID_NUMBERS
+#define DEFAULT_DECODE_INVALID_NUMBERS 0
+#endif
+
+#ifdef _MSC_VER
+/* Microsoft C compiler lacks strncasecmp and strcasecmp. */
+#define strncasecmp _strnicmp
+#define strcasecmp _stricmp
+#endif
+
+#if LONG_MAX > ((1UL << 31) - 1)
+#define json_lightudata_mask(ludata) \
+ ((void *) ((uintptr_t) (ludata) & ((1UL << 47) - 1)))
+
+#else
+#define json_lightudata_mask(ludata) (ludata)
+#endif
+
+#if LUA_VERSION_NUM > 501
+#define lua_objlen(L,i) lua_rawlen(L, (i))
+#endif
+
+static const char * const *json_empty_array;
+static const char * const *json_array;
+
+typedef enum {
+ T_OBJ_BEGIN,
+ T_OBJ_END,
+ T_ARR_BEGIN,
+ T_ARR_END,
+ T_STRING,
+ T_NUMBER,
+ T_BOOLEAN,
+ T_NULL,
+ T_COLON,
+ T_COMMA,
+ T_END,
+ T_WHITESPACE,
+ T_ERROR,
+ T_UNKNOWN
+} json_token_type_t;
+
+static const char *json_token_type_name[] = {
+ "T_OBJ_BEGIN",
+ "T_OBJ_END",
+ "T_ARR_BEGIN",
+ "T_ARR_END",
+ "T_STRING",
+ "T_NUMBER",
+ "T_BOOLEAN",
+ "T_NULL",
+ "T_COLON",
+ "T_COMMA",
+ "T_END",
+ "T_WHITESPACE",
+ "T_ERROR",
+ "T_UNKNOWN",
+ NULL
+};
+
+typedef struct {
+ json_token_type_t ch2token[256];
+ char escape2char[256]; /* Decoding */
+
+ /* encode_buf is only allocated and used when
+ * encode_keep_buffer is set */
+ strbuf_t encode_buf;
+
+ int encode_sparse_convert;
+ int encode_sparse_ratio;
+ int encode_sparse_safe;
+ int encode_max_depth;
+ int encode_invalid_numbers; /* 2 => Encode as "null" */
+ int encode_number_precision;
+ int encode_keep_buffer;
+ int encode_empty_table_as_object;
+ int encode_escape_forward_slash;
+
+ int decode_invalid_numbers;
+ int decode_max_depth;
+ int decode_array_with_array_mt;
+ int encode_skip_unsupported_value_types;
+} json_config_t;
+
+typedef struct {
+ const char *data;
+ const char *ptr;
+ strbuf_t *tmp; /* Temporary storage for strings */
+ json_config_t *cfg;
+ int current_depth;
+} json_parse_t;
+
+typedef struct {
+ json_token_type_t type;
+ size_t index;
+ union {
+ const char *string;
+ double number;
+ int boolean;
+ } value;
+ size_t string_len;
+} json_token_t;
+
+static const char *char2escape[256] = {
+ "\\u0000", "\\u0001", "\\u0002", "\\u0003",
+ "\\u0004", "\\u0005", "\\u0006", "\\u0007",
+ "\\b", "\\t", "\\n", "\\u000b",
+ "\\f", "\\r", "\\u000e", "\\u000f",
+ "\\u0010", "\\u0011", "\\u0012", "\\u0013",
+ "\\u0014", "\\u0015", "\\u0016", "\\u0017",
+ "\\u0018", "\\u0019", "\\u001a", "\\u001b",
+ "\\u001c", "\\u001d", "\\u001e", "\\u001f",
+ NULL, NULL, "\\\"", NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "\\/",
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\\\\", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "\\u007f",
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+};
+
+/* ===== CONFIGURATION ===== */
+
+static json_config_t *json_fetch_config(lua_State *l)
+{
+ json_config_t *cfg;
+
+ cfg = lua_touserdata(l, lua_upvalueindex(1));
+ if (!cfg)
+ luaL_error(l, "BUG: Unable to fetch CJSON configuration");
+
+ return cfg;
+}
+
+/* Ensure the correct number of arguments have been provided.
+ * Pad with nil to allow other functions to simply check arg[i]
+ * to find whether an argument was provided */
+static json_config_t *json_arg_init(lua_State *l, int args)
+{
+ luaL_argcheck(l, lua_gettop(l) <= args, args + 1,
+ "found too many arguments");
+
+ while (lua_gettop(l) < args)
+ lua_pushnil(l);
+
+ return json_fetch_config(l);
+}
+
+/* Process integer options for configuration functions */
+static int json_integer_option(lua_State *l, int optindex, int *setting,
+ int min, int max)
+{
+ char errmsg[64];
+ int value;
+
+ if (!lua_isnil(l, optindex)) {
+ value = luaL_checkinteger(l, optindex);
+ snprintf(errmsg, sizeof(errmsg), "expected integer between %d and %d", min, max);
+ luaL_argcheck(l, min <= value && value <= max, 1, errmsg);
+ *setting = value;
+ }
+
+ lua_pushinteger(l, *setting);
+
+ return 1;
+}
+
+/* Process enumerated arguments for a configuration function */
+static int json_enum_option(lua_State *l, int optindex, int *setting,
+ const char **options, int bool_true)
+{
+ static const char *bool_options[] = { "off", "on", NULL };
+
+ if (!options) {
+ options = bool_options;
+ bool_true = 1;
+ }
+
+ if (!lua_isnil(l, optindex)) {
+ if (bool_true && lua_isboolean(l, optindex))
+ *setting = lua_toboolean(l, optindex) * bool_true;
+ else
+ *setting = luaL_checkoption(l, optindex, NULL, options);
+ }
+
+ if (bool_true && (*setting == 0 || *setting == bool_true))
+ lua_pushboolean(l, *setting);
+ else
+ lua_pushstring(l, options[*setting]);
+
+ return 1;
+}
+
+/* Configures handling of extremely sparse arrays:
+ * convert: Convert extremely sparse arrays into objects? Otherwise error.
+ * ratio: 0: always allow sparse; 1: never allow sparse; >1: use ratio
+ * safe: Always use an array when the max index <= safe */
+static int json_cfg_encode_sparse_array(lua_State *l)
+{
+ json_config_t *cfg = json_arg_init(l, 3);
+
+ json_enum_option(l, 1, &cfg->encode_sparse_convert, NULL, 1);
+ json_integer_option(l, 2, &cfg->encode_sparse_ratio, 0, INT_MAX);
+ json_integer_option(l, 3, &cfg->encode_sparse_safe, 0, INT_MAX);
+
+ return 3;
+}
+
+/* Configures the maximum number of nested arrays/objects allowed when
+ * encoding */
+static int json_cfg_encode_max_depth(lua_State *l)
+{
+ json_config_t *cfg = json_arg_init(l, 1);
+
+ return json_integer_option(l, 1, &cfg->encode_max_depth, 1, INT_MAX);
+}
+
+/* Configures the maximum number of nested arrays/objects allowed when
+ * encoding */
+static int json_cfg_decode_max_depth(lua_State *l)
+{
+ json_config_t *cfg = json_arg_init(l, 1);
+
+ return json_integer_option(l, 1, &cfg->decode_max_depth, 1, INT_MAX);
+}
+
+/* Configures number precision when converting doubles to text */
+static int json_cfg_encode_number_precision(lua_State *l)
+{
+ json_config_t *cfg = json_arg_init(l, 1);
+
+ return json_integer_option(l, 1, &cfg->encode_number_precision, 1, 16);
+}
+
+/* Configures how to treat empty table when encode lua table */
+static int json_cfg_encode_empty_table_as_object(lua_State *l)
+{
+ json_config_t *cfg = json_arg_init(l, 1);
+
+ return json_enum_option(l, 1, &cfg->encode_empty_table_as_object, NULL, 1);
+}
+
+/* Configures how to decode arrays */
+static int json_cfg_decode_array_with_array_mt(lua_State *l)
+{
+ json_config_t *cfg = json_arg_init(l, 1);
+
+ json_enum_option(l, 1, &cfg->decode_array_with_array_mt, NULL, 1);
+
+ return 1;
+}
+
+/* Configure how to treat invalid types */
+static int json_cfg_encode_skip_unsupported_value_types(lua_State *l)
+{
+ json_config_t *cfg = json_arg_init(l, 1);
+
+ json_enum_option(l, 1, &cfg->encode_skip_unsupported_value_types, NULL, 1);
+
+ return 1;
+}
+
+/* Configures JSON encoding buffer persistence */
+static int json_cfg_encode_keep_buffer(lua_State *l)
+{
+ json_config_t *cfg = json_arg_init(l, 1);
+ int old_value;
+
+ old_value = cfg->encode_keep_buffer;
+
+ json_enum_option(l, 1, &cfg->encode_keep_buffer, NULL, 1);
+
+ /* Init / free the buffer if the setting has changed */
+ if (old_value ^ cfg->encode_keep_buffer) {
+ if (cfg->encode_keep_buffer)
+ strbuf_init(&cfg->encode_buf, 0);
+ else
+ strbuf_free(&cfg->encode_buf);
+ }
+
+ return 1;
+}
+
+#if defined(DISABLE_INVALID_NUMBERS) && !defined(USE_INTERNAL_FPCONV)
+void json_verify_invalid_number_setting(lua_State *l, int *setting)
+{
+ if (*setting == 1) {
+ *setting = 0;
+ luaL_error(l, "Infinity, NaN, and/or hexadecimal numbers are not supported.");
+ }
+}
+#else
+#define json_verify_invalid_number_setting(l, s) do { } while(0)
+#endif
+
+static int json_cfg_encode_invalid_numbers(lua_State *l)
+{
+ static const char *options[] = { "off", "on", "null", NULL };
+ json_config_t *cfg = json_arg_init(l, 1);
+
+ json_enum_option(l, 1, &cfg->encode_invalid_numbers, options, 1);
+
+ json_verify_invalid_number_setting(l, &cfg->encode_invalid_numbers);
+
+ return 1;
+}
+
+static int json_cfg_decode_invalid_numbers(lua_State *l)
+{
+ json_config_t *cfg = json_arg_init(l, 1);
+
+ json_enum_option(l, 1, &cfg->decode_invalid_numbers, NULL, 1);
+
+ json_verify_invalid_number_setting(l, &cfg->encode_invalid_numbers);
+
+ return 1;
+}
+
+static int json_cfg_encode_escape_forward_slash(lua_State *l)
+{
+ int ret;
+ json_config_t *cfg = json_arg_init(l, 1);
+
+ ret = json_enum_option(l, 1, &cfg->encode_escape_forward_slash, NULL, 1);
+ if (cfg->encode_escape_forward_slash) {
+ char2escape['/'] = "\\/";
+ } else {
+ char2escape['/'] = NULL;
+ }
+ return ret;
+}
+
+static int json_destroy_config(lua_State *l)
+{
+ json_config_t *cfg;
+
+ cfg = lua_touserdata(l, 1);
+ if (cfg)
+ strbuf_free(&cfg->encode_buf);
+ cfg = NULL;
+
+ return 0;
+}
+
+static void json_create_config(lua_State *l)
+{
+ json_config_t *cfg;
+ int i;
+
+ cfg = lua_newuserdata(l, sizeof(*cfg));
+
+ /* Create GC method to clean up strbuf */
+ lua_newtable(l);
+ lua_pushcfunction(l, json_destroy_config);
+ lua_setfield(l, -2, "__gc");
+ lua_setmetatable(l, -2);
+
+ cfg->encode_sparse_convert = DEFAULT_SPARSE_CONVERT;
+ cfg->encode_sparse_ratio = DEFAULT_SPARSE_RATIO;
+ cfg->encode_sparse_safe = DEFAULT_SPARSE_SAFE;
+ cfg->encode_max_depth = DEFAULT_ENCODE_MAX_DEPTH;
+ cfg->decode_max_depth = DEFAULT_DECODE_MAX_DEPTH;
+ cfg->encode_invalid_numbers = DEFAULT_ENCODE_INVALID_NUMBERS;
+ cfg->decode_invalid_numbers = DEFAULT_DECODE_INVALID_NUMBERS;
+ cfg->encode_keep_buffer = DEFAULT_ENCODE_KEEP_BUFFER;
+ cfg->encode_number_precision = DEFAULT_ENCODE_NUMBER_PRECISION;
+ cfg->encode_empty_table_as_object = DEFAULT_ENCODE_EMPTY_TABLE_AS_OBJECT;
+ cfg->decode_array_with_array_mt = DEFAULT_DECODE_ARRAY_WITH_ARRAY_MT;
+ cfg->encode_escape_forward_slash = DEFAULT_ENCODE_ESCAPE_FORWARD_SLASH;
+ cfg->encode_skip_unsupported_value_types = DEFAULT_ENCODE_SKIP_UNSUPPORTED_VALUE_TYPES;
+
+#if DEFAULT_ENCODE_KEEP_BUFFER > 0
+ strbuf_init(&cfg->encode_buf, 0);
+#endif
+
+ /* Decoding init */
+
+ /* Tag all characters as an error */
+ for (i = 0; i < 256; i++)
+ cfg->ch2token[i] = T_ERROR;
+
+ /* Set tokens that require no further processing */
+ cfg->ch2token['{'] = T_OBJ_BEGIN;
+ cfg->ch2token['}'] = T_OBJ_END;
+ cfg->ch2token['['] = T_ARR_BEGIN;
+ cfg->ch2token[']'] = T_ARR_END;
+ cfg->ch2token[','] = T_COMMA;
+ cfg->ch2token[':'] = T_COLON;
+ cfg->ch2token['\0'] = T_END;
+ cfg->ch2token[' '] = T_WHITESPACE;
+ cfg->ch2token['\t'] = T_WHITESPACE;
+ cfg->ch2token['\n'] = T_WHITESPACE;
+ cfg->ch2token['\r'] = T_WHITESPACE;
+
+ /* Update characters that require further processing */
+ cfg->ch2token['f'] = T_UNKNOWN; /* false? */
+ cfg->ch2token['i'] = T_UNKNOWN; /* inf, ininity? */
+ cfg->ch2token['I'] = T_UNKNOWN;
+ cfg->ch2token['n'] = T_UNKNOWN; /* null, nan? */
+ cfg->ch2token['N'] = T_UNKNOWN;
+ cfg->ch2token['t'] = T_UNKNOWN; /* true? */
+ cfg->ch2token['"'] = T_UNKNOWN; /* string? */
+ cfg->ch2token['+'] = T_UNKNOWN; /* number? */
+ cfg->ch2token['-'] = T_UNKNOWN;
+ for (i = 0; i < 10; i++)
+ cfg->ch2token['0' + i] = T_UNKNOWN;
+
+ /* Lookup table for parsing escape characters */
+ for (i = 0; i < 256; i++)
+ cfg->escape2char[i] = 0; /* String error */
+ cfg->escape2char['"'] = '"';
+ cfg->escape2char['\\'] = '\\';
+ cfg->escape2char['/'] = '/';
+ cfg->escape2char['b'] = '\b';
+ cfg->escape2char['t'] = '\t';
+ cfg->escape2char['n'] = '\n';
+ cfg->escape2char['f'] = '\f';
+ cfg->escape2char['r'] = '\r';
+ cfg->escape2char['u'] = 'u'; /* Unicode parsing required */
+}
+
+/* ===== ENCODING ===== */
+
+static void json_encode_exception(lua_State *l, json_config_t *cfg, strbuf_t *json, int lindex,
+ const char *reason)
+{
+ if (!cfg->encode_keep_buffer)
+ strbuf_free(json);
+ luaL_error(l, "Cannot serialise %s: %s",
+ lua_typename(l, lua_type(l, lindex)), reason);
+}
+
+/* json_append_string args:
+ * - lua_State
+ * - JSON strbuf
+ * - String (Lua stack index)
+ *
+ * Returns nothing. Doesn't remove string from Lua stack */
+static void json_append_string(lua_State *l, strbuf_t *json, int lindex)
+{
+ const char *escstr;
+ unsigned i;
+ const char *str;
+ size_t len;
+
+ str = lua_tolstring(l, lindex, &len);
+
+ /* Worst case is len * 6 (all unicode escapes).
+ * This buffer is reused constantly for small strings
+ * If there are any excess pages, they won't be hit anyway.
+ * This gains ~5% speedup. */
+ if (len > SIZE_MAX / 6 - 3)
+ abort(); /* Overflow check */
+ strbuf_ensure_empty_length(json, len * 6 + 2);
+
+ strbuf_append_char_unsafe(json, '\"');
+ for (i = 0; i < len; i++) {
+ escstr = char2escape[(unsigned char)str[i]];
+ if (escstr)
+ strbuf_append_string(json, escstr);
+ else
+ strbuf_append_char_unsafe(json, str[i]);
+ }
+ strbuf_append_char_unsafe(json, '\"');
+}
+
+/* Find the size of the array on the top of the Lua stack
+ * -1 object (not a pure array)
+ * >=0 elements in array
+ */
+static int lua_array_length(lua_State *l, json_config_t *cfg, strbuf_t *json)
+{
+ double k;
+ int max;
+ int items;
+
+ max = 0;
+ items = 0;
+
+ lua_pushnil(l);
+ /* table, startkey */
+ while (lua_next(l, -2) != 0) {
+ /* table, key, value */
+ if (lua_type(l, -2) == LUA_TNUMBER &&
+ (k = lua_tonumber(l, -2))) {
+ /* Integer >= 1 ? */
+ if (floor(k) == k && k >= 1) {
+ if (k > max)
+ max = k;
+ items++;
+ lua_pop(l, 1);
+ continue;
+ }
+ }
+
+ /* Must not be an array (non integer key) */
+ lua_pop(l, 2);
+ return -1;
+ }
+
+ /* Encode excessively sparse arrays as objects (if enabled) */
+ if (cfg->encode_sparse_ratio > 0 &&
+ max > items * cfg->encode_sparse_ratio &&
+ max > cfg->encode_sparse_safe) {
+ if (!cfg->encode_sparse_convert)
+ json_encode_exception(l, cfg, json, -1, "excessively sparse array");
+
+ return -1;
+ }
+
+ return max;
+}
+
+static void json_check_encode_depth(lua_State *l, json_config_t *cfg,
+ int current_depth, strbuf_t *json)
+{
+ /* Ensure there are enough slots free to traverse a table (key,
+ * value) and push a string for a potential error message.
+ *
+ * Unlike "decode", the key and value are still on the stack when
+ * lua_checkstack() is called. Hence an extra slot for luaL_error()
+ * below is required just in case the next check to lua_checkstack()
+ * fails.
+ *
+ * While this won't cause a crash due to the EXTRA_STACK reserve
+ * slots, it would still be an improper use of the API. */
+ if (current_depth <= cfg->encode_max_depth && lua_checkstack(l, 3))
+ return;
+
+ if (!cfg->encode_keep_buffer)
+ strbuf_free(json);
+
+ luaL_error(l, "Cannot serialise, excessive nesting (%d)",
+ current_depth);
+}
+
+static int json_append_data(lua_State *l, json_config_t *cfg,
+ int current_depth, strbuf_t *json);
+
+/* json_append_array args:
+ * - lua_State
+ * - JSON strbuf
+ * - Size of passwd Lua array (top of stack) */
+static void json_append_array(lua_State *l, json_config_t *cfg, int current_depth,
+ strbuf_t *json, int array_length)
+{
+ int comma, i, json_pos, err;
+
+ strbuf_append_char(json, '[');
+
+ comma = 0;
+ for (i = 1; i <= array_length; i++) {
+ json_pos = strbuf_length(json);
+ if (comma++ > 0)
+ strbuf_append_char(json, ',');
+
+ lua_rawgeti(l, -1, i);
+ err = json_append_data(l, cfg, current_depth, json);
+ if (err) {
+ strbuf_set_length(json, json_pos);
+ if (comma == 1) {
+ comma = 0;
+ }
+ }
+ lua_pop(l, 1);
+ }
+
+ strbuf_append_char(json, ']');
+}
+
+static void json_append_number(lua_State *l, json_config_t *cfg,
+ strbuf_t *json, int lindex)
+{
+ double num = lua_tonumber(l, lindex);
+ int len;
+
+ if (cfg->encode_invalid_numbers == 0) {
+ /* Prevent encoding invalid numbers */
+ if (isinf(num) || isnan(num))
+ json_encode_exception(l, cfg, json, lindex,
+ "must not be NaN or Infinity");
+ } else if (cfg->encode_invalid_numbers == 1) {
+ /* Encode NaN/Infinity separately to ensure Javascript compatible
+ * values are used. */
+ if (isnan(num)) {
+ strbuf_append_mem(json, "NaN", 3);
+ return;
+ }
+ if (isinf(num)) {
+ if (num < 0)
+ strbuf_append_mem(json, "-Infinity", 9);
+ else
+ strbuf_append_mem(json, "Infinity", 8);
+ return;
+ }
+ } else {
+ /* Encode invalid numbers as "null" */
+ if (isinf(num) || isnan(num)) {
+ strbuf_append_mem(json, "null", 4);
+ return;
+ }
+ }
+
+ strbuf_ensure_empty_length(json, FPCONV_G_FMT_BUFSIZE);
+ len = fpconv_g_fmt(strbuf_empty_ptr(json), num, cfg->encode_number_precision);
+ strbuf_extend_length(json, len);
+}
+
+static void json_append_object(lua_State *l, json_config_t *cfg,
+ int current_depth, strbuf_t *json)
+{
+ int comma, keytype, json_pos, err;
+
+ /* Object */
+ strbuf_append_char(json, '{');
+
+ lua_pushnil(l);
+ /* table, startkey */
+ comma = 0;
+ while (lua_next(l, -2) != 0) {
+ json_pos = strbuf_length(json);
+ if (comma++ > 0)
+ strbuf_append_char(json, ',');
+
+ /* table, key, value */
+ keytype = lua_type(l, -2);
+ if (keytype == LUA_TNUMBER) {
+ strbuf_append_char(json, '"');
+ json_append_number(l, cfg, json, -2);
+ strbuf_append_mem(json, "\":", 2);
+ } else if (keytype == LUA_TSTRING) {
+ json_append_string(l, json, -2);
+ strbuf_append_char(json, ':');
+ } else {
+ json_encode_exception(l, cfg, json, -2,
+ "table key must be a number or string");
+ /* never returns */
+ }
+
+ /* table, key, value */
+ err = json_append_data(l, cfg, current_depth, json);
+ if (err) {
+ strbuf_set_length(json, json_pos);
+ if (comma == 1) {
+ comma = 0;
+ }
+ }
+
+ lua_pop(l, 1);
+ /* table, key */
+ }
+
+ strbuf_append_char(json, '}');
+}
+
+/* Serialise Lua data into JSON string. Return 1 if error an error happened, else 0 */
+static int json_append_data(lua_State *l, json_config_t *cfg,
+ int current_depth, strbuf_t *json)
+{
+ int len;
+ int as_array = 0;
+ int has_metatable;
+
+ switch (lua_type(l, -1)) {
+ case LUA_TSTRING:
+ json_append_string(l, json, -1);
+ break;
+ case LUA_TNUMBER:
+ json_append_number(l, cfg, json, -1);
+ break;
+ case LUA_TBOOLEAN:
+ if (lua_toboolean(l, -1))
+ strbuf_append_mem(json, "true", 4);
+ else
+ strbuf_append_mem(json, "false", 5);
+ break;
+ case LUA_TTABLE:
+ current_depth++;
+ json_check_encode_depth(l, cfg, current_depth, json);
+
+ has_metatable = lua_getmetatable(l, -1);
+
+ if (has_metatable) {
+ lua_pushlightuserdata(l, json_lightudata_mask(&json_array));
+ lua_rawget(l, LUA_REGISTRYINDEX);
+ as_array = lua_rawequal(l, -1, -2);
+ lua_pop(l, 2);
+ }
+
+ if (as_array) {
+ len = lua_objlen(l, -1);
+ json_append_array(l, cfg, current_depth, json, len);
+ } else {
+ len = lua_array_length(l, cfg, json);
+
+ if (len > 0 || (len == 0 && !cfg->encode_empty_table_as_object)) {
+ json_append_array(l, cfg, current_depth, json, len);
+ } else {
+ if (has_metatable) {
+ lua_getmetatable(l, -1);
+ lua_pushlightuserdata(l, json_lightudata_mask(
+ &json_empty_array));
+ lua_rawget(l, LUA_REGISTRYINDEX);
+ as_array = lua_rawequal(l, -1, -2);
+ lua_pop(l, 2); /* pop pointer + metatable */
+ if (as_array) {
+ json_append_array(l, cfg, current_depth, json, 0);
+ break;
+ }
+ }
+ json_append_object(l, cfg, current_depth, json);
+ }
+ }
+ break;
+ case LUA_TNIL:
+ strbuf_append_mem(json, "null", 4);
+ break;
+ case LUA_TLIGHTUSERDATA:
+ if (lua_touserdata(l, -1) == NULL) {
+ strbuf_append_mem(json, "null", 4);
+ } else if (lua_touserdata(l, -1) == json_lightudata_mask(&json_array)) {
+ json_append_array(l, cfg, current_depth, json, 0);
+ }
+ break;
+ default:
+ /* Remaining types (LUA_TFUNCTION, LUA_TUSERDATA, LUA_TTHREAD,
+ * and LUA_TLIGHTUSERDATA) cannot be serialised */
+ if (cfg->encode_skip_unsupported_value_types) {
+ return 1;
+ } else {
+ json_encode_exception(l, cfg, json, -1, "type not supported");
+ }
+
+ /* never returns */
+ }
+ return 0;
+}
+
+static int json_encode(lua_State *l)
+{
+ json_config_t *cfg = json_fetch_config(l);
+ strbuf_t local_encode_buf;
+ strbuf_t *encode_buf;
+ char *json;
+ size_t len;
+
+ luaL_argcheck(l, lua_gettop(l) == 1, 1, "expected 1 argument");
+
+ if (!cfg->encode_keep_buffer) {
+ /* Use private buffer */
+ encode_buf = &local_encode_buf;
+ strbuf_init(encode_buf, 0);
+ } else {
+ /* Reuse existing buffer */
+ encode_buf = &cfg->encode_buf;
+ strbuf_reset(encode_buf);
+ }
+
+ json_append_data(l, cfg, 0, encode_buf);
+ json = strbuf_string(encode_buf, &len);
+
+ lua_pushlstring(l, json, len);
+
+ if (!cfg->encode_keep_buffer)
+ strbuf_free(encode_buf);
+
+ return 1;
+}
+
+/* ===== DECODING ===== */
+
+static void json_process_value(lua_State *l, json_parse_t *json,
+ json_token_t *token);
+
+static int hexdigit2int(char hex)
+{
+ if ('0' <= hex && hex <= '9')
+ return hex - '0';
+
+ /* Force lowercase */
+ hex |= 0x20;
+ if ('a' <= hex && hex <= 'f')
+ return 10 + hex - 'a';
+
+ return -1;
+}
+
+static int decode_hex4(const char *hex)
+{
+ int digit[4];
+ int i;
+
+ /* Convert ASCII hex digit to numeric digit
+ * Note: this returns an error for invalid hex digits, including
+ * NULL */
+ for (i = 0; i < 4; i++) {
+ digit[i] = hexdigit2int(hex[i]);
+ if (digit[i] < 0) {
+ return -1;
+ }
+ }
+
+ return (digit[0] << 12) +
+ (digit[1] << 8) +
+ (digit[2] << 4) +
+ digit[3];
+}
+
+/* Converts a Unicode codepoint to UTF-8.
+ * Returns UTF-8 string length, and up to 4 bytes in *utf8 */
+static int codepoint_to_utf8(char *utf8, int codepoint)
+{
+ /* 0xxxxxxx */
+ if (codepoint <= 0x7F) {
+ utf8[0] = codepoint;
+ return 1;
+ }
+
+ /* 110xxxxx 10xxxxxx */
+ if (codepoint <= 0x7FF) {
+ utf8[0] = (codepoint >> 6) | 0xC0;
+ utf8[1] = (codepoint & 0x3F) | 0x80;
+ return 2;
+ }
+
+ /* 1110xxxx 10xxxxxx 10xxxxxx */
+ if (codepoint <= 0xFFFF) {
+ utf8[0] = (codepoint >> 12) | 0xE0;
+ utf8[1] = ((codepoint >> 6) & 0x3F) | 0x80;
+ utf8[2] = (codepoint & 0x3F) | 0x80;
+ return 3;
+ }
+
+ /* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
+ if (codepoint <= 0x1FFFFF) {
+ utf8[0] = (codepoint >> 18) | 0xF0;
+ utf8[1] = ((codepoint >> 12) & 0x3F) | 0x80;
+ utf8[2] = ((codepoint >> 6) & 0x3F) | 0x80;
+ utf8[3] = (codepoint & 0x3F) | 0x80;
+ return 4;
+ }
+
+ return 0;
+}
+
+
+/* Called when index pointing to beginning of UTF-16 code escape: \uXXXX
+ * \u is guaranteed to exist, but the remaining hex characters may be
+ * missing.
+ * Translate to UTF-8 and append to temporary token string.
+ * Must advance index to the next character to be processed.
+ * Returns: 0 success
+ * -1 error
+ */
+static int json_append_unicode_escape(json_parse_t *json)
+{
+ char utf8[4]; /* Surrogate pairs require 4 UTF-8 bytes */
+ int codepoint;
+ int surrogate_low;
+ int len;
+ int escape_len = 6;
+
+ /* Fetch UTF-16 code unit */
+ codepoint = decode_hex4(json->ptr + 2);
+ if (codepoint < 0)
+ return -1;
+
+ /* UTF-16 surrogate pairs take the following 2 byte form:
+ * 11011 x yyyyyyyyyy
+ * When x = 0: y is the high 10 bits of the codepoint
+ * x = 1: y is the low 10 bits of the codepoint
+ *
+ * Check for a surrogate pair (high or low) */
+ if ((codepoint & 0xF800) == 0xD800) {
+ /* Error if the 1st surrogate is not high */
+ if (codepoint & 0x400)
+ return -1;
+
+ /* Ensure the next code is a unicode escape */
+ if (*(json->ptr + escape_len) != '\\' ||
+ *(json->ptr + escape_len + 1) != 'u') {
+ return -1;
+ }
+
+ /* Fetch the next codepoint */
+ surrogate_low = decode_hex4(json->ptr + 2 + escape_len);
+ if (surrogate_low < 0)
+ return -1;
+
+ /* Error if the 2nd code is not a low surrogate */
+ if ((surrogate_low & 0xFC00) != 0xDC00)
+ return -1;
+
+ /* Calculate Unicode codepoint */
+ codepoint = (codepoint & 0x3FF) << 10;
+ surrogate_low &= 0x3FF;
+ codepoint = (codepoint | surrogate_low) + 0x10000;
+ escape_len = 12;
+ }
+
+ /* Convert codepoint to UTF-8 */
+ len = codepoint_to_utf8(utf8, codepoint);
+ if (!len)
+ return -1;
+
+ /* Append bytes and advance parse index */
+ strbuf_append_mem_unsafe(json->tmp, utf8, len);
+ json->ptr += escape_len;
+
+ return 0;
+}
+
+static void json_set_token_error(json_token_t *token, json_parse_t *json,
+ const char *errtype)
+{
+ token->type = T_ERROR;
+ token->index = json->ptr - json->data;
+ token->value.string = errtype;
+}
+
+static void json_next_string_token(json_parse_t *json, json_token_t *token)
+{
+ char *escape2char = json->cfg->escape2char;
+ char ch;
+
+ /* Caller must ensure a string is next */
+ assert(*json->ptr == '"');
+
+ /* Skip " */
+ json->ptr++;
+
+ /* json->tmp is the temporary strbuf used to accumulate the
+ * decoded string value.
+ * json->tmp is sized to handle JSON containing only a string value.
+ */
+ strbuf_reset(json->tmp);
+
+ while ((ch = *json->ptr) != '"') {
+ if (!ch) {
+ /* Premature end of the string */
+ json_set_token_error(token, json, "unexpected end of string");
+ return;
+ }
+
+ /* Handle escapes */
+ if (ch == '\\') {
+ /* Fetch escape character */
+ ch = *(json->ptr + 1);
+
+ /* Translate escape code and append to tmp string */
+ ch = escape2char[(unsigned char)ch];
+ if (ch == 'u') {
+ if (json_append_unicode_escape(json) == 0)
+ continue;
+
+ json_set_token_error(token, json,
+ "invalid unicode escape code");
+ return;
+ }
+ if (!ch) {
+ json_set_token_error(token, json, "invalid escape code");
+ return;
+ }
+
+ /* Skip '\' */
+ json->ptr++;
+ }
+ /* Append normal character or translated single character
+ * Unicode escapes are handled above */
+ strbuf_append_char_unsafe(json->tmp, ch);
+ json->ptr++;
+ }
+ json->ptr++; /* Eat final quote (") */
+
+ strbuf_ensure_null(json->tmp);
+
+ token->type = T_STRING;
+ token->value.string = strbuf_string(json->tmp, &token->string_len);
+}
+
+/* JSON numbers should take the following form:
+ * -?(0|[1-9]|[1-9][0-9]+)(.[0-9]+)?([eE][-+]?[0-9]+)?
+ *
+ * json_next_number_token() uses strtod() which allows other forms:
+ * - numbers starting with '+'
+ * - NaN, -NaN, infinity, -infinity
+ * - hexadecimal numbers
+ * - numbers with leading zeros
+ *
+ * json_is_invalid_number() detects "numbers" which may pass strtod()'s
+ * error checking, but should not be allowed with strict JSON.
+ *
+ * json_is_invalid_number() may pass numbers which cause strtod()
+ * to generate an error.
+ */
+static int json_is_invalid_number(json_parse_t *json)
+{
+ const char *p = json->ptr;
+
+ /* Reject numbers starting with + */
+ if (*p == '+')
+ return 1;
+
+ /* Skip minus sign if it exists */
+ if (*p == '-')
+ p++;
+
+ /* Reject numbers starting with 0x, or leading zeros */
+ if (*p == '0') {
+ int ch2 = *(p + 1);
+
+ if ((ch2 | 0x20) == 'x' || /* Hex */
+ ('0' <= ch2 && ch2 <= '9')) /* Leading zero */
+ return 1;
+
+ return 0;
+ } else if (*p <= '9') {
+ return 0; /* Ordinary number */
+ }
+
+ /* Reject inf/nan */
+ if (!strncasecmp(p, "inf", 3))
+ return 1;
+ if (!strncasecmp(p, "nan", 3))
+ return 1;
+
+ /* Pass all other numbers which may still be invalid, but
+ * strtod() will catch them. */
+ return 0;
+}
+
+static void json_next_number_token(json_parse_t *json, json_token_t *token)
+{
+ char *endptr;
+
+ token->type = T_NUMBER;
+ token->value.number = fpconv_strtod(json->ptr, &endptr);
+ if (json->ptr == endptr)
+ json_set_token_error(token, json, "invalid number");
+ else
+ json->ptr = endptr; /* Skip the processed number */
+
+ return;
+}
+
+/* Fills in the token struct.
+ * T_STRING will return a pointer to the json_parse_t temporary string
+ * T_ERROR will leave the json->ptr pointer at the error.
+ */
+static void json_next_token(json_parse_t *json, json_token_t *token)
+{
+ const json_token_type_t *ch2token = json->cfg->ch2token;
+ int ch;
+
+ /* Eat whitespace. */
+ while (1) {
+ ch = (unsigned char)*(json->ptr);
+ token->type = ch2token[ch];
+ if (token->type != T_WHITESPACE)
+ break;
+ json->ptr++;
+ }
+
+ /* Store location of new token. Required when throwing errors
+ * for unexpected tokens (syntax errors). */
+ token->index = json->ptr - json->data;
+
+ /* Don't advance the pointer for an error or the end */
+ if (token->type == T_ERROR) {
+ json_set_token_error(token, json, "invalid token");
+ return;
+ }
+
+ if (token->type == T_END) {
+ return;
+ }
+
+ /* Found a known single character token, advance index and return */
+ if (token->type != T_UNKNOWN) {
+ json->ptr++;
+ return;
+ }
+
+ /* Process characters which triggered T_UNKNOWN
+ *
+ * Must use strncmp() to match the front of the JSON string.
+ * JSON identifier must be lowercase.
+ * When strict_numbers if disabled, either case is allowed for
+ * Infinity/NaN (since we are no longer following the spec..) */
+ if (ch == '"') {
+ json_next_string_token(json, token);
+ return;
+ } else if (ch == '-' || ('0' <= ch && ch <= '9')) {
+ if (!json->cfg->decode_invalid_numbers && json_is_invalid_number(json)) {
+ json_set_token_error(token, json, "invalid number");
+ return;
+ }
+ json_next_number_token(json, token);
+ return;
+ } else if (!strncmp(json->ptr, "true", 4)) {
+ token->type = T_BOOLEAN;
+ token->value.boolean = 1;
+ json->ptr += 4;
+ return;
+ } else if (!strncmp(json->ptr, "false", 5)) {
+ token->type = T_BOOLEAN;
+ token->value.boolean = 0;
+ json->ptr += 5;
+ return;
+ } else if (!strncmp(json->ptr, "null", 4)) {
+ token->type = T_NULL;
+ json->ptr += 4;
+ return;
+ } else if (json->cfg->decode_invalid_numbers &&
+ json_is_invalid_number(json)) {
+ /* When decode_invalid_numbers is enabled, only attempt to process
+ * numbers we know are invalid JSON (Inf, NaN, hex)
+ * This is required to generate an appropriate token error,
+ * otherwise all bad tokens will register as "invalid number"
+ */
+ json_next_number_token(json, token);
+ return;
+ }
+
+ /* Token starts with t/f/n but isn't recognised above. */
+ json_set_token_error(token, json, "invalid token");
+}
+
+/* This function does not return.
+ * DO NOT CALL WITH DYNAMIC MEMORY ALLOCATED.
+ * The only supported exception is the temporary parser string
+ * json->tmp struct.
+ * json and token should exist on the stack somewhere.
+ * luaL_error() will long_jmp and release the stack */
+static void json_throw_parse_error(lua_State *l, json_parse_t *json,
+ const char *exp, json_token_t *token)
+{
+ const char *found;
+
+ strbuf_free(json->tmp);
+
+ if (token->type == T_ERROR)
+ found = token->value.string;
+ else
+ found = json_token_type_name[token->type];
+
+ /* Note: token->index is 0 based, display starting from 1 */
+ luaL_error(l, "Expected %s but found %s at character %d",
+ exp, found, token->index + 1);
+}
+
+static inline void json_decode_ascend(json_parse_t *json)
+{
+ json->current_depth--;
+}
+
+static void json_decode_descend(lua_State *l, json_parse_t *json, int slots)
+{
+ json->current_depth++;
+
+ if (json->current_depth <= json->cfg->decode_max_depth &&
+ lua_checkstack(l, slots)) {
+ return;
+ }
+
+ strbuf_free(json->tmp);
+ luaL_error(l, "Found too many nested data structures (%d) at character %d",
+ json->current_depth, json->ptr - json->data);
+}
+
+static void json_parse_object_context(lua_State *l, json_parse_t *json)
+{
+ json_token_t token;
+
+ /* 3 slots required:
+ * .., table, key, value */
+ json_decode_descend(l, json, 3);
+
+ lua_newtable(l);
+
+ json_next_token(json, &token);
+
+ /* Handle empty objects */
+ if (token.type == T_OBJ_END) {
+ json_decode_ascend(json);
+ return;
+ }
+
+ while (1) {
+ if (token.type != T_STRING)
+ json_throw_parse_error(l, json, "object key string", &token);
+
+ /* Push key */
+ lua_pushlstring(l, token.value.string, token.string_len);
+
+ json_next_token(json, &token);
+ if (token.type != T_COLON)
+ json_throw_parse_error(l, json, "colon", &token);
+
+ /* Fetch value */
+ json_next_token(json, &token);
+ json_process_value(l, json, &token);
+
+ /* Set key = value */
+ lua_rawset(l, -3);
+
+ json_next_token(json, &token);
+
+ if (token.type == T_OBJ_END) {
+ json_decode_ascend(json);
+ return;
+ }
+
+ if (token.type != T_COMMA)
+ json_throw_parse_error(l, json, "comma or object end", &token);
+
+ json_next_token(json, &token);
+ }
+}
+
+/* Handle the array context */
+static void json_parse_array_context(lua_State *l, json_parse_t *json)
+{
+ json_token_t token;
+ int i;
+
+ /* 2 slots required:
+ * .., table, value */
+ json_decode_descend(l, json, 2);
+
+ lua_newtable(l);
+
+ /* set array_mt on the table at the top of the stack */
+ if (json->cfg->decode_array_with_array_mt) {
+ lua_pushlightuserdata(l, json_lightudata_mask(&json_array));
+ lua_rawget(l, LUA_REGISTRYINDEX);
+ lua_setmetatable(l, -2);
+ }
+
+ json_next_token(json, &token);
+
+ /* Handle empty arrays */
+ if (token.type == T_ARR_END) {
+ json_decode_ascend(json);
+ return;
+ }
+
+ for (i = 1; ; i++) {
+ json_process_value(l, json, &token);
+ lua_rawseti(l, -2, i); /* arr[i] = value */
+
+ json_next_token(json, &token);
+
+ if (token.type == T_ARR_END) {
+ json_decode_ascend(json);
+ return;
+ }
+
+ if (token.type != T_COMMA)
+ json_throw_parse_error(l, json, "comma or array end", &token);
+
+ json_next_token(json, &token);
+ }
+}
+
+/* Handle the "value" context */
+static void json_process_value(lua_State *l, json_parse_t *json,
+ json_token_t *token)
+{
+ switch (token->type) {
+ case T_STRING:
+ lua_pushlstring(l, token->value.string, token->string_len);
+ break;;
+ case T_NUMBER:
+ lua_pushnumber(l, token->value.number);
+ break;;
+ case T_BOOLEAN:
+ lua_pushboolean(l, token->value.boolean);
+ break;;
+ case T_OBJ_BEGIN:
+ json_parse_object_context(l, json);
+ break;;
+ case T_ARR_BEGIN:
+ json_parse_array_context(l, json);
+ break;;
+ case T_NULL:
+ /* In Lua, setting "t[k] = nil" will delete k from the table.
+ * Hence a NULL pointer lightuserdata object is used instead */
+ lua_pushlightuserdata(l, NULL);
+ break;;
+ default:
+ json_throw_parse_error(l, json, "value", token);
+ }
+}
+
+static int json_decode(lua_State *l)
+{
+ json_parse_t json;
+ json_token_t token;
+ size_t json_len;
+
+ luaL_argcheck(l, lua_gettop(l) == 1, 1, "expected 1 argument");
+
+ json.cfg = json_fetch_config(l);
+ json.data = luaL_checklstring(l, 1, &json_len);
+ json.current_depth = 0;
+ json.ptr = json.data;
+
+ /* Detect Unicode other than UTF-8 (see RFC 4627, Sec 3)
+ *
+ * CJSON can support any simple data type, hence only the first
+ * character is guaranteed to be ASCII (at worst: '"'). This is
+ * still enough to detect whether the wrong encoding is in use. */
+ if (json_len >= 2 && (!json.data[0] || !json.data[1]))
+ luaL_error(l, "JSON parser does not support UTF-16 or UTF-32");
+
+ /* Ensure the temporary buffer can hold the entire string.
+ * This means we no longer need to do length checks since the decoded
+ * string must be smaller than the entire json string */
+ json.tmp = strbuf_new(json_len);
+
+ json_next_token(&json, &token);
+ json_process_value(l, &json, &token);
+
+ /* Ensure there is no more input left */
+ json_next_token(&json, &token);
+
+ if (token.type != T_END)
+ json_throw_parse_error(l, &json, "the end", &token);
+
+ strbuf_free(json.tmp);
+
+ return 1;
+}
+
+/* ===== INITIALISATION ===== */
+
+#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 502
+/* Compatibility for Lua 5.1 and older LuaJIT.
+ *
+ * compat_luaL_setfuncs() is used to create a module table where the functions
+ * have json_config_t as their first upvalue. Code borrowed from Lua 5.2
+ * source's luaL_setfuncs().
+ */
+static void compat_luaL_setfuncs(lua_State *l, const luaL_Reg *reg, int nup)
+{
+ int i;
+
+ luaL_checkstack(l, nup, "too many upvalues");
+ for (; reg->name != NULL; reg++) { /* fill the table with given functions */
+ for (i = 0; i < nup; i++) /* copy upvalues to the top */
+ lua_pushvalue(l, -nup);
+ lua_pushcclosure(l, reg->func, nup); /* closure with those upvalues */
+ lua_setfield(l, -(nup + 2), reg->name);
+ }
+ lua_pop(l, nup); /* remove upvalues */
+}
+#else
+#define compat_luaL_setfuncs(L, reg, nup) luaL_setfuncs(L, reg, nup)
+#endif
+
+/* Call target function in protected mode with all supplied args.
+ * Assumes target function only returns a single non-nil value.
+ * Convert and return thrown errors as: nil, "error message" */
+static int json_protect_conversion(lua_State *l)
+{
+ int err;
+
+ /* Deliberately throw an error for invalid arguments */
+ luaL_argcheck(l, lua_gettop(l) == 1, 1, "expected 1 argument");
+
+ /* pcall() the function stored as upvalue(1) */
+ lua_pushvalue(l, lua_upvalueindex(1));
+ lua_insert(l, 1);
+ err = lua_pcall(l, 1, 1, 0);
+ if (!err)
+ return 1;
+
+ if (err == LUA_ERRRUN) {
+ lua_pushnil(l);
+ lua_insert(l, -2);
+ return 2;
+ }
+
+ /* Since we are not using a custom error handler, the only remaining
+ * errors are memory related */
+ return luaL_error(l, "Memory allocation error in CJSON protected call");
+}
+
+/* Return cjson module table */
+static int lua_cjson_new(lua_State *l)
+{
+ luaL_Reg reg[] = {
+ { "encode", json_encode },
+ { "decode", json_decode },
+ { "encode_empty_table_as_object", json_cfg_encode_empty_table_as_object },
+ { "decode_array_with_array_mt", json_cfg_decode_array_with_array_mt },
+ { "encode_sparse_array", json_cfg_encode_sparse_array },
+ { "encode_max_depth", json_cfg_encode_max_depth },
+ { "decode_max_depth", json_cfg_decode_max_depth },
+ { "encode_number_precision", json_cfg_encode_number_precision },
+ { "encode_keep_buffer", json_cfg_encode_keep_buffer },
+ { "encode_invalid_numbers", json_cfg_encode_invalid_numbers },
+ { "decode_invalid_numbers", json_cfg_decode_invalid_numbers },
+ { "encode_escape_forward_slash", json_cfg_encode_escape_forward_slash },
+ { "encode_skip_unsupported_value_types", json_cfg_encode_skip_unsupported_value_types },
+ { "new", lua_cjson_new },
+ { NULL, NULL }
+ };
+
+ /* Initialise number conversions */
+ fpconv_init();
+
+ /* Test if array metatables are in registry */
+ lua_pushlightuserdata(l, json_lightudata_mask(&json_empty_array));
+ lua_rawget(l, LUA_REGISTRYINDEX);
+ if (lua_isnil(l, -1)) {
+ /* Create array metatables.
+ *
+ * If multiple calls to lua_cjson_new() are made,
+ * this prevents overriding the tables at the given
+ * registry's index with a new one.
+ */
+ lua_pop(l, 1);
+
+ /* empty_array_mt */
+ lua_pushlightuserdata(l, json_lightudata_mask(&json_empty_array));
+ lua_newtable(l);
+ lua_rawset(l, LUA_REGISTRYINDEX);
+
+ /* array_mt */
+ lua_pushlightuserdata(l, json_lightudata_mask(&json_array));
+ lua_newtable(l);
+ lua_rawset(l, LUA_REGISTRYINDEX);
+ }
+
+ /* cjson module table */
+ lua_newtable(l);
+
+ /* Register functions with config data as upvalue */
+ json_create_config(l);
+ compat_luaL_setfuncs(l, reg, 1);
+
+ /* Set cjson.null */
+ lua_pushlightuserdata(l, NULL);
+ lua_setfield(l, -2, "null");
+
+ /* Set cjson.empty_array_mt */
+ lua_pushlightuserdata(l, json_lightudata_mask(&json_empty_array));
+ lua_rawget(l, LUA_REGISTRYINDEX);
+ lua_setfield(l, -2, "empty_array_mt");
+
+ /* Set cjson.array_mt */
+ lua_pushlightuserdata(l, json_lightudata_mask(&json_array));
+ lua_rawget(l, LUA_REGISTRYINDEX);
+ lua_setfield(l, -2, "array_mt");
+
+ /* Set cjson.empty_array */
+ lua_pushlightuserdata(l, json_lightudata_mask(&json_array));
+ lua_setfield(l, -2, "empty_array");
+
+ /* Set module name / version fields */
+ lua_pushliteral(l, CJSON_MODNAME);
+ lua_setfield(l, -2, "_NAME");
+ lua_pushliteral(l, CJSON_VERSION);
+ lua_setfield(l, -2, "_VERSION");
+
+ return 1;
+}
+
+/* Return cjson.safe module table */
+static int lua_cjson_safe_new(lua_State *l)
+{
+ const char *func[] = { "decode", "encode", NULL };
+ int i;
+
+ lua_cjson_new(l);
+
+ /* Fix new() method */
+ lua_pushcfunction(l, lua_cjson_safe_new);
+ lua_setfield(l, -2, "new");
+
+ for (i = 0; func[i]; i++) {
+ lua_getfield(l, -1, func[i]);
+ lua_pushcclosure(l, json_protect_conversion, 1);
+ lua_setfield(l, -2, func[i]);
+ }
+
+ return 1;
+}
+
+int luaopen_cjson(lua_State *l)
+{
+ lua_cjson_new(l);
+
+#ifdef ENABLE_CJSON_GLOBAL
+ /* Register a global "cjson" table. */
+ lua_pushvalue(l, -1);
+ lua_setglobal(l, CJSON_MODNAME);
+#endif
+
+ /* Return cjson table */
+ return 1;
+}
+
+int luaopen_cjson_safe(lua_State *l)
+{
+ lua_cjson_safe_new(l);
+
+ /* Return cjson.safe table */
+ return 1;
+}
+
+/* vi:ai et sw=4 ts=4:
+ */
diff --git a/csgo2/luaCjson/strbuf.c b/csgo2/luaCjson/strbuf.c
new file mode 100644
index 0000000..2dc30be
--- /dev/null
+++ b/csgo2/luaCjson/strbuf.c
@@ -0,0 +1,199 @@
+/* strbuf - String buffer routines
+ *
+ * Copyright (c) 2010-2012 Mark Pulford
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include
+#include
+#include
+#include
+#include
+
+#include "strbuf.h"
+
+static void die(const char *fmt, ...)
+{
+ va_list arg;
+
+ va_start(arg, fmt);
+ vfprintf(stderr, fmt, arg);
+ va_end(arg);
+ fprintf(stderr, "\n");
+
+ abort();
+}
+
+void strbuf_init(strbuf_t *s, size_t len)
+{
+ size_t size;
+
+ if (!len)
+ size = STRBUF_DEFAULT_SIZE;
+ else
+ size = len + 1;
+ if (size < len)
+ die("Overflow, len: %zu", len);
+ s->buf = NULL;
+ s->size = size;
+ s->length = 0;
+ s->dynamic = 0;
+ s->reallocs = 0;
+ s->debug = 0;
+
+ s->buf = malloc(size);
+ if (!s->buf)
+ die("Out of memory");
+
+ strbuf_ensure_null(s);
+}
+
+strbuf_t *strbuf_new(size_t len)
+{
+ strbuf_t *s;
+
+ s = malloc(sizeof(strbuf_t));
+ if (!s)
+ die("Out of memory");
+
+ strbuf_init(s, len);
+
+ /* Dynamic strbuf allocation / deallocation */
+ s->dynamic = 1;
+
+ return s;
+}
+
+static inline void debug_stats(strbuf_t *s)
+{
+ if (s->debug) {
+ fprintf(stderr, "strbuf(%lx) reallocs: %d, length: %zd, size: %zd\n",
+ (long)s, s->reallocs, s->length, s->size);
+ }
+}
+
+/* If strbuf_t has not been dynamically allocated, strbuf_free() can
+ * be called any number of times strbuf_init() */
+void strbuf_free(strbuf_t *s)
+{
+ debug_stats(s);
+
+ if (s->buf) {
+ free(s->buf);
+ s->buf = NULL;
+ }
+ if (s->dynamic)
+ free(s);
+}
+
+char *strbuf_free_to_string(strbuf_t *s, size_t *len)
+{
+ char *buf;
+
+ debug_stats(s);
+
+ strbuf_ensure_null(s);
+
+ buf = s->buf;
+ if (len)
+ *len = s->length;
+
+ if (s->dynamic)
+ free(s);
+
+ return buf;
+}
+
+static size_t calculate_new_size(strbuf_t *s, size_t len)
+{
+ size_t reqsize, newsize;
+
+ if (len <= 0)
+ die("BUG: Invalid strbuf length requested");
+
+ /* Ensure there is room for optional NULL termination */
+ reqsize = len + 1;
+ if (reqsize < len)
+ die("Overflow, len: %zu", len);
+
+ /* If the user has requested to shrink the buffer, do it exactly */
+ if (s->size > reqsize)
+ return reqsize;
+
+ newsize = s->size;
+ if (reqsize >= SIZE_MAX / 2) {
+ newsize = reqsize;
+ } else {
+ /* Exponential sizing */
+ while (newsize < reqsize)
+ newsize *= 2;
+ }
+
+ if (newsize < reqsize)
+ die("BUG: strbuf length would overflow, len: %zu", len);
+
+
+ return newsize;
+}
+
+
+/* Ensure strbuf can handle a string length bytes long (ignoring NULL
+ * optional termination). */
+void strbuf_resize(strbuf_t *s, size_t len)
+{
+ size_t newsize;
+
+ newsize = calculate_new_size(s, len);
+
+ if (s->debug > 1) {
+ fprintf(stderr, "strbuf(%lx) resize: %zd => %zd\n",
+ (long)s, s->size, newsize);
+ }
+
+ s->size = newsize;
+ s->buf = realloc(s->buf, s->size);
+ if (!s->buf)
+ die("Out of memory, len: %zu", len);
+ s->reallocs++;
+}
+
+void strbuf_append_string(strbuf_t *s, const char *str)
+{
+ int i;
+ size_t space;
+
+ space = strbuf_empty_length(s);
+
+ for (i = 0; str[i]; i++) {
+ if (space < 1) {
+ strbuf_resize(s, s->length + 1);
+ space = strbuf_empty_length(s);
+ }
+
+ s->buf[s->length] = str[i];
+ s->length++;
+ space--;
+ }
+}
+
+
+/* vi:ai et sw=4 ts=4:
+ */
diff --git a/csgo2/luaCjson/strbuf.h b/csgo2/luaCjson/strbuf.h
new file mode 100644
index 0000000..d77e0f4
--- /dev/null
+++ b/csgo2/luaCjson/strbuf.h
@@ -0,0 +1,157 @@
+/* strbuf - String buffer routines
+ *
+ * Copyright (c) 2010-2012 Mark Pulford
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include
+#include
+
+/* Workaround for MSVC */
+#ifdef _MSC_VER
+#define inline __inline
+#endif
+
+/* Size: Total bytes allocated to *buf
+ * Length: String length, excluding optional NULL terminator.
+ * Dynamic: True if created via strbuf_new()
+ */
+
+typedef struct {
+ char *buf;
+ size_t size;
+ size_t length;
+ int dynamic;
+ int reallocs;
+ int debug;
+} strbuf_t;
+
+#ifndef STRBUF_DEFAULT_SIZE
+#define STRBUF_DEFAULT_SIZE 1023
+#endif
+
+/* Initialise */
+extern strbuf_t *strbuf_new(size_t len);
+extern void strbuf_init(strbuf_t *s, size_t len);
+
+/* Release */
+extern void strbuf_free(strbuf_t *s);
+extern char *strbuf_free_to_string(strbuf_t *s, size_t *len);
+
+/* Management */
+extern void strbuf_resize(strbuf_t *s, size_t len);
+static size_t strbuf_empty_length(strbuf_t *s);
+static size_t strbuf_length(strbuf_t *s);
+static char *strbuf_string(strbuf_t *s, size_t *len);
+static void strbuf_ensure_empty_length(strbuf_t *s, size_t len);
+static char *strbuf_empty_ptr(strbuf_t *s);
+static void strbuf_extend_length(strbuf_t *s, size_t len);
+static void strbuf_set_length(strbuf_t *s, int len);
+
+/* Update */
+static void strbuf_append_mem(strbuf_t *s, const char *c, size_t len);
+extern void strbuf_append_string(strbuf_t *s, const char *str);
+static void strbuf_append_char(strbuf_t *s, const char c);
+static void strbuf_ensure_null(strbuf_t *s);
+
+/* Reset string for before use */
+static inline void strbuf_reset(strbuf_t *s)
+{
+ s->length = 0;
+}
+
+static inline int strbuf_allocated(strbuf_t *s)
+{
+ return s->buf != NULL;
+}
+
+/* Return bytes remaining in the string buffer
+ * Ensure there is space for a NULL terminator. */
+static inline size_t strbuf_empty_length(strbuf_t *s)
+{
+ return s->size - s->length - 1;
+}
+
+static inline void strbuf_ensure_empty_length(strbuf_t *s, size_t len)
+{
+ if (len > strbuf_empty_length(s))
+ strbuf_resize(s, s->length + len);
+}
+
+static inline char *strbuf_empty_ptr(strbuf_t *s)
+{
+ return s->buf + s->length;
+}
+
+static inline void strbuf_set_length(strbuf_t *s, int len)
+{
+ s->length = len;
+}
+
+static inline void strbuf_extend_length(strbuf_t *s, size_t len)
+{
+ s->length += len;
+}
+
+static inline size_t strbuf_length(strbuf_t *s)
+{
+ return s->length;
+}
+
+static inline void strbuf_append_char(strbuf_t *s, const char c)
+{
+ strbuf_ensure_empty_length(s, 1);
+ s->buf[s->length++] = c;
+}
+
+static inline void strbuf_append_char_unsafe(strbuf_t *s, const char c)
+{
+ s->buf[s->length++] = c;
+}
+
+static inline void strbuf_append_mem(strbuf_t *s, const char *c, size_t len)
+{
+ strbuf_ensure_empty_length(s, len);
+ memcpy(s->buf + s->length, c, len);
+ s->length += len;
+}
+
+static inline void strbuf_append_mem_unsafe(strbuf_t *s, const char *c, size_t len)
+{
+ memcpy(s->buf + s->length, c, len);
+ s->length += len;
+}
+
+static inline void strbuf_ensure_null(strbuf_t *s)
+{
+ s->buf[s->length] = 0;
+}
+
+static inline char *strbuf_string(strbuf_t *s, size_t *len)
+{
+ if (len)
+ *len = s->length;
+
+ return s->buf;
+}
+
+/* vi:ai et sw=4 ts=4:
+ */
diff --git a/csgo2/memory.cpp b/csgo2/memory.cpp
index e69de29..dc2c67e 100644
--- a/csgo2/memory.cpp
+++ b/csgo2/memory.cpp
@@ -0,0 +1,23 @@
+#include "memory.h"
+namespace Memory {
+ auto PathVscript() -> void {
+ CModule vscript_old("vscript_old.dll");
+ CModule vscript("vscript.dll");
+
+ uint64_t vscriptPathAddr = 0;
+ if (vscript_old.IsLoaded() == true) {
+ vscript_old.FindPattern(Offset::pattern_VscriptPath).Get(vscriptPathAddr);
+ }
+ else {
+ vscript.FindPattern(Offset::pattern_VscriptPath).Get(vscriptPathAddr);
+ }
+ if (vscriptPathAddr != 0) {
+ const static char PatchVScriptEnable[] = { 0xBE, 0x02 };
+ DWORD oldProtect;
+ VirtualProtect(reinterpret_cast(vscriptPathAddr), sizeof(PatchVScriptEnable), PAGE_EXECUTE_READWRITE, &oldProtect);
+ memcpy(reinterpret_cast(vscriptPathAddr), PatchVScriptEnable, sizeof(PatchVScriptEnable));
+ VirtualProtect(reinterpret_cast(vscriptPathAddr), sizeof(PatchVScriptEnable), oldProtect, &oldProtect);
+ LOG("success patch vscript at %llx \n", vscriptPathAddr);
+ }
+ }
+};
\ No newline at end of file
diff --git a/csgo2/memory.h b/csgo2/memory.h
index 27968b8..a0926f5 100644
--- a/csgo2/memory.h
+++ b/csgo2/memory.h
@@ -14,5 +14,5 @@ namespace Memory {
ReadProcessMemory(GetCurrentProcess(), (void*)address, &buffer, sizeof(T), 0);
return buffer;
}
-
+ auto PathVscript() -> void;
};
\ No newline at end of file
diff --git a/csgo2/module.h b/csgo2/module.h
index b8c0dbf..874ed91 100644
--- a/csgo2/module.h
+++ b/csgo2/module.h
@@ -2,6 +2,10 @@
#include "head.h"
#define IS_WINDOWS 1
class InterfaceReg;
+//cancer fix me plz
+namespace global {
+ extern bool isMetaModInit;
+};
// Pointer arithmetic utility class.
struct UTILPtr {
public:
@@ -65,10 +69,8 @@ class CModule {
UTILPtr GetProcAddress(const char* procName) const {
UTILPtr rv = 0;
if (this->IsLoaded()) {
-#ifdef IS_WINDOWS
rv = ::GetProcAddress(static_cast(this->m_handle),
procName);
-#endif
}
return rv;
}
@@ -77,11 +79,7 @@ class CModule {
if (this->IsLoaded()) {
UTILPtr pCreateInterface = this->GetProcAddress("CreateInterface");
if (!pCreateInterface.IsValid()) return rv;
-
- InterfaceReg* s_pInterfaceRegs = pCreateInterface.ToAbsolute(3, 0)
- .Dereference(1)
- .Get();
-
+ auto s_pInterfaceRegs = pCreateInterface.ToAbsolute(3, 0).Dereference(1).Get();
for (; s_pInterfaceRegs;
s_pInterfaceRegs = s_pInterfaceRegs->m_pNext) {
if (strcmp(version, s_pInterfaceRegs->m_pName) == 0) {
@@ -121,9 +119,36 @@ class CModule {
private:
void InitializeHandle() {
-#ifdef IS_WINDOWS
- this->m_handle = static_cast(GetModuleHandleA(this->GetName()));
-#endif
+ if (global::isMetaModInit == false) {
+ this->m_handle = static_cast(GetModuleHandleA(this->GetName()));
+ return;
+ }
+
+ HANDLE hProcess = GetCurrentProcess();
+ DWORD cbNeeded;
+
+ // Call EnumProcessModules with a null hMods parameter to get the needed size.
+ EnumProcessModules(hProcess, nullptr, 0, &cbNeeded);
+ int moduleCount = cbNeeded / sizeof(HMODULE);
+ std::vector hMods(moduleCount);
+
+ if (EnumProcessModules(hProcess, hMods.data(), cbNeeded, &cbNeeded))
+ {
+ for (const auto& hMod : hMods)
+ {
+ char szModName[MAX_PATH];
+
+ if (GetModuleFileNameExA(hProcess, hMod, szModName, sizeof(szModName) / sizeof(char)))
+ {
+ const auto fullModulePath = std::string(szModName);
+ if (fullModulePath.find("metamod") == std::string::npos && fullModulePath.ends_with(this->GetName()) == true) {
+ this->m_handle = static_cast(hMod);
+ break;
+ }
+ }
+ }
+ }
+ CloseHandle(hProcess);
}
void InitializeBounds() {
if (!this->IsLoaded()) return;
diff --git a/csgo2/native_sdk.cpp b/csgo2/native_sdk.cpp
index 68ac29b..c605ef7 100644
--- a/csgo2/native_sdk.cpp
+++ b/csgo2/native_sdk.cpp
@@ -100,8 +100,7 @@ static bool InitSchemaFieldsForClass(SchemaTableMap_t* tableMap,
for (int i = 0; i < fieldsSize; ++i) {
SchemaClassFieldData_t& field = pFields[i];
- // LOG("%s::%s found at -> 0x%X - %llx\n", className, field.m_name,
- // field.m_offset, &field);
+ LOG("%s::%s found at -> 0x%X - %llx\n", className, field.m_name, field.m_offset, &field);
keyValueMap->Insert(hash_32_fnv1a_const(field.m_name),
{field.m_offset, IsFieldNetworked(field)});
diff --git a/csgo2/native_sdk.h b/csgo2/native_sdk.h
index 248b0c3..3a81c94 100644
--- a/csgo2/native_sdk.h
+++ b/csgo2/native_sdk.h
@@ -85,7 +85,7 @@ extern auto SetStateChanged(Z_CBaseEntity* pEntity, int offset) -> void;
static constexpr auto prop_hash = hash_32_fnv1a_const(#varName); \
\
static const auto m_key = \
- schema::GetOffset(ThisClass, datatable_hash, #varName, prop_hash); \
+ schema::GetOffset(datatableName, datatable_hash, #varName, prop_hash); \
\
return *reinterpret_cast>( \
(uintptr_t)(this) + m_key.offset + extra_offset); \
@@ -96,7 +96,7 @@ extern auto SetStateChanged(Z_CBaseEntity* pEntity, int offset) -> void;
static constexpr auto prop_hash = hash_32_fnv1a_const(#varName); \
\
static const auto m_key = \
- schema::GetOffset(ThisClass, datatable_hash, #varName, prop_hash); \
+ schema::GetOffset(datatableName, datatable_hash, #varName, prop_hash); \
\
static const auto m_chain = schema::FindChainOffset(ThisClass); \
\
@@ -111,7 +111,7 @@ extern auto SetStateChanged(Z_CBaseEntity* pEntity, int offset) -> void;
middle of a class will need to have their this pointer \
corrected by the offset .*/ \
LOG("Attempting to call SetStateChanged on on %s::%s\n", \
- ThisClass, #varName); \
+ datatableName, #varName); \
if (!OffsetIsStruct) \
SetStateChanged((Z_CBaseEntity*)this, \
m_key.offset + extra_offset); \
@@ -380,13 +380,7 @@ class CGlowProperty {
SCHEMA_FIELD(bool, m_bFlashing)
SCHEMA_FIELD(bool, m_bGlowing)
};
-class CBaseModelEntity {
- public:
- DECLARE_CLASS(CBaseModelEntity);
- SCHEMA_FIELD(CCollisionProperty, m_Collision)
- SCHEMA_FIELD(CGlowProperty, m_Glow)
-};
class CBaseEntity : public CEntityInstance {
public:
DECLARE_CLASS(CBaseEntity);
@@ -396,11 +390,17 @@ class CBaseEntity : public CEntityInstance {
// SCHEMA_FIELD(Vector, m_vecBaseVelocity)
SCHEMA_FIELD(CCollisionProperty*, m_pCollision)
SCHEMA_FIELD(Vector, m_vecBaseVelocity)
- SCHEMA_FIELD_EX(CGlowProperty, "CBaseModelEntity", m_Glow);
+ //SCHEMA_FIELD_EX(CGlowProperty, "CBaseModelEntity", m_Glow);
auto IsBasePlayerController() -> bool;
auto SpawnClientEntity() -> void;
};
+class CBaseModelEntity : public CBaseEntity {
+public:
+ DECLARE_CLASS(CBaseModelEntity);
+ SCHEMA_FIELD(CCollisionProperty, m_Collision)
+ SCHEMA_FIELD(CGlowProperty, m_Glow)
+};
class CBasePlayerController : public CBaseEntity {
public:
DECLARE_CLASS(CBasePlayerController);
diff --git a/csgo2/offset.cpp b/csgo2/offset.cpp
index 0b8de55..4a1f880 100644
--- a/csgo2/offset.cpp
+++ b/csgo2/offset.cpp
@@ -11,7 +11,7 @@ uint64_t MaxPlayerNumsPtr;
HashFunction_t FnServerHashFunction;
StateChanged_t FnStateChanged;
NetworkStateChanged_t FnNetworkStateChanged;
-RespawnPlayer_t FnRespawnPlayer;
+RespawnPlayerInDeathMatch_t FnRespawnPlayerInDeathMatch;
GiveNamedItem_t FnGiveNamedItem;
EntityRemove_t FnEntityRemove;
UTIL_SayTextFilter_t FnUTIL_SayTextFilter;
@@ -49,11 +49,14 @@ auto SafeDelayInit(void* ctx) -> void {
LOG("m_bForceTeamChangeSilent: %d \n",
InterFaces::CCSGameRulesInterFace->m_bForceTeamChangeSilent());
}
+
auto Init() -> bool {
CModule server("server.dll");
CModule schemasystem("schemasystem.dll");
CModule engine("engine2.dll");
CModule localize("localize.dll");
+ CModule tier0("tier0.dll");
+ Memory::PathVscript();
// engine.dll
engine.FindPattern(pattern_MaxPlayerNumsPtr)
@@ -71,11 +74,11 @@ auto Init() -> bool {
server.FindPattern(pattern_CreateCCSGameRulesInterFacePtr)
.ToAbsolute(3, 0)
.Get(CCSGameRulesInterFacePtr);
- server.FindPattern(pattern_FnRespawnPlayer).Get(FnRespawnPlayer);
+ server.FindPattern(pattern_FnRespawnPlayerInDeathMatch).Get(FnRespawnPlayerInDeathMatch);
server.FindPattern(pattern_FnEntityRemove).Get(FnEntityRemove);
server.FindPattern(pattern_FnGiveNamedItemPtr).Get(FnGiveNamedItem);
server.FindPattern(pattern_fnHost_SayPtr).Get(Host_SayPtr);
- server.FindPattern(pattern_ServerHashFunctionPtr).Get(FnServerHashFunction);
+ //server.FindPattern(pattern_ServerHashFunctionPtr).Get(FnServerHashFunction);
server.FindPattern(pattern_UTIL_ClientPrintAll).Get(FnUTIL_ClientPrintAll);
server.FindPattern(pattern_FnClientPrint).Get(FnClientPrint);
@@ -89,7 +92,7 @@ auto Init() -> bool {
InterFaces::ILocalize = reinterpret_cast(
localize.FindInterface("Localize_001").Get());
InterFaces::IVEngineCvar = reinterpret_cast(
- engine.FindInterface("VEngineCvar007").Get());
+ tier0.FindInterface("VEngineCvar007").Get());
InterFaces::GameResourceServiceServer =
reinterpret_cast(
@@ -121,9 +124,9 @@ auto Init() -> bool {
LOG("[huoji]FireEventServerSidePtr : %llx \n", FireEventServerSidePtr);
LOG("[huoji]Host_SayPtr : %llx \n", Host_SayPtr);
LOG("[huoji]FnNetworkStateChanged : %llx \n", FnNetworkStateChanged);
- LOG("[huoji]FnServerHashFunction : %llx \n", FnServerHashFunction);
+ //LOG("[huoji]FnServerHashFunction : %llx \n", FnServerHashFunction);
LOG("[huoji]FnStateChanged : %llx \n", FnStateChanged);
- LOG("[huoji]FnRespawnPlayer : %llx \n", FnRespawnPlayer);
+ LOG("[huoji]FnRespawnPlayerInDeathMatch : %llx \n", FnRespawnPlayerInDeathMatch);
LOG("[huoji]FnGiveNamedItem : %llx \n", FnGiveNamedItem);
LOG("[huoji]FnClientPrint : %llx \n", FnClientPrint);
LOG("[huoji]FnUTIL_ClientPrintAll : %llx \n", FnUTIL_ClientPrintAll);
@@ -154,8 +157,7 @@ auto Init() -> bool {
0, NULL);
// LOG("FnServerHashFunction: %llx \n", FnServerHashFunction("here",
// sizeof("here") - 1, 0x31415926));
- return FnCCSWeaponBase_Spawn && FnEntityRemove && FnRespawnPlayer && FnGiveNamedItem &&
- FnServerHashFunction && Host_SayPtr && InterFaces::IVEngineServer &&
+ return FnCCSWeaponBase_Spawn && FnEntityRemove && FnRespawnPlayerInDeathMatch && FnGiveNamedItem && Host_SayPtr && InterFaces::IVEngineServer &&
InterFaces::GameResourceServiceServer &&
InterFaces::IServerGameClient && InterFaces::GameEventManager &&
InterFaces::SchemaSystem && FireEventServerSidePtr &&
diff --git a/csgo2/offset.h b/csgo2/offset.h
index 17487ed..e52d4fc 100644
--- a/csgo2/offset.h
+++ b/csgo2/offset.h
@@ -14,7 +14,7 @@ typedef void(__fastcall* StateChanged_t)(void* networkTransmitComponent,
typedef void(__fastcall* NetworkStateChanged_t)(uintptr_t chainEntity,
uintptr_t offset, uintptr_t a3);
typedef void*(__fastcall* CreateGameRuleInterFace_t)();
-typedef bool(__fastcall* RespawnPlayer_t)(CCSPlayerPawn* player);
+typedef bool(__fastcall* RespawnPlayerInDeathMatch_t)(CCSPlayerPawn* player);
typedef void(__fastcall* GiveNamedItem_t)(void* itemService,
const char* pchName, void* iSubType,
void* pScriptItem, void* a5,
@@ -26,7 +26,6 @@ typedef void*(__fastcall* UTIL_SayTextFilter_t)(IRecipientFilter&, const char*,
typedef void(__fastcall* UTIL_ClientPrintAll_t)(int msg_dest, const char* msg_name, const char* param1, const char* param2, const char* param3, const char* param4);
typedef void(__fastcall* ClientPrint_t)(CCSPlayerController* player, int msg_dest, const char* msg_name, const char* param1, const char* param2, const char* param3, const char* param4);
typedef void(__fastcall* CCSWeaponBase_Spawn_t)(CBaseEntity*, void*);
-
class CSchemaSystem;
class CGameResourceService;
class CLocalize;
@@ -45,6 +44,7 @@ extern ISource2Server* ISource2ServerInterFace;
extern CCSGameRules* CCSGameRulesInterFace;
extern ICvar* IVEngineCvar;
}; // namespace InterFaces
+static const auto pattern_VscriptPath = THE_GAME_SIG("BE 01 ?? ?? ?? 2B D6 74 ?? 3B D6");
static const auto pattern_CGameEventManager = THE_GAME_SIG(
"48 ?? ?? ?? ?? ?? ?? 48 89 ?? ?? ?? 48 89 01 48 8B D9 48 ?? ?? ?? ?? ?? "
"?? 48 89 ?? ?? E8 ?? ?? ?? ?? 48 ?? ?? ?? ?? ?? ??");
@@ -79,6 +79,8 @@ static const auto pattern_CreateCCSGameRulesInterFacePtr = THE_GAME_SIG(
"?? ?? 4C 8D ?? ?? ?? 49 8B ?? ?? 49 8B ?? ?? 49 8B ?? ?? 49 8B E3 41 5F "
"41 5E 5F C3");
static const auto pattern_FnRespawnPlayer = THE_GAME_SIG(
+ "48 89 ?? ?? ?? 48 89 ?? ?? ?? 56 48 ?? ?? ?? ?? ?? ?? 48 8B DA 48 8B E9 48 85 D2 0F ?? ?? ?? ?? ?? 48 8B 02 48 8B CA FF ?? ?? ?? ?? ?? 84 C0 0F ?? ?? ?? ?? ?? 83 BB ?? ?? ?? ?? ?? 0F ?? ?? ?? ?? ??");
+static const auto pattern_FnRespawnPlayerInDeathMatch = THE_GAME_SIG(
"48 89 ?? ?? ?? 57 48 ?? ?? ?? 48 8D ?? ?? ?? 48 8B F9 E8 ?? ?? ?? ?? 83 "
"?? ?? 74 ?? 48 ?? ?? ?? ?? ?? ?? 48 8B CF 48 8B 10 48 8B ?? ?? ?? ?? ?? "
"48 8D ?? ?? ?? E8 ?? ?? ?? ?? 48 ?? ?? ?? ?? ?? ??");
@@ -102,7 +104,7 @@ extern uint64_t MaxPlayerNumsPtr;
extern HashFunction_t FnServerHashFunction;
extern StateChanged_t FnStateChanged;
extern NetworkStateChanged_t FnNetworkStateChanged;
-extern RespawnPlayer_t FnRespawnPlayer;
+extern RespawnPlayerInDeathMatch_t FnRespawnPlayerInDeathMatch;
extern GiveNamedItem_t FnGiveNamedItem;
extern EntityRemove_t FnEntityRemove;
extern UTIL_SayTextFilter_t FnUTIL_SayTextFilter;
diff --git a/csgo2/script_apis.cpp b/csgo2/script_apis.cpp
index 46e45ba..ce6532b 100644
--- a/csgo2/script_apis.cpp
+++ b/csgo2/script_apis.cpp
@@ -111,6 +111,7 @@ auto luaApi_SetPlayerCurrentWeaponAmmo(lua_State* luaVm) -> int {
lua_pop(luaVm, 3);
return 0;
}
+//
auto luaApi_RespawnPlayer(lua_State* luaVm) -> int {
const auto playerIndex = lua_tointeger(luaVm, 1);
int playerArmorValue = 0;
@@ -120,7 +121,20 @@ auto luaApi_RespawnPlayer(lua_State* luaVm) -> int {
if (playerPawn == nullptr) {
return;
}
- Offset::FnRespawnPlayer(playerPawn);
+ Offset::InterFaces::CCSGameRulesInterFace->PlayerRespawn(playerPawn);
+ });
+ return 0;
+}
+auto luaApi_RespawnPlayerInDeathMatch(lua_State* luaVm) -> int {
+ const auto playerIndex = lua_tointeger(luaVm, 1);
+ int playerArmorValue = 0;
+ ExcutePlayerAction(playerIndex, [&](CCSPlayerController* playerController) {
+ const auto playerPawn =
+ playerController->m_hPawn().Get();
+ if (playerPawn == nullptr) {
+ return;
+ }
+ Offset::FnRespawnPlayerInDeathMatch(playerPawn);
});
return 0;
}
@@ -580,7 +594,7 @@ auto luaApi_SendToPlayerChat(lua_State* luaVm) -> int {
const auto playerIndex = lua_tointeger(luaVm, 1);
const auto hudType = lua_tointeger(luaVm, 2);
const auto message = lua_tostring(luaVm, 3);
- if (hudType >= _HubType::kMax || hudType < _HubType::kNotify) {
+ if (hudType >= static_cast(_HubType::kMax) || hudType < static_cast(_HubType::kNotify)) {
lua_pop(luaVm, 3);
return 0;
}
@@ -595,7 +609,7 @@ auto luaApi_SentToAllPlayerChat(lua_State* luaVm) -> int {
// param: playerIndex:int, message:string
const auto message = lua_tostring(luaVm, 1);
const auto hudType = lua_tointeger(luaVm, 2);
- if (hudType >= _HubType::kMax || hudType < _HubType::kNotify) {
+ if (hudType >= static_cast(_HubType::kMax) || hudType < static_cast(_HubType::kNotify)) {
lua_pop(luaVm, 3);
return 0;
}
@@ -661,7 +675,7 @@ auto luaApi_SetPlayerGlowColor(lua_State* luaVm) -> int {
const auto b = lua_tonumber(luaVm, 4);
ExcutePlayerAction(playerIndex, [&](CCSPlayerController* playerController) {
playerController->m_hPawn()
- .Get()
+ .Get()
->m_Glow()
.m_glowColorOverride(Color(r, g, b, 230));
});
@@ -673,10 +687,67 @@ auto luaApi_SetPlayerGlowEnable(lua_State* luaVm) -> int {
const auto playerIndex = lua_tointeger(luaVm, 1);
const auto isEnable = lua_toboolean(luaVm, 2);
ExcutePlayerAction(playerIndex, [&](CCSPlayerController* playerController) {
- playerController->m_hPawn().Get()->m_Glow().m_bGlowing(
+ LOG("glow set %d to %d \n",
+ playerController->m_hPawn()
+ .Get()
+ ->m_Glow()
+ .m_bGlowing(),
isEnable);
- playerController->m_hPawn().Get()->m_Glow().m_iGlowType(
- 3);
+ playerController->m_hPawn()
+ .Get()
+ ->m_Glow()
+ .m_bGlowing(isEnable);
+ playerController->m_hPawn()
+ .Get()
+ ->m_Glow()
+ .m_iGlowType(3);
+ playerController->m_hPawn()
+ .Get()
+ ->m_Glow()
+ .m_glowColorOverride(Color(201, 0, 118, 230));
+ });
+ lua_pop(luaVm, 2);
+ return 0;
+}
+auto luaApi_RunServerCommand(lua_State* luaVm) -> int {
+ const auto command = lua_tostring(luaVm, 1);
+ Offset::InterFaces::IVEngineServer->ServerCommand(command);
+ lua_pop(luaVm, 1);
+ return 0;
+}
+auto luaApi_RunClientCommand(lua_State* luaVm) -> int {
+ const auto playerIndex = lua_tointeger(luaVm, 1);
+ const auto command = lua_tostring(luaVm, 2);
+
+ ExcutePlayerAction(playerIndex, [&](CCSPlayerController* playerController) {
+ Offset::InterFaces::IVEngineServer->ClientCommand(EntityIndex_to_PlayerSlot(playerIndex), command);
+ });
+ lua_pop(luaVm, 2);
+ return 0;
+}
+auto luaApi_GetPlayerSteamId(lua_State* luaVm) -> int {
+ const auto playerIndex = lua_tointeger(luaVm, 1);
+ std::string steamid;
+ ExcutePlayerAction(playerIndex, [&](CCSPlayerController* playerController) {
+ steamid = std::to_string(playerController->m_steamID());
+ });
+ lua_pop(luaVm, 1);
+ lua_pushstring(luaVm, steamid.c_str());
+ return 1;
+}
+auto luaApi_KickPlayer(lua_State* luaVm) -> int {
+ const auto playerIndex = lua_tointeger(luaVm, 1);
+ const auto reason = lua_tostring(luaVm, 2);
+ ExcutePlayerAction(playerIndex, [&](CCSPlayerController* playerController) {
+ auto playerSlot = EntityIndex_to_PlayerSlot(playerIndex);
+ if (playerSlot == -1) {
+ return;
+ }
+ const auto theReason =
+ "You have kicked by server , reason: " + std::string(reason);
+ Offset::InterFaces::IVEngineServer->DisconnectClient(playerSlot, 39);
+ SdkTools::SentChatToClient(playerController, _HubType::kTalk,
+ theReason.c_str());
});
lua_pop(luaVm, 2);
return 0;
@@ -694,10 +765,10 @@ auto luaApi_GetAllPlayerIndex(lua_State* luaVm) -> int {
auto player = EntitySystem->GetBaseEntity(i);
if (player == nullptr) {
- break;
+ continue;
}
if (player->IsBasePlayerController() == false) {
- break;
+ continue;
}
lua_pushinteger(luaVm, player->GetRefEHandle().GetEntryIndex());
lua_rawseti(luaVm, -2, index++);
@@ -705,6 +776,160 @@ auto luaApi_GetAllPlayerIndex(lua_State* luaVm) -> int {
} while (false);
return 1;
}
+auto luaApi_HttpGet(lua_State* luaVm) -> int {
+ // param: url:string header:string timeOut:int
+ const auto url = lua_tostring(luaVm, 1);
+ const auto header = lua_tostring(luaVm, 2);
+ const auto timeOut = lua_tointeger(luaVm, 3);
+ auto strHeader = std::string(header);
+ std::string response;
+ auto result = Server::HttpGet(url, response, strHeader, timeOut);
+ lua_pushinteger(luaVm, result);
+ lua_pushstring(luaVm, response.c_str());
+ return 2;
+}
+auto luaApi_HttpPost(lua_State* luaVm) -> int {
+ // param: url:string header:string postdata:string timeOut:int
+ const auto url = lua_tostring(luaVm, 1);
+ const auto header = lua_tostring(luaVm, 2);
+ const auto postdata = lua_tostring(luaVm, 3);
+ const auto timeOut = lua_tointeger(luaVm, 4);
+ auto strHeader = std::string(header);
+ std::string response;
+ auto result = Server::HttpPost(url, strHeader, postdata, response, timeOut);
+ lua_pushinteger(luaVm, result);
+ lua_pushstring(luaVm, response.c_str());
+ return 2;
+}
+auto luaApi_HttpAsyncPost(lua_State* luaVm) -> int {
+ // param: url:string header:string postdata:string timeOut:int
+ // metadata:string
+ const auto url = lua_tostring(luaVm, 1);
+ const auto header = lua_tostring(luaVm, 2);
+ const auto postdata = lua_tostring(luaVm, 3);
+ const auto theTimeOut = lua_tointeger(luaVm, 4);
+ const auto metadata = lua_tostring(luaVm, 5);
+ struct _ctx {
+ std::shared_ptr url;
+ std::shared_ptr header;
+ std::shared_ptr postdata;
+ std::shared_ptr metadata;
+ long timeOut;
+ };
+ _ctx* ctx = new _ctx{
+ .url = std::make_shared(url),
+ .header = std::make_shared(header),
+ .postdata = std::make_shared(postdata),
+ .metadata = std::make_shared(metadata),
+ .timeOut = (int)theTimeOut,
+ };
+ if (ctx) {
+ CreateThread(
+ nullptr, 0,
+ [](void* ctx) -> DWORD {
+ const auto theCtx = reinterpret_cast<_ctx*>(ctx);
+ auto strHeader = std::string(*theCtx->header.get());
+ std::string response;
+ auto result = Server::HttpPost(*theCtx->url.get(), strHeader,
+ *theCtx->postdata.get(),
+ response, theCtx->timeOut);
+ ScriptCallBacks::luaCall_onHttpRequest(
+ *theCtx->url.get(), *theCtx->metadata.get(),
+ response.c_str(), result);
+ delete theCtx;
+ return 0;
+ },
+ ctx, 0, nullptr);
+ }
+ lua_pop(luaVm, 5);
+ return 0;
+}
+auto luaApi_HttpAsyncGet(lua_State* luaVm) -> int {
+ // param: url:string header:string timeOut:int
+ // metadata:string
+ const auto url = lua_tostring(luaVm, 1);
+ const auto header = lua_tostring(luaVm, 2);
+ const auto theTimeOut = lua_tointeger(luaVm, 3);
+ const auto metadata = lua_tostring(luaVm, 4);
+ struct _ctx {
+ std::shared_ptr url;
+ std::shared_ptr header;
+ std::shared_ptr metadata;
+ long timeOut;
+ };
+ _ctx* ctx = new _ctx{
+ .url = std::make_shared(url),
+ .header = std::make_shared(header),
+ .metadata = std::make_shared(metadata),
+ .timeOut = (long)theTimeOut,
+ };
+ if (ctx) {
+ CreateThread(
+ nullptr, 0,
+ [](void* ctx) -> DWORD {
+ const auto theCtx = reinterpret_cast<_ctx*>(ctx);
+ std::string response;
+ auto httpCode =
+ Server::HttpGet(*theCtx->url.get(), response,
+ *theCtx->header.get(), theCtx->timeOut);
+ ScriptCallBacks::luaCall_onHttpRequest(
+ *theCtx->url.get(), *theCtx->metadata.get(),
+ response.c_str(), httpCode);
+ delete theCtx;
+ return 0;
+ },
+ const_cast<_ctx*>(ctx), 0, nullptr);
+ }
+ lua_pop(luaVm, 4);
+ return 0;
+}
+auto luaApi_GetConVarString(lua_State* luaVm) -> int {
+ // param: convarObject:int
+ const auto inputData = lua_tointeger(luaVm, 1);
+ std::string value;
+ if (inputData != NULL) {
+ ConVarHandle theConvarHandle{};
+ theConvarHandle.Set(inputData);
+ if (theConvarHandle.IsValid()) {
+ const auto convarData =
+ Offset::InterFaces::IVEngineCvar->GetConVar(theConvarHandle);
+ if (convarData) {
+ const auto address = convarData->values;
+ const auto valueData = reinterpret_cast(address);
+ value = valueData ? std::string(valueData) : "";
+ }
+ }
+ }
+ lua_pop(luaVm, 1);
+ lua_pushstring(luaVm, value.c_str());
+
+ return 1;
+}
+auto luaApi_GetConVarInt(lua_State* luaVm) -> int {
+ // param: convarObject:int
+ const auto inputData = lua_tointeger(luaVm, 1);
+ if (inputData)
+ {
+ ConVarHandle theConvarHandle{};
+ theConvarHandle.Set(inputData);
+ int value = -1;
+ if (theConvarHandle.IsValid()) {
+ const auto convarData =
+ Offset::InterFaces::IVEngineCvar->GetConVar(theConvarHandle);
+ value = convarData ? reinterpret_cast(convarData->values) : -1;
+ }
+ lua_pop(luaVm, 1);
+ lua_pushinteger(luaVm, value);
+ }
+ return 1;
+}
+auto luaApi_GetConVarObject(lua_State* luaVm) -> int {
+ // param: name:string
+ const auto name = lua_tostring(luaVm, 1);
+ lua_pushnumber(luaVm,
+ Offset::InterFaces::IVEngineCvar->FindConVar(name).Get());
+ return 1;
+}
auto initFunciton(lua_State* luaVm) -> void {
lua_register(luaVm, "ListenToGameEvent", luaApi_ListenToGameEvent);
lua_register(luaVm, "luaApi_SetPlayerCurrentWeaponAmmo",
@@ -716,6 +941,8 @@ auto initFunciton(lua_State* luaVm) -> void {
lua_register(luaVm, "luaApi_SetPlayerArmorValue",
luaApi_SetPlayerArmorValue);
lua_register(luaVm, "luaApi_RespawnPlayer", luaApi_RespawnPlayer);
+ lua_register(luaVm, "luaApi_RespawnPlayerInDeathMatch",
+ luaApi_RespawnPlayerInDeathMatch);
lua_register(luaVm, "luaApi_CreateTimer", luaApi_CreateTimer);
lua_register(luaVm, "luaApi_CreateTickRunFunction",
luaApi_CreateTickRunFunction);
@@ -746,6 +973,20 @@ auto initFunciton(lua_State* luaVm) -> void {
luaApi_SetPlayerGlowEnable);
lua_register(luaVm, "luaApi_SetPlayerGlowColor", luaApi_SetPlayerGlowColor);
lua_register(luaVm, "luaApi_GetAllPlayerIndex", luaApi_GetAllPlayerIndex);
+ lua_register(luaVm, "luaApi_RunServerCommand", luaApi_RunServerCommand);
+ lua_register(luaVm, "luaApi_KickPlayer", luaApi_KickPlayer);
+ lua_register(luaVm, "luaApi_HttpGet", luaApi_HttpGet);
+ lua_register(luaVm, "luaApi_HttpPost", luaApi_HttpPost);
+ lua_register(luaVm, "luaApi_HttpAsyncGet", luaApi_HttpAsyncGet);
+ lua_register(luaVm, "luaApi_HttpAsyncPost", luaApi_HttpAsyncPost);
+ lua_register(luaVm, "luaApi_GetConVarObject", luaApi_GetConVarObject);
+
+ lua_register(luaVm, "luaApi_GetConVarString", luaApi_GetConVarString);
+ lua_register(luaVm, "luaApi_GetConVarInt", luaApi_GetConVarInt);
+ lua_register(luaVm, "luaApi_GetPlayerSteamId", luaApi_GetPlayerSteamId);
+ lua_register(luaVm, "luaApi_RunClientCommand", luaApi_RunClientCommand);
+
+ // lua_register(luaVm, "luaApi_TeleportPlayer", luaApi_TeleportPlayer);
luabridge::getGlobalNamespace(luaVm)
.beginClass<_luaApi_WeaponInfo>("WeaponInfo")
diff --git a/csgo2/script_callbacks.cpp b/csgo2/script_callbacks.cpp
index 6448273..6a1c885 100644
--- a/csgo2/script_callbacks.cpp
+++ b/csgo2/script_callbacks.cpp
@@ -14,6 +14,9 @@ std::unordered_map callbackNameWithEnumMap{
{hash_32_fnv1a_const("round_start"), _CallbackNames::kOnRoundStart},
{hash_32_fnv1a_const("round_end"), _CallbackNames::kOnRoundEnd},
{hash_32_fnv1a_const("player_hurt"), _CallbackNames::kOnPlayerHurt},
+ {hash_32_fnv1a_const("player_team"), _CallbackNames::kOnPlayerTeamChange},
+ {hash_32_fnv1a_const("http_request"), _CallbackNames::kOnHttpRequest},
+
};
auto CallBackNameToEnum(const char* name) -> _CallbackNames {
if (name == nullptr) {
@@ -205,4 +208,51 @@ auto luaCall_onPlayerHurt(int userid, int attacker, int health, int armor,
}
});
}
+auto luaCall_onPlayerTeamChange(int userid, int team, int oldteam,
+ bool disconnect, bool slient, bool isBot)
+ -> bool {
+ bool result = false;
+ ExcuteCallbackInAllLuaVm(_CallbackNames::kOnPlayerTeamChange,
+ [&](lua_State* luaVm, int refIndex) -> void {
+ lua_rawgeti(luaVm, LUA_REGISTRYINDEX,
+ refIndex);
+ if (lua_isfunction(luaVm, -1)) {
+ lua_pushinteger(luaVm, userid);
+ lua_pushinteger(luaVm, team);
+ lua_pushinteger(luaVm, oldteam);
+ lua_pushboolean(luaVm, disconnect);
+ lua_pushboolean(luaVm, slient);
+ lua_pushboolean(luaVm, isBot);
+
+ if (lua_pcall(luaVm, 6, 1, 0) != LUA_OK) {
+ LOG("Error calling Lua callback: %s\n",
+ lua_tostring(luaVm, -1));
+ lua_pop(luaVm, 1);
+ }
+ if (lua_isboolean(luaVm, -1)) {
+ result = lua_toboolean(luaVm, -1);
+ }
+ }
+ });
+ return result;
+}
+auto luaCall_onHttpRequest(std::string url, std::string metaData,
+ std::string respon, int statusCode) -> void {
+ ExcuteCallbackInAllLuaVm(_CallbackNames::kOnHttpRequest,
+ [&](lua_State* luaVm, int refIndex) -> void {
+ lua_rawgeti(luaVm, LUA_REGISTRYINDEX,
+ refIndex);
+ if (lua_isfunction(luaVm, -1)) {
+ lua_pushstring(luaVm, url.c_str());
+ lua_pushstring(luaVm, metaData.c_str());
+ lua_pushstring(luaVm, respon.c_str());
+ lua_pushinteger(luaVm, statusCode);
+ if (lua_pcall(luaVm, 4, 0, 0) != LUA_OK) {
+ LOG("Error calling Lua callback: %s\n",
+ lua_tostring(luaVm, -1));
+ lua_pop(luaVm, 1);
+ }
+ }
+ });
+}
} // namespace ScriptCallBacks
diff --git a/csgo2/script_callbacks.h b/csgo2/script_callbacks.h
index c3e3ba1..9e4b6ad 100644
--- a/csgo2/script_callbacks.h
+++ b/csgo2/script_callbacks.h
@@ -11,7 +11,9 @@ enum class _CallbackNames {
kOnPlayerSpawn,
kOnRoundStart,
kOnRoundEnd,
- kOnPlayerHurt
+ kOnPlayerHurt,
+ kOnPlayerTeamChange,
+ kOnHttpRequest
};
extern std::unordered_map>
callbackList;
@@ -33,4 +35,9 @@ auto luaCall_onRoundEnd(int winnerTeam, int reason, const char* message)
auto luaCall_onPlayerHurt(int userid, int attacker, int health, int armor,
const char* weapon, int dmg_health, int dmg_armor,
int hitgroup) -> void;
+auto luaCall_onPlayerTeamChange(int userid, int team, int oldteam,
+ bool disconnect, bool slient, bool isBot)
+ -> bool;
+auto luaCall_onHttpRequest(std::string url, std::string metaData,
+ std::string respon, int statusCode) -> void;
} // namespace ScriptCallBacks
diff --git a/csgo2/script_engine.cpp b/csgo2/script_engine.cpp
index f9c2526..ce8c66b 100644
--- a/csgo2/script_engine.cpp
+++ b/csgo2/script_engine.cpp
@@ -1,4 +1,6 @@
#include "script_engine.h"
+extern "C" int luaopen_cjson(lua_State * L);
+
namespace ScriptEngine {
std::string luaPath;
std::map pluginEnvs;
@@ -44,6 +46,10 @@ auto initLuaScripts() -> void {
lua_State* L = luaL_newstate();
luaL_openlibs(L);
+
+ luaL_requiref(L, "cjson", luaopen_cjson, 1);
+ lua_pop(L, 1);
+
ScriptApis::initFunciton(L);
pluginEnvs[dirName] = L;
@@ -59,15 +65,20 @@ auto initLuaScripts() -> void {
std::string scriptDir = dirPath;
lua_getglobal(L, "package");
- lua_getfield(L, -1, "path"); // get field "path" from table at top of stack (-1)
- std::string cur_path = lua_tostring(L, -1); // grab path string from top of stack
- cur_path.append(";"); // do your path magic here
+ lua_getfield(
+ L, -1, "path"); // get field "path" from table at top of stack (-1)
+ std::string cur_path =
+ lua_tostring(L, -1); // grab path string from top of stack
+ cur_path.append(";"); // do your path magic here
cur_path.append(scriptDir);
cur_path.append("\\?.lua");
- lua_pop(L, 1); // get rid of the string on the stack we just pushed on line 5
- lua_pushstring(L, cur_path.c_str()); // push the new one
- lua_setfield(L, -2, "path"); // set the field "path" in table at -2 with value at top of stack
- lua_pop(L, 1); // get rid of package table from top of stack
+ lua_pop(
+ L,
+ 1); // get rid of the string on the stack we just pushed on line 5
+ lua_pushstring(L, cur_path.c_str()); // push the new one
+ lua_setfield(L, -2, "path"); // set the field "path" in table at -2
+ // with value at top of stack
+ lua_pop(L, 1); // get rid of package table from top of stack
if (luaL_dofile(L, file.c_str())) {
LOG("dofile_err:%s\n\n", lua_tostring(L, -1));
diff --git a/csgo2/sdk/gameevent/IGameEvent.h b/csgo2/sdk/gameevent/IGameEvent.h
index 0a25ed4..5d2c105 100644
--- a/csgo2/sdk/gameevent/IGameEvent.h
+++ b/csgo2/sdk/gameevent/IGameEvent.h
@@ -9,87 +9,168 @@ class CUtlString;
class IToolGameEventAPI {
virtual void unk001(void*) = 0;
};
-struct UnkGameEventStruct_t {
- UnkGameEventStruct_t(const char* keyName) {
- m_Unk = 0;
- m_Key = keyName;
+
+static auto MurmurHash2(const void* key, int len, uint32 seed) -> uint32_t
+{
+#define LittleDWord( val ) ( val )
+
+ // 'm' and 'r' are mixing constants generated offline.
+ // They're not really 'magic', they just happen to work well.
+
+ const uint32 m = 0x5bd1e995;
+ const int r = 24;
+
+ // Initialize the hash to a 'random' value
+
+ uint32 h = seed ^ len;
+
+ // Mix 4 bytes at a time into the hash
+
+ const unsigned char* data = (const unsigned char*)key;
+
+ while (len >= 4)
+ {
+ uint32 k = LittleDWord(*(uint32*)data);
+
+ k *= m;
+ k ^= k >> r;
+ k *= m;
+
+ h *= m;
+ h ^= k;
+
+ data += 4;
+ len -= 4;
}
- uint64_t m_Unk;
- const char* m_Key;
+ // Handle the last few bytes of the input array
+
+ switch (len)
+ {
+ case 3: h ^= data[2] << 16;
+ case 2: h ^= data[1] << 8;
+ case 1: h ^= data[0];
+ h *= m;
+ };
+
+ // Do a few final mixes of the hash to ensure the last few
+ // bytes are well-incorporated.
+
+ h ^= h >> 13;
+ h *= m;
+ h ^= h >> 15;
+
+ return h;
+}
+
+struct GameEventKeySymbol_t {
+ GameEventKeySymbol_t(const char* keyName) {
+ if (keyName != nullptr) {
+ m_nHashCode = MurmurHash2(keyName, strlen(keyName), 0x31415926);
+ m_pszKeyName = keyName;
+ }
+ }
+
+ uint64_t m_nHashCode;
+ const char* m_pszKeyName;
};
-class IGameEvent {
+class IHandleEntity
+{
+ virtual void Schema_DynamicBinding(void**) = 0;
+public:
+ virtual ~IHandleEntity() = 0;
+ virtual const CEntityHandle GetRefEHandle() const = 0;
+};
+class IGameEvent{
public:
- // 0
- virtual ~IGameEvent(){};
+ virtual ~IGameEvent() {};
virtual const char* GetName() const = 0; // get event name
virtual int GetID() const = 0;
virtual bool IsReliable() const = 0; // if event handled reliable
virtual bool IsLocal() const = 0; // if event is never networked
- virtual bool IsEmpty(
- const char* keyName = NULL) = 0; // check if data field exists
+ virtual bool IsEmpty(const GameEventKeySymbol_t
+ & keySymbol) = 0; // check if data field exists
- // Data access index 6
- virtual bool GetBool(UnkGameEventStruct_t* keyName = NULL,
+ // Data access
+ virtual bool GetBool(const GameEventKeySymbol_t& keySymbol,
bool defaultValue = false) = 0;
- virtual int GetInt(UnkGameEventStruct_t* keyName = NULL,
+ virtual int GetInt(const GameEventKeySymbol_t& keySymbol,
int defaultValue = 0) = 0;
- virtual uint64_t GetUint64(const char* keyName = NULL,
- uint64_t defaultValue = 0) = 0;
- virtual float GetFloat(const char* keyName = NULL,
+ virtual uint64 GetUint64(const GameEventKeySymbol_t& keySymbol,
+ uint64 defaultValue = 0) = 0;
+ virtual float GetFloat(const GameEventKeySymbol_t& keySymbol,
float defaultValue = 0.0f) = 0;
- virtual const char* GetString(UnkGameEventStruct_t* keyName = NULL,
+ virtual const char* GetString(const GameEventKeySymbol_t& keySymbol,
const char* defaultValue = "") = 0;
- virtual void* GetPtr(const char* keyName = NULL,
- void* defaultValue = NULL) = 0;
-
- /* These function prototypes and names are very speculative and might be
- * incorrect */
- virtual CEntityHandle GetEHandle(UnkGameEventStruct_t* keyName,
- CEntityHandle defaultValue) = 0;
- virtual CEntityHandle GetStrictEHandle(UnkGameEventStruct_t* keyName,
- CEntityHandle defaultValue) = 0;
- virtual CEntityHandle GetEHandle2(UnkGameEventStruct_t* keyName,
- CEntityHandle defaultValue) = 0;
-
- virtual CPlayerSlot* GetPlayerSlot(
- UnkGameEventStruct_t* keyName = NULL) = 0;
- virtual CBasePlayer* GetPlayer(UnkGameEventStruct_t* keyName = NULL) = 0;
-
- virtual void* GetPlayerPawn(UnkGameEventStruct_t* keyName = NULL) = 0;
- virtual CEntityHandle GetPlayerControllerEHandle(
- UnkGameEventStruct_t* keyName = NULL) = 0;
- virtual CEntityHandle GetPlayerControllerEHandle2(
- UnkGameEventStruct_t* keyName = NULL) = 0;
- /* ============================================================ */
-
- virtual void SetBool(const char* keyName, bool value) = 0;
- virtual void SetInt(const char* keyName, int value) = 0;
- virtual void SetUint64(const char* keyName, uint64_t value) = 0;
- virtual void SetFloat(const char* keyName, float value) = 0;
- virtual void SetString(const char* keyName, const char* value) = 0;
- virtual void SetPtr(const char* keyName, void* value) = 0;
-
- /* These function prototypes and names are very speculative and might be
- * incorrect */
- virtual void SetEHandleStrict(const char* keyName,
- CEntityHandle handle) = 0;
- virtual void SetEHandle(const char* keyName, CEntityHandle handle) = 0;
+ virtual void* GetPtr(const GameEventKeySymbol_t& keySymbol) = 0;
+
+ virtual CEntityHandle GetEHandle(
+ const GameEventKeySymbol_t& keySymbol,
+ CEntityHandle defaultValue = CEntityHandle()) = 0;
+
+ // Returns the entity instance, mostly used for _pawn keys, might return 0
+ // if used on any other key (even on a controller).
+ virtual IHandleEntity* GetEntity(
+ const GameEventKeySymbol_t& keySymbol,
+ IHandleEntity* fallbackInstance = NULL) = 0;
+ virtual CEntityIndex GetEntityIndex(
+ const GameEventKeySymbol_t& keySymbol,
+ CEntityIndex defaultValue = CEntityIndex(-1)) = 0;
+
+ virtual CPlayerSlot GetPlayerSlot(
+ const GameEventKeySymbol_t& keySymbol) = 0;
+
+ virtual IHandleEntity* GetPlayerController(
+ const GameEventKeySymbol_t& keySymbol) = 0;
+ virtual IHandleEntity* GetPlayerPawn(
+ const GameEventKeySymbol_t& keySymbol) = 0;
+
+ // Returns the EHandle for the _pawn entity.
+ virtual CEntityHandle GetPawnEHandle(
+ const GameEventKeySymbol_t& keySymbol) = 0;
+ // Returns the CEntityIndex for the _pawn entity.
+ virtual CEntityIndex GetPawnEntityIndex(
+ const GameEventKeySymbol_t& keySymbol) = 0;
+
+ virtual void SetBool(const GameEventKeySymbol_t& keySymbol, bool value) = 0;
+ virtual void SetInt(const GameEventKeySymbol_t& keySymbol, int value) = 0;
+ virtual void SetUint64(const GameEventKeySymbol_t& keySymbol,
+ uint64 value) = 0;
+ virtual void SetFloat(const GameEventKeySymbol_t& keySymbol,
+ float value) = 0;
+ virtual void SetString(const GameEventKeySymbol_t& keySymbol,
+ const char* value) = 0;
+ virtual void SetPtr(const GameEventKeySymbol_t& keySymbol, void* value) = 0;
+
+ virtual void SetEntity(const GameEventKeySymbol_t& keySymbol,
+ CEntityIndex value) = 0;
+ virtual void SetEntity(const GameEventKeySymbol_t& keySymbol,
+ IHandleEntity* value) = 0;
// Also sets the _pawn key
- virtual void SetPlayerSlot(const char* keyName, CPlayerSlot value) = 0;
- virtual void SetPlayer(const char* keyName, CBasePlayer* value) = 0;
- /* ============================================================ */
+ virtual void SetPlayer(const GameEventKeySymbol_t& keySymbol,
+ CPlayerSlot value) = 0;
+ // Also sets the _pawn key (Expects pawn entity to be passed)
+ virtual void SetPlayer(const GameEventKeySymbol_t& keySymbol,
+ IHandleEntity* pawn) = 0;
- virtual bool HasKey(const char* keyName) = 0;
+ // Expects pawn entity to be passed, will set the controller entity as a
+ // controllerKeyName and pawn entity as a pawnKeyName.
+ virtual void SetPlayerRaw(const GameEventKeySymbol_t& controllerKeySymbol,
+ const GameEventKeySymbol_t& pawnKeySymbol,
+ IHandleEntity* pawn) = 0;
+
+ virtual bool HasKey(const GameEventKeySymbol_t& keySymbol) = 0;
// Something script vm related
virtual void unk001() = 0;
- // virtual KeyValues* GetDataKeys() const = 0;
+ // Not based on keyvalues anymore as it seems like
+ virtual void* GetDataKeys() const = 0;
};
+
class IGameEventListener2 {
public:
virtual ~IGameEventListener2(void){};
diff --git a/csgo2/sdk/public/eiface.h b/csgo2/sdk/public/eiface.h
index afc5bb7..dbabd48 100644
--- a/csgo2/sdk/public/eiface.h
+++ b/csgo2/sdk/public/eiface.h
@@ -313,6 +313,7 @@ class ISource2Server : public IAppSystem
virtual void ServerConVarChanged(const char* pVarName, const char* pValue) = 0;
};
+
//-----------------------------------------------------------------------------
// Purpose: Interface the engine exposes to the game DLL
//-----------------------------------------------------------------------------
@@ -326,6 +327,7 @@ class IVEngineServer2 : public ISource2Engine
virtual void unk003() = 0;
virtual void unk004() = 0;
virtual void unk005() = 0;
+ virtual void unk006() = 0;
// Tell engine to change level ( "changelevel s1\n" or "changelevel2 s1 s2\n" )
@@ -417,7 +419,7 @@ class IVEngineServer2 : public ISource2Engine
virtual void SetTimescale(float flTimescale) = 0;
- virtual uint32_t GetAppID() = 0;
+ virtual uint32 GetAppID() = 0;
// Returns the SteamID of the specified player. It'll be NULL if the player hasn't authenticated yet.
virtual const CSteamID* GetClientSteamID(CPlayerSlot clientIndex) = 0;
@@ -451,7 +453,7 @@ class IVEngineServer2 : public ISource2Engine
virtual bool GetPlayerInfo(CPlayerSlot clientIndex, google::protobuf::Message& info) = 0;
// Returns the XUID of the specified player. It'll be NULL if the player hasn't connected yet.
- virtual uint64_t GetClientXUID(CPlayerSlot clientIndex) = 0;
+ virtual uint64 GetClientXUID(CPlayerSlot clientIndex) = 0;
virtual void* GetPVSForSpawnGroup(SpawnGroupHandle_t spawnGroup) = 0;
virtual SpawnGroupHandle_t FindSpawnGroupByName(const char* szName) = 0;
@@ -463,45 +465,57 @@ class IVEngineServer2 : public ISource2Engine
virtual bool IsClientLowViolence(CEntityIndex clientIndex) = 0;
-#if 0 // Don't really match the binary
+ // Kicks the slot with the specified NetworkDisconnectionReason
virtual void DisconnectClient(CEntityIndex clientIndex, /* ENetworkDisconnectionReason */ int reason) = 0;
+#if 0 // Don't really match the binary
virtual void GetAllSpawnGroupsWithPVS(CUtlVector* spawnGroups, CUtlVector* pOut) = 0;
virtual void P2PGroupChanged() = 0;
#endif
- virtual void unk006() = 0;
- virtual void unk007() = 0;
- virtual void unk008() = 0;
- virtual void unk009() = 0;
- virtual void unk010() = 0;
- virtual void unk011() = 0;
- virtual void unk012() = 0;
- virtual void unk013() = 0;
+ virtual void unk101() = 0;
+ virtual void unk102() = 0;
+ virtual void unk103() = 0;
+ virtual void unk104() = 0;
+ virtual void unk105() = 0;
+ virtual void unk106() = 0;
+ virtual void unk107() = 0;
virtual void OnKickClient(const CCommandContext& context, const CCommand& cmd) = 0;
- // Kicks the slot with the specified NetworkDisconnectionReason.
+ // Kicks and bans the slot.
// Note that the internal reason is never displayed to the user.
+ // ENetworkDisconnectionReason reason is ignored, client is always kicked with ENetworkDisconnectionReason::NETWORK_DISCONNECT_KICKBANADDED
//
// AM TODO: add header ref for ENetworkDisconnectReason from proto header
- virtual void KickClient(CPlayerSlot slot, const char* szInternalReason, /*ENetworkDisconnectionReason*/ char reason) = 0;
-
- virtual void unk015() = 0;
- virtual void unk016() = 0;
- virtual void unk017() = 0;
- virtual void unk018() = 0;
- virtual void unk019() = 0;
- virtual void unk020() = 0;
- virtual void unk021() = 0;
- virtual void unk022() = 0;
- virtual void unk023() = 0;
+ virtual void BanClient(CPlayerSlot slot, const char* szInternalReason, /*ENetworkDisconnectionReason*/ char reason) = 0;
+
+ virtual void unk200() = 0;
+ virtual void unk201() = 0;
+ virtual void unk202() = 0;
+ virtual void unk203() = 0;
+ virtual void unk204() = 0;
+ virtual void unk205() = 0;
+ virtual void unk206() = 0;
+ virtual void unk207() = 0;
+ virtual void unk208() = 0;
virtual void SetClientUpdateRate(CEntityIndex clientIndex, float flUpdateRate) = 0;
- virtual void unk024() = 0;
- virtual void unk025() = 0;
+ virtual void unk300() = 0;
+ virtual void unk301() = 0;
+};
+
+class IServerGCLobby
+{
+public:
+ virtual bool HasLobby() const = 0;
+ virtual bool SteamIDAllowedToConnect(const CSteamID& steamId) const = 0;
+ virtual void UpdateServerDetails(void) = 0;
+ virtual bool ShouldHibernate() = 0;
+ virtual bool SteamIDAllowedToP2PConnect(const CSteamID& steamId) const = 0;
+ virtual bool LobbyAllowsCheats(void) const = 0;
};
//-----------------------------------------------------------------------------
// Purpose: Player / Client related functions
diff --git a/csgo2/sdk_tools.cpp b/csgo2/sdk_tools.cpp
index 8207867..4f5108c 100644
--- a/csgo2/sdk_tools.cpp
+++ b/csgo2/sdk_tools.cpp
@@ -38,7 +38,7 @@ auto SentChatToClient(CCSPlayerController* player, _HubType hubtype, const char*
va_end(args);
- Offset::FnClientPrint(player, hubtype, buf, nullptr, nullptr, nullptr, nullptr);
+ Offset::FnClientPrint(player, static_cast(hubtype), buf, nullptr, nullptr, nullptr, nullptr);
}
auto SendConsoleChat(_HubType hubtype, const char* msg, ...) -> void
{
@@ -50,6 +50,6 @@ auto SendConsoleChat(_HubType hubtype, const char* msg, ...) -> void
va_end(args);
- Offset::FnUTIL_ClientPrintAll(hubtype, buf, nullptr, nullptr, nullptr, nullptr);
+ Offset::FnUTIL_ClientPrintAll(static_cast(hubtype), buf, nullptr, nullptr, nullptr, nullptr);
}
}; // namespace SdkTools
diff --git a/csgo2/sdk_tools.h b/csgo2/sdk_tools.h
index 86894fd..0c95519 100644
--- a/csgo2/sdk_tools.h
+++ b/csgo2/sdk_tools.h
@@ -8,8 +8,8 @@ inline int EntityIndex_to_PlayerSlot(int EntityIndex) {
#define HUD_PRINTCONSOLE 2
#define HUD_PRINTTALK 3
#define HUD_PRINTCENTER 4
-enum _ChatType { kTeam, kAll };
-enum _HubType { kNotify = 1, kConsole, kTalk, kCenter, kMax };
+enum class _ChatType { kTeam, kAll, kConsole };
+enum class _HubType { kNotify = 1, kConsole, kTalk, kCenter, kMax };
namespace SdkTools {
auto ProcessChatString(const std::string& input)
diff --git a/csgo2/tools.cpp b/csgo2/tools.cpp
index 588925f..a8b7d49 100644
--- a/csgo2/tools.cpp
+++ b/csgo2/tools.cpp
@@ -1,5 +1,11 @@
#include "tools.h"
namespace Tools {
+auto toLower(const std::string& str) -> std::string{
+ std::string lowerStr = str;
+ std::transform(lowerStr.begin(), lowerStr.end(), lowerStr.begin(),
+ [](unsigned char c) { return std::tolower(c); });
+ return lowerStr;
+}
auto GetDirs(const std::string& path)
-> std::pair, std::vector> {
std::vector dirPaths;
diff --git a/csgo2/tools.h b/csgo2/tools.h
index 75d194c..6cf3377 100644
--- a/csgo2/tools.h
+++ b/csgo2/tools.h
@@ -6,4 +6,5 @@ auto GetExePath() -> std::string;
auto GetFiles(const std::string& path, std::vector& files) -> void;
auto GetDirs(const std::string& path)
-> std::pair, std::vector>;
+auto toLower(const std::string& str) -> std::string;
}; // namespace Tools
diff --git a/loader/loader/loader.cpp b/loader/loader/loader.cpp
index 77219dd..dea2e6c 100644
--- a/loader/loader/loader.cpp
+++ b/loader/loader/loader.cpp
@@ -4,16 +4,48 @@
#include
#include
#include
+#include
+#include "../../raidjson/rapidjson/rapidjson.h"
+#include
+#include
+struct _Config
+{
+ std::string dll;
+ std::string path;
+ std::string command;
+};
+namespace Config {
+ std::vector<_Config> configs;
+ auto ReadConfig() -> bool {
+ bool result = false;
+ std::ifstream ifs("config.json");
+ if (!ifs.is_open()) {
+ std::cerr << "Could not open file for reading!\n";
+ return result;
+ }
-// 读取INI文件
-std::pair readConfig() {
- char path[255], command[255];
+ rapidjson::IStreamWrapper isw(ifs);
+ rapidjson::Document d;
+ d.ParseStream(isw);
- GetPrivateProfileStringA("server", "path", "", path, 255, ".\\config.ini");
- GetPrivateProfileStringA("server", "command", "", command, 255, ".\\config.ini");
-
- return { std::string(path), std::string(command) };
-}
+ const rapidjson::Value& servers = d["servers"]; // Using a reference for consecutive access is handy and faster.
+ assert(servers.IsArray());
+ for (rapidjson::SizeType i = 0; i < servers.Size(); i++) { // Uses SizeType instead of size_t
+ const rapidjson::Value& server = servers[i];
+ assert(server.IsObject()); // Each server should be an object.
+ if (server.HasMember("path") && server["path"].IsString() && server.HasMember("command") && server["command"].IsString() && server.HasMember("dll") && server["dll"].IsString())
+ {
+ configs.push_back(_Config{
+ .dll = server["dll"].GetString(),
+ .path = server["path"].GetString(),
+ .command = server["command"].GetString()
+ });
+ }
+ }
+ result = true;
+ return result;
+ }
+};
// 创建进程
PROCESS_INFORMATION createProcess(const std::string& path, const std::string& command) {
@@ -48,9 +80,13 @@ void loadDll(PROCESS_INFORMATION pi) {
}
int main() {
- auto [path, command] = readConfig();
- PROCESS_INFORMATION pi = createProcess(path, command);
- loadDll(pi);
-
+ Config::ReadConfig();
+ if (Config::configs.size() > 0) {
+ for (auto& config : Config::configs)
+ {
+ PROCESS_INFORMATION pi = createProcess(config.path, config.command);
+ loadDll(pi);
+ }
+ }
return 0;
}
\ No newline at end of file
diff --git a/loader/loader/loader.vcxproj b/loader/loader/loader.vcxproj
index 8cc1ffb..cecc8cc 100644
--- a/loader/loader/loader.vcxproj
+++ b/loader/loader/loader.vcxproj
@@ -78,9 +78,11 @@
true
+ $(ProjectDir)..\..\raidjson\rapidjson;$(IncludePath)
false
+ $(ProjectDir)..\..\raidjson\rapidjson;$(IncludePath)
@@ -132,6 +134,7 @@
NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
true
stdcpplatest
+ MultiThreaded
Console
diff --git a/raidjson/rapidjson/allocators.h b/raidjson/rapidjson/allocators.h
new file mode 100644
index 0000000..12bc5ba
--- /dev/null
+++ b/raidjson/rapidjson/allocators.h
@@ -0,0 +1,692 @@
+// Tencent is pleased to support the open source community by making RapidJSON available.
+//
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
+//
+// Licensed under the MIT License (the "License"); you may not use this file except
+// in compliance with the License. You may obtain a copy of the License at
+//
+// http://opensource.org/licenses/MIT
+//
+// Unless required by applicable law or agreed to in writing, software distributed
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations under the License.
+
+#ifndef RAPIDJSON_ALLOCATORS_H_
+#define RAPIDJSON_ALLOCATORS_H_
+
+#include "rapidjson.h"
+#include "internal/meta.h"
+
+#include
+
+#if RAPIDJSON_HAS_CXX11
+#include
+#endif
+
+RAPIDJSON_NAMESPACE_BEGIN
+
+///////////////////////////////////////////////////////////////////////////////
+// Allocator
+
+/*! \class rapidjson::Allocator
+ \brief Concept for allocating, resizing and freeing memory block.
+
+ Note that Malloc() and Realloc() are non-static but Free() is static.
+
+ So if an allocator need to support Free(), it needs to put its pointer in
+ the header of memory block.
+
+\code
+concept Allocator {
+ static const bool kNeedFree; //!< Whether this allocator needs to call Free().
+
+ // Allocate a memory block.
+ // \param size of the memory block in bytes.
+ // \returns pointer to the memory block.
+ void* Malloc(size_t size);
+
+ // Resize a memory block.
+ // \param originalPtr The pointer to current memory block. Null pointer is permitted.
+ // \param originalSize The current size in bytes. (Design issue: since some allocator may not book-keep this, explicitly pass to it can save memory.)
+ // \param newSize the new size in bytes.
+ void* Realloc(void* originalPtr, size_t originalSize, size_t newSize);
+
+ // Free a memory block.
+ // \param pointer to the memory block. Null pointer is permitted.
+ static void Free(void *ptr);
+};
+\endcode
+*/
+
+
+/*! \def RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY
+ \ingroup RAPIDJSON_CONFIG
+ \brief User-defined kDefaultChunkCapacity definition.
+
+ User can define this as any \c size that is a power of 2.
+*/
+
+#ifndef RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY
+#define RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY (64 * 1024)
+#endif
+
+
+///////////////////////////////////////////////////////////////////////////////
+// CrtAllocator
+
+//! C-runtime library allocator.
+/*! This class is just wrapper for standard C library memory routines.
+ \note implements Allocator concept
+*/
+class CrtAllocator {
+public:
+ static const bool kNeedFree = true;
+ void* Malloc(size_t size) {
+ if (size) // behavior of malloc(0) is implementation defined.
+ return RAPIDJSON_MALLOC(size);
+ else
+ return NULL; // standardize to returning NULL.
+ }
+ void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {
+ (void)originalSize;
+ if (newSize == 0) {
+ RAPIDJSON_FREE(originalPtr);
+ return NULL;
+ }
+ return RAPIDJSON_REALLOC(originalPtr, newSize);
+ }
+ static void Free(void *ptr) RAPIDJSON_NOEXCEPT { RAPIDJSON_FREE(ptr); }
+
+ bool operator==(const CrtAllocator&) const RAPIDJSON_NOEXCEPT {
+ return true;
+ }
+ bool operator!=(const CrtAllocator&) const RAPIDJSON_NOEXCEPT {
+ return false;
+ }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// MemoryPoolAllocator
+
+//! Default memory allocator used by the parser and DOM.
+/*! This allocator allocate memory blocks from pre-allocated memory chunks.
+
+ It does not free memory blocks. And Realloc() only allocate new memory.
+
+ The memory chunks are allocated by BaseAllocator, which is CrtAllocator by default.
+
+ User may also supply a buffer as the first chunk.
+
+ If the user-buffer is full then additional chunks are allocated by BaseAllocator.
+
+ The user-buffer is not deallocated by this allocator.
+
+ \tparam BaseAllocator the allocator type for allocating memory chunks. Default is CrtAllocator.
+ \note implements Allocator concept
+*/
+template
+class MemoryPoolAllocator {
+ //! Chunk header for perpending to each chunk.
+ /*! Chunks are stored as a singly linked list.
+ */
+ struct ChunkHeader {
+ size_t capacity; //!< Capacity of the chunk in bytes (excluding the header itself).
+ size_t size; //!< Current size of allocated memory in bytes.
+ ChunkHeader *next; //!< Next chunk in the linked list.
+ };
+
+ struct SharedData {
+ ChunkHeader *chunkHead; //!< Head of the chunk linked-list. Only the head chunk serves allocation.
+ BaseAllocator* ownBaseAllocator; //!< base allocator created by this object.
+ size_t refcount;
+ bool ownBuffer;
+ };
+
+ static const size_t SIZEOF_SHARED_DATA = RAPIDJSON_ALIGN(sizeof(SharedData));
+ static const size_t SIZEOF_CHUNK_HEADER = RAPIDJSON_ALIGN(sizeof(ChunkHeader));
+
+ static inline ChunkHeader *GetChunkHead(SharedData *shared)
+ {
+ return reinterpret_cast(reinterpret_cast(shared) + SIZEOF_SHARED_DATA);
+ }
+ static inline uint8_t *GetChunkBuffer(SharedData *shared)
+ {
+ return reinterpret_cast(shared->chunkHead) + SIZEOF_CHUNK_HEADER;
+ }
+
+ static const size_t kDefaultChunkCapacity = RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY; //!< Default chunk capacity.
+
+public:
+ static const bool kNeedFree = false; //!< Tell users that no need to call Free() with this allocator. (concept Allocator)
+ static const bool kRefCounted = true; //!< Tell users that this allocator is reference counted on copy
+
+ //! Constructor with chunkSize.
+ /*! \param chunkSize The size of memory chunk. The default is kDefaultChunkSize.
+ \param baseAllocator The allocator for allocating memory chunks.
+ */
+ explicit
+ MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :
+ chunk_capacity_(chunkSize),
+ baseAllocator_(baseAllocator ? baseAllocator : RAPIDJSON_NEW(BaseAllocator)()),
+ shared_(static_cast(baseAllocator_ ? baseAllocator_->Malloc(SIZEOF_SHARED_DATA + SIZEOF_CHUNK_HEADER) : 0))
+ {
+ RAPIDJSON_ASSERT(baseAllocator_ != 0);
+ RAPIDJSON_ASSERT(shared_ != 0);
+ if (baseAllocator) {
+ shared_->ownBaseAllocator = 0;
+ }
+ else {
+ shared_->ownBaseAllocator = baseAllocator_;
+ }
+ shared_->chunkHead = GetChunkHead(shared_);
+ shared_->chunkHead->capacity = 0;
+ shared_->chunkHead->size = 0;
+ shared_->chunkHead->next = 0;
+ shared_->ownBuffer = true;
+ shared_->refcount = 1;
+ }
+
+ //! Constructor with user-supplied buffer.
+ /*! The user buffer will be used firstly. When it is full, memory pool allocates new chunk with chunk size.
+
+ The user buffer will not be deallocated when this allocator is destructed.
+
+ \param buffer User supplied buffer.
+ \param size Size of the buffer in bytes. It must at least larger than sizeof(ChunkHeader).
+ \param chunkSize The size of memory chunk. The default is kDefaultChunkSize.
+ \param baseAllocator The allocator for allocating memory chunks.
+ */
+ MemoryPoolAllocator(void *buffer, size_t size, size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :
+ chunk_capacity_(chunkSize),
+ baseAllocator_(baseAllocator),
+ shared_(static_cast(AlignBuffer(buffer, size)))
+ {
+ RAPIDJSON_ASSERT(size >= SIZEOF_SHARED_DATA + SIZEOF_CHUNK_HEADER);
+ shared_->chunkHead = GetChunkHead(shared_);
+ shared_->chunkHead->capacity = size - SIZEOF_SHARED_DATA - SIZEOF_CHUNK_HEADER;
+ shared_->chunkHead->size = 0;
+ shared_->chunkHead->next = 0;
+ shared_->ownBaseAllocator = 0;
+ shared_->ownBuffer = false;
+ shared_->refcount = 1;
+ }
+
+ MemoryPoolAllocator(const MemoryPoolAllocator& rhs) RAPIDJSON_NOEXCEPT :
+ chunk_capacity_(rhs.chunk_capacity_),
+ baseAllocator_(rhs.baseAllocator_),
+ shared_(rhs.shared_)
+ {
+ RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
+ ++shared_->refcount;
+ }
+ MemoryPoolAllocator& operator=(const MemoryPoolAllocator& rhs) RAPIDJSON_NOEXCEPT
+ {
+ RAPIDJSON_NOEXCEPT_ASSERT(rhs.shared_->refcount > 0);
+ ++rhs.shared_->refcount;
+ this->~MemoryPoolAllocator();
+ baseAllocator_ = rhs.baseAllocator_;
+ chunk_capacity_ = rhs.chunk_capacity_;
+ shared_ = rhs.shared_;
+ return *this;
+ }
+
+#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
+ MemoryPoolAllocator(MemoryPoolAllocator&& rhs) RAPIDJSON_NOEXCEPT :
+ chunk_capacity_(rhs.chunk_capacity_),
+ baseAllocator_(rhs.baseAllocator_),
+ shared_(rhs.shared_)
+ {
+ RAPIDJSON_NOEXCEPT_ASSERT(rhs.shared_->refcount > 0);
+ rhs.shared_ = 0;
+ }
+ MemoryPoolAllocator& operator=(MemoryPoolAllocator&& rhs) RAPIDJSON_NOEXCEPT
+ {
+ RAPIDJSON_NOEXCEPT_ASSERT(rhs.shared_->refcount > 0);
+ this->~MemoryPoolAllocator();
+ baseAllocator_ = rhs.baseAllocator_;
+ chunk_capacity_ = rhs.chunk_capacity_;
+ shared_ = rhs.shared_;
+ rhs.shared_ = 0;
+ return *this;
+ }
+#endif
+
+ //! Destructor.
+ /*! This deallocates all memory chunks, excluding the user-supplied buffer.
+ */
+ ~MemoryPoolAllocator() RAPIDJSON_NOEXCEPT {
+ if (!shared_) {
+ // do nothing if moved
+ return;
+ }
+ if (shared_->refcount > 1) {
+ --shared_->refcount;
+ return;
+ }
+ Clear();
+ BaseAllocator *a = shared_->ownBaseAllocator;
+ if (shared_->ownBuffer) {
+ baseAllocator_->Free(shared_);
+ }
+ RAPIDJSON_DELETE(a);
+ }
+
+ //! Deallocates all memory chunks, excluding the first/user one.
+ void Clear() RAPIDJSON_NOEXCEPT {
+ RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
+ for (;;) {
+ ChunkHeader* c = shared_->chunkHead;
+ if (!c->next) {
+ break;
+ }
+ shared_->chunkHead = c->next;
+ baseAllocator_->Free(c);
+ }
+ shared_->chunkHead->size = 0;
+ }
+
+ //! Computes the total capacity of allocated memory chunks.
+ /*! \return total capacity in bytes.
+ */
+ size_t Capacity() const RAPIDJSON_NOEXCEPT {
+ RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
+ size_t capacity = 0;
+ for (ChunkHeader* c = shared_->chunkHead; c != 0; c = c->next)
+ capacity += c->capacity;
+ return capacity;
+ }
+
+ //! Computes the memory blocks allocated.
+ /*! \return total used bytes.
+ */
+ size_t Size() const RAPIDJSON_NOEXCEPT {
+ RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
+ size_t size = 0;
+ for (ChunkHeader* c = shared_->chunkHead; c != 0; c = c->next)
+ size += c->size;
+ return size;
+ }
+
+ //! Whether the allocator is shared.
+ /*! \return true or false.
+ */
+ bool Shared() const RAPIDJSON_NOEXCEPT {
+ RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
+ return shared_->refcount > 1;
+ }
+
+ //! Allocates a memory block. (concept Allocator)
+ void* Malloc(size_t size) {
+ RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
+ if (!size)
+ return NULL;
+
+ size = RAPIDJSON_ALIGN(size);
+ if (RAPIDJSON_UNLIKELY(shared_->chunkHead->size + size > shared_->chunkHead->capacity))
+ if (!AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size))
+ return NULL;
+
+ void *buffer = GetChunkBuffer(shared_) + shared_->chunkHead->size;
+ shared_->chunkHead->size += size;
+ return buffer;
+ }
+
+ //! Resizes a memory block (concept Allocator)
+ void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {
+ if (originalPtr == 0)
+ return Malloc(newSize);
+
+ RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
+ if (newSize == 0)
+ return NULL;
+
+ originalSize = RAPIDJSON_ALIGN(originalSize);
+ newSize = RAPIDJSON_ALIGN(newSize);
+
+ // Do not shrink if new size is smaller than original
+ if (originalSize >= newSize)
+ return originalPtr;
+
+ // Simply expand it if it is the last allocation and there is sufficient space
+ if (originalPtr == GetChunkBuffer(shared_) + shared_->chunkHead->size - originalSize) {
+ size_t increment = static_cast(newSize - originalSize);
+ if (shared_->chunkHead->size + increment <= shared_->chunkHead->capacity) {
+ shared_->chunkHead->size += increment;
+ return originalPtr;
+ }
+ }
+
+ // Realloc process: allocate and copy memory, do not free original buffer.
+ if (void* newBuffer = Malloc(newSize)) {
+ if (originalSize)
+ std::memcpy(newBuffer, originalPtr, originalSize);
+ return newBuffer;
+ }
+ else
+ return NULL;
+ }
+
+ //! Frees a memory block (concept Allocator)
+ static void Free(void *ptr) RAPIDJSON_NOEXCEPT { (void)ptr; } // Do nothing
+
+ //! Compare (equality) with another MemoryPoolAllocator
+ bool operator==(const MemoryPoolAllocator& rhs) const RAPIDJSON_NOEXCEPT {
+ RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
+ RAPIDJSON_NOEXCEPT_ASSERT(rhs.shared_->refcount > 0);
+ return shared_ == rhs.shared_;
+ }
+ //! Compare (inequality) with another MemoryPoolAllocator
+ bool operator!=(const MemoryPoolAllocator& rhs) const RAPIDJSON_NOEXCEPT {
+ return !operator==(rhs);
+ }
+
+private:
+ //! Creates a new chunk.
+ /*! \param capacity Capacity of the chunk in bytes.
+ \return true if success.
+ */
+ bool AddChunk(size_t capacity) {
+ if (!baseAllocator_)
+ shared_->ownBaseAllocator = baseAllocator_ = RAPIDJSON_NEW(BaseAllocator)();
+ if (ChunkHeader* chunk = static_cast(baseAllocator_->Malloc(SIZEOF_CHUNK_HEADER + capacity))) {
+ chunk->capacity = capacity;
+ chunk->size = 0;
+ chunk->next = shared_->chunkHead;
+ shared_->chunkHead = chunk;
+ return true;
+ }
+ else
+ return false;
+ }
+
+ static inline void* AlignBuffer(void* buf, size_t &size)
+ {
+ RAPIDJSON_NOEXCEPT_ASSERT(buf != 0);
+ const uintptr_t mask = sizeof(void*) - 1;
+ const uintptr_t ubuf = reinterpret_cast(buf);
+ if (RAPIDJSON_UNLIKELY(ubuf & mask)) {
+ const uintptr_t abuf = (ubuf + mask) & ~mask;
+ RAPIDJSON_ASSERT(size >= abuf - ubuf);
+ buf = reinterpret_cast(abuf);
+ size -= abuf - ubuf;
+ }
+ return buf;
+ }
+
+ size_t chunk_capacity_; //!< The minimum capacity of chunk when they are allocated.
+ BaseAllocator* baseAllocator_; //!< base allocator for allocating memory chunks.
+ SharedData *shared_; //!< The shared data of the allocator
+};
+
+namespace internal {
+ template
+ struct IsRefCounted :
+ public FalseType
+ { };
+ template
+ struct IsRefCounted::Type> :
+ public TrueType
+ { };
+}
+
+template
+inline T* Realloc(A& a, T* old_p, size_t old_n, size_t new_n)
+{
+ RAPIDJSON_NOEXCEPT_ASSERT(old_n <= SIZE_MAX / sizeof(T) && new_n <= SIZE_MAX / sizeof(T));
+ return static_cast(a.Realloc(old_p, old_n * sizeof(T), new_n * sizeof(T)));
+}
+
+template
+inline T *Malloc(A& a, size_t n = 1)
+{
+ return Realloc(a, NULL, 0, n);
+}
+
+template
+inline void Free(A& a, T *p, size_t n = 1)
+{
+ static_cast(Realloc(a, p, n, 0));
+}
+
+#ifdef __GNUC__
+RAPIDJSON_DIAG_PUSH
+RAPIDJSON_DIAG_OFF(effc++) // std::allocator can safely be inherited
+#endif
+
+template
+class StdAllocator :
+ public std::allocator
+{
+ typedef std::allocator allocator_type;
+#if RAPIDJSON_HAS_CXX11
+ typedef std::allocator_traits traits_type;
+#else
+ typedef allocator_type traits_type;
+#endif
+
+public:
+ typedef BaseAllocator BaseAllocatorType;
+
+ StdAllocator() RAPIDJSON_NOEXCEPT :
+ allocator_type(),
+ baseAllocator_()
+ { }
+
+ StdAllocator(const StdAllocator& rhs) RAPIDJSON_NOEXCEPT :
+ allocator_type(rhs),
+ baseAllocator_(rhs.baseAllocator_)
+ { }
+
+ template
+ StdAllocator(const StdAllocator& rhs) RAPIDJSON_NOEXCEPT :
+ allocator_type(rhs),
+ baseAllocator_(rhs.baseAllocator_)
+ { }
+
+#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
+ StdAllocator(StdAllocator&& rhs) RAPIDJSON_NOEXCEPT :
+ allocator_type(std::move(rhs)),
+ baseAllocator_(std::move(rhs.baseAllocator_))
+ { }
+#endif
+#if RAPIDJSON_HAS_CXX11
+ using propagate_on_container_move_assignment = std::true_type;
+ using propagate_on_container_swap = std::true_type;
+#endif
+
+ /* implicit */
+ StdAllocator(const BaseAllocator& allocator) RAPIDJSON_NOEXCEPT :
+ allocator_type(),
+ baseAllocator_(allocator)
+ { }
+
+ ~StdAllocator() RAPIDJSON_NOEXCEPT
+ { }
+
+ template
+ struct rebind {
+ typedef StdAllocator other;
+ };
+
+ typedef typename traits_type::size_type size_type;
+ typedef typename traits_type::difference_type difference_type;
+
+ typedef typename traits_type::value_type value_type;
+ typedef typename traits_type::pointer pointer;
+ typedef typename traits_type::const_pointer const_pointer;
+
+#if RAPIDJSON_HAS_CXX11
+
+ typedef typename std::add_lvalue_reference::type &reference;
+ typedef typename std::add_lvalue_reference::type>::type &const_reference;
+
+ pointer address(reference r) const RAPIDJSON_NOEXCEPT
+ {
+ return std::addressof(r);
+ }
+ const_pointer address(const_reference r) const RAPIDJSON_NOEXCEPT
+ {
+ return std::addressof(r);
+ }
+
+ size_type max_size() const RAPIDJSON_NOEXCEPT
+ {
+ return traits_type::max_size(*this);
+ }
+
+ template
+ void construct(pointer p, Args&&... args)
+ {
+ traits_type::construct(*this, p, std::forward(args)...);
+ }
+ void destroy(pointer p)
+ {
+ traits_type::destroy(*this, p);
+ }
+
+#else // !RAPIDJSON_HAS_CXX11
+
+ typedef typename allocator_type::reference reference;
+ typedef typename allocator_type::const_reference const_reference;
+
+ pointer address(reference r) const RAPIDJSON_NOEXCEPT
+ {
+ return allocator_type::address(r);
+ }
+ const_pointer address(const_reference r) const RAPIDJSON_NOEXCEPT
+ {
+ return allocator_type::address(r);
+ }
+
+ size_type max_size() const RAPIDJSON_NOEXCEPT
+ {
+ return allocator_type::max_size();
+ }
+
+ void construct(pointer p, const_reference r)
+ {
+ allocator_type::construct(p, r);
+ }
+ void destroy(pointer p)
+ {
+ allocator_type::destroy(p);
+ }
+
+#endif // !RAPIDJSON_HAS_CXX11
+
+ template
+ U* allocate(size_type n = 1, const void* = 0)
+ {
+ return RAPIDJSON_NAMESPACE::Malloc(baseAllocator_, n);
+ }
+ template
+ void deallocate(U* p, size_type n = 1)
+ {
+ RAPIDJSON_NAMESPACE::Free(baseAllocator_, p, n);
+ }
+
+ pointer allocate(size_type n = 1, const void* = 0)
+ {
+ return allocate(n);
+ }
+ void deallocate(pointer p, size_type n = 1)
+ {
+ deallocate(p, n);
+ }
+
+#if RAPIDJSON_HAS_CXX11
+ using is_always_equal = std::is_empty;
+#endif
+
+ template
+ bool operator==(const StdAllocator& rhs) const RAPIDJSON_NOEXCEPT
+ {
+ return baseAllocator_ == rhs.baseAllocator_;
+ }
+ template
+ bool operator!=(const StdAllocator& rhs) const RAPIDJSON_NOEXCEPT
+ {
+ return !operator==(rhs);
+ }
+
+ //! rapidjson Allocator concept
+ static const bool kNeedFree = BaseAllocator::kNeedFree;
+ static const bool kRefCounted = internal::IsRefCounted::Value;
+ void* Malloc(size_t size)
+ {
+ return baseAllocator_.Malloc(size);
+ }
+ void* Realloc(void* originalPtr, size_t originalSize, size_t newSize)
+ {
+ return baseAllocator_.Realloc(originalPtr, originalSize, newSize);
+ }
+ static void Free(void *ptr) RAPIDJSON_NOEXCEPT
+ {
+ BaseAllocator::Free(ptr);
+ }
+
+private:
+ template
+ friend class StdAllocator; // access to StdAllocator.*
+
+ BaseAllocator baseAllocator_;
+};
+
+#if !RAPIDJSON_HAS_CXX17 // std::allocator deprecated in C++17
+template
+class StdAllocator :
+ public std::allocator
+{
+ typedef std::allocator allocator_type;
+
+public:
+ typedef BaseAllocator BaseAllocatorType;
+
+ StdAllocator() RAPIDJSON_NOEXCEPT :
+ allocator_type(),
+ baseAllocator_()
+ { }
+
+ StdAllocator(const StdAllocator& rhs) RAPIDJSON_NOEXCEPT :
+ allocator_type(rhs),
+ baseAllocator_(rhs.baseAllocator_)
+ { }
+
+ template
+ StdAllocator(const StdAllocator& rhs) RAPIDJSON_NOEXCEPT :
+ allocator_type(rhs),
+ baseAllocator_(rhs.baseAllocator_)
+ { }
+
+ /* implicit */
+ StdAllocator(const BaseAllocator& baseAllocator) RAPIDJSON_NOEXCEPT :
+ allocator_type(),
+ baseAllocator_(baseAllocator)
+ { }
+
+ ~StdAllocator() RAPIDJSON_NOEXCEPT
+ { }
+
+ template
+ struct rebind {
+ typedef StdAllocator other;
+ };
+
+ typedef typename allocator_type::value_type value_type;
+
+private:
+ template
+ friend class StdAllocator; // access to StdAllocator.*
+
+ BaseAllocator baseAllocator_;
+};
+#endif
+
+#ifdef __GNUC__
+RAPIDJSON_DIAG_POP
+#endif
+
+RAPIDJSON_NAMESPACE_END
+
+#endif // RAPIDJSON_ENCODINGS_H_
diff --git a/raidjson/rapidjson/cursorstreamwrapper.h b/raidjson/rapidjson/cursorstreamwrapper.h
new file mode 100644
index 0000000..fd6513d
--- /dev/null
+++ b/raidjson/rapidjson/cursorstreamwrapper.h
@@ -0,0 +1,78 @@
+// Tencent is pleased to support the open source community by making RapidJSON available.
+//
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
+//
+// Licensed under the MIT License (the "License"); you may not use this file except
+// in compliance with the License. You may obtain a copy of the License at
+//
+// http://opensource.org/licenses/MIT
+//
+// Unless required by applicable law or agreed to in writing, software distributed
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations under the License.
+
+#ifndef RAPIDJSON_CURSORSTREAMWRAPPER_H_
+#define RAPIDJSON_CURSORSTREAMWRAPPER_H_
+
+#include "stream.h"
+
+#if defined(__GNUC__)
+RAPIDJSON_DIAG_PUSH
+RAPIDJSON_DIAG_OFF(effc++)
+#endif
+
+#if defined(_MSC_VER) && _MSC_VER <= 1800
+RAPIDJSON_DIAG_PUSH
+RAPIDJSON_DIAG_OFF(4702) // unreachable code
+RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
+#endif
+
+RAPIDJSON_NAMESPACE_BEGIN
+
+
+//! Cursor stream wrapper for counting line and column number if error exists.
+/*!
+ \tparam InputStream Any stream that implements Stream Concept
+*/
+template >
+class CursorStreamWrapper : public GenericStreamWrapper {
+public:
+ typedef typename Encoding::Ch Ch;
+
+ CursorStreamWrapper(InputStream& is):
+ GenericStreamWrapper(is), line_(1), col_(0) {}
+
+ // counting line and column number
+ Ch Take() {
+ Ch ch = this->is_.Take();
+ if(ch == '\n') {
+ line_ ++;
+ col_ = 0;
+ } else {
+ col_ ++;
+ }
+ return ch;
+ }
+
+ //! Get the error line number, if error exists.
+ size_t GetLine() const { return line_; }
+ //! Get the error column number, if error exists.
+ size_t GetColumn() const { return col_; }
+
+private:
+ size_t line_; //!< Current Line
+ size_t col_; //!< Current Column
+};
+
+#if defined(_MSC_VER) && _MSC_VER <= 1800
+RAPIDJSON_DIAG_POP
+#endif
+
+#if defined(__GNUC__)
+RAPIDJSON_DIAG_POP
+#endif
+
+RAPIDJSON_NAMESPACE_END
+
+#endif // RAPIDJSON_CURSORSTREAMWRAPPER_H_
diff --git a/raidjson/rapidjson/document.h b/raidjson/rapidjson/document.h
new file mode 100644
index 0000000..4f1e246
--- /dev/null
+++ b/raidjson/rapidjson/document.h
@@ -0,0 +1,3043 @@
+// Tencent is pleased to support the open source community by making RapidJSON available.
+//
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
+//
+// Licensed under the MIT License (the "License"); you may not use this file except
+// in compliance with the License. You may obtain a copy of the License at
+//
+// http://opensource.org/licenses/MIT
+//
+// Unless required by applicable law or agreed to in writing, software distributed
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations under the License.
+
+#ifndef RAPIDJSON_DOCUMENT_H_
+#define RAPIDJSON_DOCUMENT_H_
+
+/*! \file document.h */
+
+#include "reader.h"
+#include "internal/meta.h"
+#include "internal/strfunc.h"
+#include "memorystream.h"
+#include "encodedstream.h"
+#include // placement new
+#include
+#ifdef __cpp_lib_three_way_comparison
+#include
+#endif
+
+RAPIDJSON_DIAG_PUSH
+#ifdef __clang__
+RAPIDJSON_DIAG_OFF(padded)
+RAPIDJSON_DIAG_OFF(switch-enum)
+RAPIDJSON_DIAG_OFF(c++98-compat)
+#elif defined(_MSC_VER)
+RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
+RAPIDJSON_DIAG_OFF(4244) // conversion from kXxxFlags to 'uint16_t', possible loss of data
+#endif
+
+#ifdef __GNUC__
+RAPIDJSON_DIAG_OFF(effc++)
+#endif // __GNUC__
+
+#ifdef GetObject
+// see https://github.com/Tencent/rapidjson/issues/1448
+// a former included windows.h might have defined a macro called GetObject, which affects
+// GetObject defined here. This ensures the macro does not get applied
+#pragma push_macro("GetObject")
+#define RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED
+#undef GetObject
+#endif
+
+#ifndef RAPIDJSON_NOMEMBERITERATORCLASS
+#include // std::random_access_iterator_tag
+#endif
+
+#if RAPIDJSON_USE_MEMBERSMAP
+#include